diff --git a/.gitignore b/.gitignore index 640e20c..e002574 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,6 @@ Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk -/artifacts \ No newline at end of file +/artifacts + +node_modules \ No newline at end of file diff --git a/contracts/anchor/examples/schema.rs b/contracts/anchor/examples/schema.rs index 37e536b..f2c3698 100644 --- a/contracts/anchor/examples/schema.rs +++ b/contracts/anchor/examples/schema.rs @@ -4,7 +4,7 @@ use std::fs::create_dir_all; use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; use protocol_cosmwasm::anchor::{ - Cw20HookMsg, ExecuteMsg, InfoResponse, InstantiateMsg, QueryMsg, WithdrawMsg, + ConfigResponse, Cw20HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg, WithdrawMsg, }; fn main() { @@ -18,5 +18,5 @@ fn main() { export_schema(&schema_for!(WithdrawMsg), &out_dir); export_schema(&schema_for!(Cw20HookMsg), &out_dir); export_schema(&schema_for!(QueryMsg), &out_dir); - export_schema(&schema_for!(InfoResponse), &out_dir); + export_schema(&schema_for!(ConfigResponse), &out_dir); } diff --git a/contracts/anchor/src/contract.rs b/contracts/anchor/src/contract.rs index cd1b8e3..d43dcd1 100644 --- a/contracts/anchor/src/contract.rs +++ b/contracts/anchor/src/contract.rs @@ -1,19 +1,21 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - attr, from_binary, to_binary, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, - StdError, StdResult, Storage, Uint128, Uint256, WasmMsg, + attr, from_binary, to_binary, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, + Response, StdError, StdResult, Storage, Uint128, WasmMsg, }; use cw2::set_contract_version; use crate::state::{ - save_root, save_subtree, Anchor, LinkableMerkleTree, MerkleTree, ANCHOR, ANCHORVERIFIER, - NULLIFIERS, POSEIDON, + read_edge, read_neighbor_roots, read_root, save_root, save_subtree, Anchor, LinkableMerkleTree, + MerkleTree, ANCHOR, ANCHORVERIFIER, NULLIFIERS, POSEIDON, }; use codec::Encode; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; use protocol_cosmwasm::anchor::{ - Cw20HookMsg, ExecuteMsg, InfoResponse, InstantiateMsg, QueryMsg, WithdrawMsg, + ConfigResponse, Cw20HookMsg, EdgeInfoResponse, ExecuteMsg, InstantiateMsg, + MerkleRootInfoResponse, MerkleTreeInfoResponse, NeighborRootInfoResponse, QueryMsg, + WithdrawMsg, }; use protocol_cosmwasm::anchor_verifier::AnchorVerifier; use protocol_cosmwasm::error::ContractError; @@ -65,16 +67,20 @@ pub fn instantiate( chain_id_list: Vec::new(), }; - // Get the "cw20_address" - let cw20_address = deps.api.addr_canonicalize(&msg.cw20_address)?; + // Get the "TokenWrapper" token address. + let tokenwrapper_addr = deps.api.addr_validate(msg.tokenwrapper_addr.as_str())?; // Initialize the Anchor + let deposit_size = match parse_string_to_uint128(msg.deposit_size) { + Ok(v) => v, + Err(e) => return Err(ContractError::Std(e)), + }; let anchor = Anchor { chain_id: msg.chain_id, - deposit_size: Uint256::from(msg.deposit_size.u128()), linkable_tree: linkable_merkle_tree, + deposit_size, merkle_tree, - cw20_address, + tokenwrapper_addr, }; ANCHOR.save(deps.storage, &anchor)?; @@ -99,35 +105,33 @@ pub fn execute( msg: ExecuteMsg, ) -> Result { match msg { + // Withdraw the cw20 token with proof ExecuteMsg::Withdraw(msg) => withdraw(deps, info, msg), + // Deposit the cw20 token with commitment ExecuteMsg::Receive(msg) => receive_cw20(deps, info, msg), } } -/// User deposits the Cw20 tokens with its commitments. -/// The deposit starts from executing the hook message -/// coming from the Cw20 token contract. -/// It checks the validity of the Cw20 tokens sent. -/// It also checks the merkle tree availiability. -/// It saves the commitment in "merkle tree". pub fn receive_cw20( deps: DepsMut, info: MessageInfo, cw20_msg: Cw20ReceiveMsg, ) -> Result { - // Only Cw20 token contract can execute this message. let anchor: Anchor = ANCHOR.load(deps.storage)?; - if anchor.cw20_address != deps.api.addr_canonicalize(info.sender.as_str())? { + + // Validations + let cw20_address = deps.api.addr_validate(info.sender.as_str())?; + if anchor.tokenwrapper_addr != cw20_address { return Err(ContractError::Unauthorized {}); } - let tokens_sent = cw20_msg.amount; + let sent_cw20_token_amt = cw20_msg.amount; + if sent_cw20_token_amt < anchor.deposit_size { + return Err(ContractError::InsufficientFunds {}); + } match from_binary(&cw20_msg.msg) { Ok(Cw20HookMsg::DepositCw20 { commitment }) => { - if Uint256::from(tokens_sent) < anchor.deposit_size { - return Err(ContractError::InsufficientFunds {}); - } - // Checks the validity of + // Handle the "deposit" cw20 tokens if let Some(commitment) = commitment { let mut merkle_tree = anchor.merkle_tree; let poseidon = POSEIDON.load(deps.storage)?; @@ -141,7 +145,7 @@ pub fn receive_cw20( chain_id: anchor.chain_id, deposit_size: anchor.deposit_size, linkable_tree: anchor.linkable_tree, - cw20_address: anchor.cw20_address, + tokenwrapper_addr: anchor.tokenwrapper_addr, merkle_tree, }, )?; @@ -162,25 +166,31 @@ pub fn receive_cw20( } } -/// User withdraws the CW20 tokens to "recipient" address -/// by providing the "proof" for the "commitment". -/// It verifies the "withdraw" by verifying the "proof" -/// with "commitment" saved in prior. -/// If success on verify, then it performs "withdraw" action -/// which sends the CW20 tokens to "recipient" & "relayer" address. pub fn withdraw( deps: DepsMut, info: MessageInfo, msg: WithdrawMsg, ) -> Result { - // Validation 1. Check if the funds are sent. - if !info.funds.is_empty() { - return Err(ContractError::UnnecessaryFunds {}); + let recipient = msg.recipient; + let relayer = msg.relayer; + let fee = match parse_string_to_uint128(msg.fee) { + Ok(v) => v, + Err(e) => return Err(ContractError::Std(e)), + }; + let refund = match parse_string_to_uint128(msg.refund) { + Ok(v) => v, + Err(e) => return Err(ContractError::Std(e)), + }; + let sent_funds = info.funds; + if !refund.is_zero() && (sent_funds.len() != 1 || sent_funds[0].amount != refund) { + return Err(ContractError::Std(StdError::GenericErr { + msg: "Sent insufficent refund".to_string(), + })); } - // Validation 2. Check if the root is known to merkle tree let anchor = ANCHOR.load(deps.storage)?; + // Validation 1. Check if the root is known to merkle tree. let merkle_tree = anchor.merkle_tree; if !merkle_tree.is_known_root(msg.roots[0], deps.storage) { return Err(ContractError::Std(StdError::GenericErr { @@ -188,7 +198,7 @@ pub fn withdraw( })); } - // Validation 3. Check if the roots are valid in linkable tree. + // Validation 2. Check if the roots are valid in linkable tree. let linkable_tree = anchor.linkable_tree; if !linkable_tree.is_valid_neighbor_roots(&msg.roots[1..], deps.storage) { return Err(ContractError::Std(StdError::GenericErr { @@ -196,13 +206,14 @@ pub fn withdraw( })); } - // Checks if the nullifier already used. + // Validation 3. Check if the nullifier already used. if is_known_nullifier(deps.storage, msg.nullifier_hash) { return Err(ContractError::Std(StdError::GenericErr { msg: "Nullifier is known".to_string(), })); } + // let element_encoder = |v: &[u8]| { let mut output = [0u8; 32]; output.iter_mut().zip(v).for_each(|(b1, b2)| *b1 = *b2); @@ -212,32 +223,14 @@ pub fn withdraw( // Format the public input bytes let chain_id_type_bytes = element_encoder(&compute_chain_id_type(anchor.chain_id, &COSMOS_CHAIN_TYPE).to_le_bytes()); - let recipient_bytes = - truncate_and_pad(&hex::decode(&msg.recipient).map_err(|_| ContractError::DecodeError)?); - let relayer_bytes = - truncate_and_pad(&hex::decode(&msg.relayer).map_err(|_| ContractError::DecodeError)?); - let fee_u128 = match Uint128::try_from(msg.fee) { - Ok(v) => v, - Err(_) => { - return Err(ContractError::Std(StdError::GenericErr { - msg: "Cannot convert fee".to_string(), - })) - } - }; - let refund_u128 = match Uint128::try_from(msg.refund) { - Ok(v) => v, - Err(_) => { - return Err(ContractError::Std(StdError::GenericErr { - msg: "Cannot convert refund".to_string(), - })) - } - }; + let recipient_bytes = truncate_and_pad(recipient.as_bytes()); + let relayer_bytes = truncate_and_pad(relayer.as_bytes()); let mut arbitrary_data_bytes = Vec::new(); arbitrary_data_bytes.extend_from_slice(&recipient_bytes); arbitrary_data_bytes.extend_from_slice(&relayer_bytes); - arbitrary_data_bytes.extend_from_slice(&fee_u128.u128().encode()); - arbitrary_data_bytes.extend_from_slice(&refund_u128.u128().encode()); + arbitrary_data_bytes.extend_from_slice(&fee.u128().encode()); + arbitrary_data_bytes.extend_from_slice(&refund.u128().encode()); arbitrary_data_bytes.extend_from_slice(&msg.commitment); let arbitrary_input = Keccak256::hash(&arbitrary_data_bytes).map_err(|_| ContractError::HashError)?; @@ -266,7 +259,7 @@ pub fn withdraw( // Validate the "cw20_address". let cw20_address = msg.cw20_address; - if anchor.cw20_address != deps.api.addr_canonicalize(cw20_address.as_str())? { + if anchor.tokenwrapper_addr != deps.api.addr_validate(cw20_address.as_str())? { return Err(ContractError::Std(StdError::generic_err( "Invalid cw20 address", ))); @@ -276,61 +269,46 @@ pub fn withdraw( let mut msgs: Vec = vec![]; // Send the funds to "recipient" - let amt_to_recipient = match Uint128::try_from(anchor.deposit_size - msg.fee) { + let amt_to_recipient = match anchor.deposit_size.checked_sub(fee) { Ok(v) => v, - Err(_) => { + Err(e) => { return Err(ContractError::Std(StdError::GenericErr { - msg: "Cannot compute amount".to_string(), + msg: e.to_string(), })) } }; - msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: cw20_address.clone(), - funds: [].to_vec(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { - recipient: msg.recipient.clone(), - amount: amt_to_recipient, - })?, - })); - // Send the funds to "relayer" - let amt_to_relayer = match Uint128::try_from(msg.fee) { - Ok(v) => v, - Err(_) => { - return Err(ContractError::Std(StdError::GenericErr { - msg: "Cannot compute amount".to_string(), - })) - } - }; - msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: cw20_address.clone(), - funds: [].to_vec(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { - recipient: msg.relayer.clone(), - amount: amt_to_relayer, - })?, - })); + if !amt_to_recipient.is_zero() { + msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: cw20_address.clone(), + funds: [].to_vec(), + msg: to_binary(&Cw20ExecuteMsg::Transfer { + recipient: recipient.clone(), + amount: amt_to_recipient, + })?, + })); + } - // If "refund" field is non-zero, send the funds to "recipient" - if msg.refund > Uint256::zero() { - let amt_refund = match Uint128::try_from(msg.refund) { - Ok(v) => v, - Err(_) => { - return Err(ContractError::Std(StdError::GenericErr { - msg: "Cannot compute amount".to_string(), - })) - } - }; + // Send the funds to "relayer" + if !fee.is_zero() { msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: cw20_address, funds: [].to_vec(), msg: to_binary(&Cw20ExecuteMsg::Transfer { - recipient: msg.recipient.clone(), - amount: amt_refund, + recipient: relayer, + amount: fee, })?, })); } + // If "refund" field is non-zero, send the funds to "recipient" + if !refund.is_zero() { + msgs.push(CosmosMsg::Bank(BankMsg::Send { + to_address: recipient, + amount: sent_funds, + })); + } + Ok(Response::new() .add_attributes(vec![attr("method", "withdraw")]) .add_messages(msgs)) @@ -339,17 +317,57 @@ pub fn withdraw( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::GetCw20Address {} => to_binary(&get_cw20_address(deps)?), + QueryMsg::Config {} => to_binary(&get_config(deps)?), + QueryMsg::EdgeInfo { id } => to_binary(&get_edge_info(deps, id)?), + QueryMsg::NeighborRootInfo { chain_id, id } => { + to_binary(&get_neighbor_root_info(deps, chain_id, id)?) + } + QueryMsg::MerkleTreeInfo {} => to_binary(&get_merkle_tree_info(deps)?), + QueryMsg::MerkleRootInfo { id } => to_binary(&get_merkle_root(deps, id)?), } } -pub fn get_cw20_address(deps: Deps) -> StdResult { +pub fn get_config(deps: Deps) -> StdResult { let anchor = ANCHOR.load(deps.storage)?; - Ok(InfoResponse { - cw20_address: deps.api.addr_humanize(&anchor.cw20_address)?.to_string(), + Ok(ConfigResponse { + chain_id: anchor.chain_id, + tokenwrapper_addr: anchor.tokenwrapper_addr.to_string(), + deposit_size: anchor.deposit_size.to_string(), + }) +} + +pub fn get_edge_info(deps: Deps, id: u64) -> StdResult { + let edge = read_edge(deps.storage, id)?; + Ok(EdgeInfoResponse { + chain_id: edge.chain_id, + root: edge.root, + latest_leaf_index: edge.latest_leaf_index, }) } +pub fn get_neighbor_root_info( + deps: Deps, + chain_id: u64, + id: u32, +) -> StdResult { + let neighbor_root = read_neighbor_roots(deps.storage, (chain_id, id))?; + Ok(NeighborRootInfoResponse { neighbor_root }) +} + +pub fn get_merkle_tree_info(deps: Deps) -> StdResult { + let anchor = ANCHOR.load(deps.storage)?; + Ok(MerkleTreeInfoResponse { + levels: anchor.merkle_tree.levels, + curr_root_index: anchor.merkle_tree.current_root_index, + next_index: anchor.merkle_tree.next_index, + }) +} + +pub fn get_merkle_root(deps: Deps, id: u32) -> StdResult { + let root = read_root(deps.storage, id)?; + Ok(MerkleRootInfoResponse { root }) +} + // Check if the "nullifier" is already used or not. pub fn is_known_nullifier(store: &dyn Storage, nullifier: [u8; 32]) -> bool { NULLIFIERS.has(store, nullifier.to_vec()) @@ -386,3 +404,11 @@ pub fn compute_chain_id_type(chain_id: u64, chain_type: &[u8]) -> u64 { buf[4..8].copy_from_slice(&chain_id_value.to_be_bytes()); u64::from_be_bytes(buf) } + +pub fn parse_string_to_uint128(v: String) -> Result { + let res = match v.parse::() { + Ok(v) => Uint128::from(v), + Err(e) => return Err(StdError::GenericErr { msg: e.to_string() }), + }; + Ok(res) +} diff --git a/contracts/anchor/src/state.rs b/contracts/anchor/src/state.rs index ee1d47d..c4781a8 100644 --- a/contracts/anchor/src/state.rs +++ b/contracts/anchor/src/state.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{CanonicalAddr, StdResult, Storage, Uint256}; +use cosmwasm_std::{Addr, StdResult, Storage, Uint128}; use cw_storage_plus::{Item, Map}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -20,8 +20,6 @@ pub struct Edge { pub latest_leaf_index: u32, } -pub const EDGES: Map = Map::new("edges"); - pub fn read_edge(store: &dyn Storage, k: ChainId) -> StdResult { EDGES.load(store, k.to_string()) } @@ -34,8 +32,6 @@ pub fn has_edge(store: &dyn Storage, k: ChainId) -> bool { EDGES.has(store, k.to_string()) } -pub const CURR_NEIGHBOR_ROOT_INDEX: Map = Map::new("curr_neighbor_root_index"); - pub fn read_curr_neighbor_root_index(store: &dyn Storage, k: ChainId) -> StdResult { CURR_NEIGHBOR_ROOT_INDEX.load(store, k.to_string()) } @@ -48,8 +44,6 @@ pub fn save_curr_neighbor_root_index( CURR_NEIGHBOR_ROOT_INDEX.save(store, k.to_string(), &data) } -pub const NEIGHBOR_ROOTS: Map<(String, String), [u8; 32]> = Map::new("neighbor_roots"); - pub fn read_neighbor_roots(store: &dyn Storage, k: (ChainId, u32)) -> StdResult<[u8; 32]> { let (id, num) = k; NEIGHBOR_ROOTS.load(store, (id.to_string(), num.to_string())) @@ -192,23 +186,12 @@ impl LinkableMerkleTree { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct Anchor { pub chain_id: u64, - pub deposit_size: Uint256, + pub deposit_size: Uint128, pub merkle_tree: MerkleTree, pub linkable_tree: LinkableMerkleTree, - pub cw20_address: CanonicalAddr, + pub tokenwrapper_addr: Addr, // Cw20 token address used for wrapping native & any cw20 token } -pub const ANCHOR: Item = Item::new("anchor"); - -// Struct to save the use of "nullifiers" -pub const NULLIFIERS: Map, bool> = Map::new("used_nullifers"); - -// "Poseidon hasher" -pub const POSEIDON: Item = Item::new("poseidon"); - -// "AnchorVerifier" -pub const ANCHORVERIFIER: Item = Item::new("anchor_verifier"); - // MerkleTree #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct MerkleTree { @@ -217,9 +200,6 @@ pub struct MerkleTree { pub next_index: u32, } -// MerkleTree "filled_subtrees" -pub const FILLED_SUBTREES: Map = Map::new("filled_subtrees"); - pub fn save_subtree(store: &mut dyn Storage, k: u32, data: &[u8; 32]) -> StdResult<()> { FILLED_SUBTREES.save(store, k.to_string(), data) } @@ -228,9 +208,6 @@ pub fn read_subtree(store: &dyn Storage, k: u32) -> StdResult<[u8; 32]> { FILLED_SUBTREES.load(store, k.to_string()) } -// MerkleTree Roots -pub const MERKLEROOTS: Map = Map::new("merkle_roots"); - pub fn save_root(store: &mut dyn Storage, k: u32, data: &[u8; 32]) -> StdResult<()> { MERKLEROOTS.save(store, k.to_string(), data) } @@ -310,3 +287,14 @@ impl MerkleTree { false } } + +pub const EDGES: Map = Map::new("edges"); +pub const CURR_NEIGHBOR_ROOT_INDEX: Map = Map::new("curr_neighbor_root_index"); +pub const NEIGHBOR_ROOTS: Map<(String, String), [u8; 32]> = Map::new("neighbor_roots"); +pub const MERKLEROOTS: Map = Map::new("merkle_roots"); +pub const FILLED_SUBTREES: Map = Map::new("filled_subtrees"); +pub const NULLIFIERS: Map, bool> = Map::new("used_nullifers"); + +pub const ANCHOR: Item = Item::new("anchor"); +pub const POSEIDON: Item = Item::new("poseidon"); +pub const ANCHORVERIFIER: Item = Item::new("anchor_verifier"); diff --git a/contracts/anchor/src/test_util.rs b/contracts/anchor/src/test_util.rs index 7fa2acf..5381141 100644 --- a/contracts/anchor/src/test_util.rs +++ b/contracts/anchor/src/test_util.rs @@ -12,8 +12,6 @@ use wasm_utils::{ types::{Backend, Curve as WasmCurve}, }; -use crate::state::ANCHOR; - #[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] pub struct Element(pub [u8; 32]); diff --git a/contracts/anchor/src/tests.rs b/contracts/anchor/src/tests.rs index 3db0402..c9d686b 100644 --- a/contracts/anchor/src/tests.rs +++ b/contracts/anchor/src/tests.rs @@ -1,22 +1,23 @@ use ark_bn254::Fr; -use ark_crypto_primitives::CRH as CRHTrait; +use ark_ff::BigInteger; use ark_ff::PrimeField; -use ark_ff::{BigInteger, Field}; use ark_std::One; use arkworks_native_gadgets::poseidon::{FieldHasher, Poseidon}; use arkworks_setups::common::setup_params; use arkworks_setups::Curve; +use cosmwasm_std::testing::MockApi; +use cosmwasm_std::testing::MockQuerier; +use cosmwasm_std::testing::MockStorage; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; -use cosmwasm_std::{attr, coins, from_binary, to_binary, CosmosMsg, Uint128, WasmMsg}; +use cosmwasm_std::OwnedDeps; +use cosmwasm_std::{attr, to_binary, CosmosMsg, Uint128, WasmMsg}; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; -use protocol_cosmwasm::anchor::{ - Cw20HookMsg, ExecuteMsg, InfoResponse, InstantiateMsg, QueryMsg, WithdrawMsg, -}; +use protocol_cosmwasm::anchor::{Cw20HookMsg, ExecuteMsg, InstantiateMsg, WithdrawMsg}; use crate::contract::{ - compute_chain_id_type, execute, instantiate, query, truncate_and_pad, COSMOS_CHAIN_TYPE, + compute_chain_id_type, execute, instantiate, truncate_and_pad, COSMOS_CHAIN_TYPE, }; #[cfg(test)] use crate::test_util::Element; @@ -24,52 +25,59 @@ use crate::test_util::Element; const MAX_EDGES: u32 = 2; const CHAIN_ID: u64 = 1; const LEVELS: u32 = 30; -const CW20_ADDRESS: &str = "terra1fex9f78reuwhfsnc8sun6mz8rl9zwqh03fhwf3"; +const CW20_ADDRESS: &str = "terra1340t6lqq6jxhm8d6gtz0hzz5jzcszvm27urkn2"; const DEPOSIT_SIZE: u128 = 1_000_000; const DEPOSITOR: &str = "depositor"; -#[test] -fn test_anchor_proper_initialization() { +const RECIPIENT: &str = "terra1kejftqzx05y9rv00lw5m76csfmx7lf9se02dz4"; +const RELAYER: &str = "terra17cz29kl6z5wj04ledes9jdmn6pgkelffjxglky"; +const FEE: u128 = 0; +const REFUND: u128 = 0; + +fn create_anchor() -> OwnedDeps { let mut deps = mock_dependencies(&[]); + let env = mock_env(); let info = mock_info("anyone", &[]); let instantiate_msg = InstantiateMsg { max_edges: MAX_EDGES, chain_id: CHAIN_ID, levels: LEVELS, - deposit_size: Uint128::from(DEPOSIT_SIZE), - cw20_address: CW20_ADDRESS.to_string(), + deposit_size: DEPOSIT_SIZE.to_string(), + tokenwrapper_addr: CW20_ADDRESS.to_string(), }; // Should pass this "unwrap" if success. - let response = instantiate(deps.as_mut(), env, info, instantiate_msg).unwrap(); - - assert_eq!( - response.attributes, - vec![attr("method", "instantiate"), attr("owner", "anyone"),] - ); + let _ = instantiate(deps.as_mut(), env, info, instantiate_msg).unwrap(); - let query = query(deps.as_ref(), mock_env(), QueryMsg::GetCw20Address {}).unwrap(); - let info: InfoResponse = from_binary(&query).unwrap(); - assert_eq!(info.cw20_address, CW20_ADDRESS.to_string()); + deps } #[test] -fn test_anchor_should_be_able_to_deposit() { - let mut deps = mock_dependencies(&coins(2, "token")); - - // Initialize the contract +fn test_anchor_proper_initialization() { + let mut deps = mock_dependencies(&[]); let env = mock_env(); let info = mock_info("anyone", &[]); let instantiate_msg = InstantiateMsg { max_edges: MAX_EDGES, chain_id: CHAIN_ID, levels: LEVELS, - deposit_size: Uint128::from(DEPOSIT_SIZE), - cw20_address: CW20_ADDRESS.to_string(), + deposit_size: DEPOSIT_SIZE.to_string(), + tokenwrapper_addr: CW20_ADDRESS.to_string(), }; - let _ = instantiate(deps.as_mut(), env, info, instantiate_msg).unwrap(); + // Should pass this "unwrap" if success. + let response = instantiate(deps.as_mut(), env, info, instantiate_msg).unwrap(); + + assert_eq!( + response.attributes, + vec![attr("method", "instantiate"), attr("owner", "anyone"),] + ); +} + +#[test] +fn test_anchor_should_be_able_to_deposit() { + let mut deps = create_anchor(); // Initialize the anchor. let params = setup_params(Curve::Bn254, 5, 3); @@ -101,8 +109,8 @@ fn test_anchor_fail_when_any_byte_is_changed_in_proof() { let curve = Curve::Bn254; let (pk_bytes, _) = crate::test_util::setup_environment(curve); let src_chain_id = compute_chain_id_type(1u64, &COSMOS_CHAIN_TYPE); - let recipient_bytes = [2u8; 32]; - let relayer_bytes = [0u8; 32]; + let recipient_bytes = RECIPIENT.as_bytes(); + let relayer_bytes = RELAYER.as_bytes(); let fee_value = 0; let refund_value = 0; let commitment_bytes = [0u8; 32]; @@ -121,20 +129,7 @@ fn test_anchor_fail_when_any_byte_is_changed_in_proof() { refund_value, ); - let mut deps = mock_dependencies(&coins(2, "token")); - - // Initialize the contract - let env = mock_env(); - let info = mock_info("anyone", &[]); - let instantiate_msg = InstantiateMsg { - max_edges: MAX_EDGES, - chain_id: CHAIN_ID, - levels: LEVELS, - deposit_size: Uint128::from(DEPOSIT_SIZE), - cw20_address: CW20_ADDRESS.to_string(), - }; - - let _ = instantiate(deps.as_mut(), env, info, instantiate_msg).unwrap(); + let mut deps = create_anchor(); // Should "deposit" cw20 tokens with success. let info = mock_info(CW20_ADDRESS, &[]); @@ -170,10 +165,10 @@ fn test_anchor_fail_when_any_byte_is_changed_in_proof() { proof_bytes: wrong_proof_bytes, roots: roots.clone(), nullifier_hash: nullifier_hash_element.0, - recipient: hex::encode(recipient_bytes.to_vec()), - relayer: hex::encode(relayer_bytes.to_vec()), - fee: cosmwasm_std::Uint256::from(fee_value), - refund: cosmwasm_std::Uint256::from(refund_value), + recipient: RECIPIENT.to_string(), + relayer: RELAYER.to_string(), + fee: FEE.to_string(), + refund: REFUND.to_string(), commitment: commitment_element.0, cw20_address: CW20_ADDRESS.to_string(), }; @@ -195,8 +190,8 @@ fn test_anchor_fail_when_invalid_merkle_roots() { let curve = Curve::Bn254; let (pk_bytes, _) = crate::test_util::setup_environment(curve); let src_chain_id = compute_chain_id_type(1u64, &COSMOS_CHAIN_TYPE); - let recipient_bytes = [2u8; 32]; - let relayer_bytes = [0u8; 32]; + let recipient_bytes = RECIPIENT.as_bytes(); + let relayer_bytes = RELAYER.as_bytes(); let fee_value = 0; let refund_value = 0; let commitment_bytes = [0u8; 32]; @@ -215,20 +210,7 @@ fn test_anchor_fail_when_invalid_merkle_roots() { refund_value, ); - let mut deps = mock_dependencies(&coins(2, "token")); - - // Initialize the contract - let env = mock_env(); - let info = mock_info("anyone", &[]); - let instantiate_msg = InstantiateMsg { - max_edges: MAX_EDGES, - chain_id: CHAIN_ID, - levels: LEVELS, - deposit_size: Uint128::from(1_000_000_u128), - cw20_address: CW20_ADDRESS.to_string(), - }; - - let _ = instantiate(deps.as_mut(), env, info, instantiate_msg).unwrap(); + let mut deps = create_anchor(); // Should "deposit" cw20 tokens with success. let info = mock_info(CW20_ADDRESS, &[]); @@ -262,10 +244,10 @@ fn test_anchor_fail_when_invalid_merkle_roots() { proof_bytes: proof_bytes.clone(), roots: wrong_roots, nullifier_hash: nullifier_hash_element.0, - recipient: hex::encode(recipient_bytes.to_vec()), - relayer: hex::encode(relayer_bytes.to_vec()), - fee: cosmwasm_std::Uint256::from(fee_value), - refund: cosmwasm_std::Uint256::from(refund_value), + recipient: RECIPIENT.to_string(), + relayer: RELAYER.to_string(), + fee: FEE.to_string(), + refund: REFUND.to_string(), commitment: commitment_element.0, cw20_address: CW20_ADDRESS.to_string(), }; @@ -288,8 +270,8 @@ fn test_anchor_works_with_wasm_utils() { let curve = Curve::Bn254; let (pk_bytes, _) = crate::test_util::setup_environment(curve); let src_chain_id = compute_chain_id_type(1u64, &COSMOS_CHAIN_TYPE); - let recipient_bytes = [2u8; 32]; - let relayer_bytes = [0u8; 32]; + let recipient_bytes = RECIPIENT.as_bytes(); + let relayer_bytes = RELAYER.as_bytes(); let fee_value = 0; let refund_value = 0; let commitment_bytes = [0u8; 32]; @@ -308,20 +290,7 @@ fn test_anchor_works_with_wasm_utils() { refund_value, ); - let mut deps = mock_dependencies(&coins(2, "token")); - - // Initialize the contract - let env = mock_env(); - let info = mock_info("anyone", &[]); - let instantiate_msg = InstantiateMsg { - max_edges: MAX_EDGES, - chain_id: CHAIN_ID, - levels: LEVELS, - deposit_size: Uint128::from(1_000_000_u128), - cw20_address: CW20_ADDRESS.to_string(), - }; - - let _ = instantiate(deps.as_mut(), env, info, instantiate_msg).unwrap(); + let mut deps = create_anchor(); // Should "deposit" cw20 tokens with success. let info = mock_info(CW20_ADDRESS, &[]); @@ -354,10 +323,10 @@ fn test_anchor_works_with_wasm_utils() { proof_bytes: proof_bytes, roots: roots, nullifier_hash: nullifier_hash_element.0, - recipient: hex::encode(recipient_bytes.to_vec()), - relayer: hex::encode(relayer_bytes.to_vec()), - fee: cosmwasm_std::Uint256::from(fee_value), - refund: cosmwasm_std::Uint256::from(refund_value), + recipient: RECIPIENT.to_string(), + relayer: RELAYER.to_string(), + fee: FEE.to_string(), + refund: REFUND.to_string(), commitment: commitment_element.0, cw20_address: CW20_ADDRESS.to_string(), }; @@ -371,28 +340,16 @@ fn test_anchor_works_with_wasm_utils() { .unwrap(); assert_eq!(response.attributes, vec![attr("method", "withdraw")]); - let expected_recipient = hex::encode(recipient_bytes.to_vec()); - let expected_relayer = hex::encode(relayer_bytes.to_vec()); - let expected_messages: Vec = vec![ - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: CW20_ADDRESS.to_string(), - funds: [].to_vec(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { - recipient: expected_recipient, - amount: Uint128::from(DEPOSIT_SIZE), - }) - .unwrap(), - }), - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: CW20_ADDRESS.to_string(), - funds: [].to_vec(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { - recipient: expected_relayer, - amount: Uint128::from(0_u128), - }) - .unwrap(), - }), - ]; + let expected_recipient = RECIPIENT.to_string(); + let expected_messages: Vec = vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: CW20_ADDRESS.to_string(), + funds: [].to_vec(), + msg: to_binary(&Cw20ExecuteMsg::Transfer { + recipient: expected_recipient, + amount: Uint128::from(DEPOSIT_SIZE), + }) + .unwrap(), + })]; assert_eq!(response.messages.len(), expected_messages.len()); } @@ -400,8 +357,8 @@ fn test_anchor_works_with_wasm_utils() { fn test_anchor_works() { let curve = Curve::Bn254; let (pk_bytes, _) = crate::test_util::setup_environment(curve); - let recipient_bytes = [1u8; 32]; - let relayer_bytes = [2u8; 32]; + let recipient_bytes = RECIPIENT.as_bytes(); + let relayer_bytes = RELAYER.as_bytes(); let fee_value = 0; let refund_value = 0; let src_chain_id = compute_chain_id_type(1, &COSMOS_CHAIN_TYPE); @@ -421,20 +378,7 @@ fn test_anchor_works() { refund_value, ); - let mut deps = mock_dependencies(&coins(2, "token")); - - // Initialize the contract - let env = mock_env(); - let info = mock_info("anyone", &[]); - let instantiate_msg = InstantiateMsg { - max_edges: MAX_EDGES, - chain_id: CHAIN_ID, - levels: LEVELS, - deposit_size: Uint128::from(1_000_000_u128), - cw20_address: CW20_ADDRESS.to_string(), - }; - - let _ = instantiate(deps.as_mut(), env, info, instantiate_msg).unwrap(); + let mut deps = create_anchor(); // Should "deposit" cw20 tokens with success. let info = mock_info(CW20_ADDRESS, &[]); @@ -466,10 +410,10 @@ fn test_anchor_works() { proof_bytes: proof_bytes, roots: roots, nullifier_hash: nullifier_hash_element.0, - recipient: hex::encode(recipient_bytes.to_vec()), - relayer: hex::encode(relayer_bytes.to_vec()), - fee: cosmwasm_std::Uint256::from(fee_value), - refund: cosmwasm_std::Uint256::from(refund_value), + recipient: RECIPIENT.to_string(), + relayer: RELAYER.to_string(), + fee: FEE.to_string(), + refund: REFUND.to_string(), commitment: commitment_element.0, cw20_address: CW20_ADDRESS.to_string(), }; @@ -483,28 +427,16 @@ fn test_anchor_works() { .unwrap(); assert_eq!(response.attributes, vec![attr("method", "withdraw")]); - let expected_recipient = hex::encode(recipient_bytes.to_vec()); - let expected_relayer = hex::encode(relayer_bytes.to_vec()); - let expected_messages: Vec = vec![ - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: CW20_ADDRESS.to_string(), - funds: [].to_vec(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { - recipient: expected_recipient, - amount: Uint128::from(DEPOSIT_SIZE), - }) - .unwrap(), - }), - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: CW20_ADDRESS.to_string(), - funds: [].to_vec(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { - recipient: expected_relayer, - amount: Uint128::from(0_u128), - }) - .unwrap(), - }), - ]; + let expected_recipient = RECIPIENT.to_string(); + let expected_messages: Vec = vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: CW20_ADDRESS.to_string(), + funds: [].to_vec(), + msg: to_binary(&Cw20ExecuteMsg::Transfer { + recipient: expected_recipient, + amount: Uint128::from(DEPOSIT_SIZE), + }) + .unwrap(), + })]; assert_eq!(response.messages.len(), expected_messages.len()); } @@ -512,8 +444,8 @@ fn test_anchor_works() { fn test_anchor_fail_when_relayer_is_diff_from_that_in_proof_generation() { let curve = Curve::Bn254; let (pk_bytes, _) = crate::test_util::setup_environment(curve); - let recipient_bytes = [1u8; 32]; - let relayer_bytes = [2u8; 32]; + let recipient_bytes = RECIPIENT.as_bytes(); + let relayer_bytes = RELAYER.as_bytes(); let fee_value = 0; let refund_value = 0; let src_chain_id = compute_chain_id_type(1, &COSMOS_CHAIN_TYPE); @@ -533,20 +465,7 @@ fn test_anchor_fail_when_relayer_is_diff_from_that_in_proof_generation() { refund_value, ); - let mut deps = mock_dependencies(&coins(2, "token")); - - // Initialize the contract - let env = mock_env(); - let info = mock_info("anyone", &[]); - let instantiate_msg = InstantiateMsg { - max_edges: MAX_EDGES, - chain_id: CHAIN_ID, - levels: LEVELS, - deposit_size: Uint128::from(1_000_000_u128), - cw20_address: CW20_ADDRESS.to_string(), - }; - - let _ = instantiate(deps.as_mut(), env, info, instantiate_msg).unwrap(); + let mut deps = create_anchor(); // Should "deposit" cw20 tokens with success. let info = mock_info(CW20_ADDRESS, &[]); @@ -579,10 +498,10 @@ fn test_anchor_fail_when_relayer_is_diff_from_that_in_proof_generation() { proof_bytes: proof_bytes, roots: roots, nullifier_hash: nullifier_hash_element.0, - recipient: hex::encode(recipient_bytes.to_vec()), + recipient: RECIPIENT.to_string(), relayer: hex::encode(wrong_relayer_bytes.to_vec()), - fee: cosmwasm_std::Uint256::from(fee_value), - refund: cosmwasm_std::Uint256::from(refund_value), + fee: FEE.to_string(), + refund: REFUND.to_string(), commitment: commitment_element.0, cw20_address: CW20_ADDRESS.to_string(), }; @@ -604,8 +523,8 @@ fn test_anchor_fail_when_relayer_is_diff_from_that_in_proof_generation() { fn test_anchor_fail_when_fee_submitted_is_changed() { let curve = Curve::Bn254; let (pk_bytes, _) = crate::test_util::setup_environment(curve); - let recipient_bytes = [1u8; 32]; - let relayer_bytes = [2u8; 32]; + let recipient_bytes = RECIPIENT.as_bytes(); + let relayer_bytes = RELAYER.as_bytes(); let fee_value = 0; let refund_value = 0; let src_chain_id = compute_chain_id_type(1, &COSMOS_CHAIN_TYPE); @@ -625,20 +544,7 @@ fn test_anchor_fail_when_fee_submitted_is_changed() { refund_value, ); - let mut deps = mock_dependencies(&coins(2, "token")); - - // Initialize the contract - let env = mock_env(); - let info = mock_info("anyone", &[]); - let instantiate_msg = InstantiateMsg { - max_edges: MAX_EDGES, - chain_id: CHAIN_ID, - levels: LEVELS, - deposit_size: Uint128::from(1_000_000_u128), - cw20_address: CW20_ADDRESS.to_string(), - }; - - let _ = instantiate(deps.as_mut(), env, info, instantiate_msg).unwrap(); + let mut deps = create_anchor(); // Should "deposit" cw20 tokens with success. let info = mock_info(CW20_ADDRESS, &[]); @@ -671,10 +577,10 @@ fn test_anchor_fail_when_fee_submitted_is_changed() { proof_bytes: proof_bytes, roots: roots, nullifier_hash: nullifier_hash_element.0, - recipient: hex::encode(recipient_bytes.to_vec()), - relayer: hex::encode(relayer_bytes.to_vec()), - fee: cosmwasm_std::Uint256::from(changed_fee_value), - refund: cosmwasm_std::Uint256::from(refund_value), + recipient: RECIPIENT.to_string(), + relayer: RELAYER.to_string(), + fee: changed_fee_value.to_string(), + refund: REFUND.to_string(), commitment: commitment_element.0, cw20_address: CW20_ADDRESS.to_string(), }; diff --git a/contracts/anchor/tests/cosmwasm_anchor.wasm b/contracts/anchor/tests/cosmwasm_anchor.wasm index 04f1e1b..2362c26 100644 Binary files a/contracts/anchor/tests/cosmwasm_anchor.wasm and b/contracts/anchor/tests/cosmwasm_anchor.wasm differ diff --git a/contracts/anchor/tests/integration.rs b/contracts/anchor/tests/integration.rs index 8c43525..7842923 100644 --- a/contracts/anchor/tests/integration.rs +++ b/contracts/anchor/tests/integration.rs @@ -1,15 +1,15 @@ //! This integration test tries to run and call the generated wasm. -use cosmwasm_std::{attr, from_binary, to_binary, Response, Uint128}; +use cosmwasm_std::{attr, to_binary, Response, Uint128}; use cosmwasm_vm::testing::{ execute, instantiate, mock_env, mock_info, mock_instance_with_gas_limit, query, }; use cw20::Cw20ReceiveMsg; -use protocol_cosmwasm::anchor::{Cw20HookMsg, ExecuteMsg, InfoResponse, InstantiateMsg, QueryMsg}; +use protocol_cosmwasm::anchor::{Cw20HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg}; use ark_bn254::Fr; +use ark_ff::BigInteger; use ark_ff::PrimeField; -use ark_ff::{BigInteger, Field}; use ark_std::One; use arkworks_native_gadgets::poseidon::{FieldHasher, Poseidon}; use arkworks_setups::common::setup_params; @@ -41,8 +41,8 @@ fn integration_test_instantiate_anchor() { max_edges: MAX_EDGES, chain_id: CHAIN_ID, levels: LEVELS, - deposit_size: Uint128::from(DEPOSIT_SIZE), - cw20_address: CW20_ADDRESS.to_string(), + deposit_size: DEPOSIT_SIZE.to_string(), + tokenwrapper_addr: CW20_ADDRESS.to_string(), }; let info = mock_info("anyone", &[]); @@ -52,10 +52,6 @@ fn integration_test_instantiate_anchor() { response.attributes, vec![attr("method", "instantiate"), attr("owner", "anyone"),] ); - - let query = query(&mut deps, mock_env(), QueryMsg::GetCw20Address {}).unwrap(); - let info: InfoResponse = from_binary(&query).unwrap(); - assert_eq!(info.cw20_address, CW20_ADDRESS.to_string()); } #[test] @@ -69,8 +65,8 @@ fn test_deposit_cw20() { max_edges: MAX_EDGES, chain_id: CHAIN_ID, levels: LEVELS, - deposit_size: Uint128::from(DEPOSIT_SIZE), - cw20_address: CW20_ADDRESS.to_string(), + deposit_size: DEPOSIT_SIZE.to_string(), + tokenwrapper_addr: CW20_ADDRESS.to_string(), }; let _res: Response = instantiate(&mut deps, env, info, instantiate_msg).unwrap(); diff --git a/packages/protocol_cosmwasm/src/anchor.rs b/packages/protocol_cosmwasm/src/anchor.rs index 8d0deee..279d789 100644 --- a/packages/protocol_cosmwasm/src/anchor.rs +++ b/packages/protocol_cosmwasm/src/anchor.rs @@ -1,4 +1,3 @@ -use cosmwasm_std::{Uint128, Uint256}; use cw20::Cw20ReceiveMsg; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -8,8 +7,8 @@ pub struct InstantiateMsg { pub max_edges: u32, pub chain_id: u64, pub levels: u32, - pub deposit_size: Uint128, - pub cw20_address: String, + pub deposit_size: String, + pub tokenwrapper_addr: String, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] @@ -33,8 +32,8 @@ pub struct WithdrawMsg { pub nullifier_hash: [u8; 32], pub recipient: String, pub relayer: String, - pub fee: Uint256, - pub refund: Uint256, + pub fee: String, + pub refund: String, pub commitment: [u8; 32], pub cw20_address: String, } @@ -42,11 +41,40 @@ pub struct WithdrawMsg { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryMsg { - GetCw20Address {}, + Config {}, + EdgeInfo { id: u64 }, + NeighborRootInfo { chain_id: u64, id: u32 }, + MerkleTreeInfo {}, + MerkleRootInfo { id: u32 }, } -// We define a custom struct for each query response #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct InfoResponse { - pub cw20_address: String, +pub struct ConfigResponse { + pub tokenwrapper_addr: String, + pub chain_id: u64, + pub deposit_size: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct EdgeInfoResponse { + pub chain_id: u64, + pub root: [u8; 32], + pub latest_leaf_index: u32, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct NeighborRootInfoResponse { + pub neighbor_root: [u8; 32], +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct MerkleTreeInfoResponse { + pub levels: u32, + pub curr_root_index: u32, + pub next_index: u32, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct MerkleRootInfoResponse { + pub root: [u8; 32], } diff --git a/test-scripts/.eslintignore b/test-scripts/.eslintignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/test-scripts/.eslintignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/test-scripts/.eslintrc b/test-scripts/.eslintrc new file mode 100644 index 0000000..f15ad04 --- /dev/null +++ b/test-scripts/.eslintrc @@ -0,0 +1,12 @@ +{ + "root": true, + "parser": "@typescript-eslint/parser", + "plugins": [ + "@typescript-eslint" + ], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended" + ] +} \ No newline at end of file diff --git a/test-scripts/README.md b/test-scripts/README.md new file mode 100644 index 0000000..f1a95e6 --- /dev/null +++ b/test-scripts/README.md @@ -0,0 +1,18 @@ +# How to run the tests + +```bash +npm install +npm run test:setup-mixer +npm run test:test-mixer +npm run test:setup-anchor +npm run test:test-anchor +``` + +**TIPS:** +After each of the setup commands, you update the config +file before proceeding to run the next command. +These commands depends on another. + +**NOTES:** +All the data, wallet and contract addresses SHOULD be updated, +since they are just one example for guide of testing the contracts. \ No newline at end of file diff --git a/test-scripts/package.json b/test-scripts/package.json new file mode 100644 index 0000000..b1eab95 --- /dev/null +++ b/test-scripts/package.json @@ -0,0 +1,26 @@ +{ + "name": "protocol-cosmwasm-test-scripts", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "scripts": { + "lint": "eslint . --ext .ts", + "test": "ts-node ./src/index.ts", + "test:setup-mixer": "npm run test --mode=testnet_setup_mixer", + "test:test-mixer": "npm run test --mode=testnet_test_mixer", + "test:setup-anchor": "npm run test --mode=testnet_setup_anchor", + "test:test-anchor": "npm run test --mode=testnet_test_anchor" + }, + "dependencies": { + "@terra-money/terra.js": "^2.0.14", + "chalk": "4.1.2", + "fs": "^0.0.1-security", + "ts-node": "^10.4.0", + "typescript": "^4.4.4" + }, + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^5.19.0", + "@typescript-eslint/parser": "^5.19.0", + "eslint": "^8.13.0" + } +} diff --git a/test-scripts/src/config.ts b/test-scripts/src/config.ts new file mode 100644 index 0000000..0403004 --- /dev/null +++ b/test-scripts/src/config.ts @@ -0,0 +1,23 @@ + +export default { + // Testnet bombay-12 + networkInfo: { + lcd_url: 'https://bombay.stakesystems.io', // backup: 'https://bombay-lcd.terra.dev' + chainId: 'bombay-12', + gasPrice: 0.15, + gasAdjustment: 1.4, + }, + + mnemonicKeys: { + deployer: "", + }, + + contracts: { + cw20: "terra1340t6lqq6jxhm8d6gtz0hzz5jzcszvm27urkn2", + mixer: "", + anchor: "", + vanchor: "", + recipient: "terra1kejftqzx05y9rv00lw5m76csfmx7lf9se02dz4", + relayer: "terra1jrj2vh6cstqwk3pg8nkmdf0r9z0n3q3f3jk5xn" + }, +}; diff --git a/test-scripts/src/index.ts b/test-scripts/src/index.ts new file mode 100644 index 0000000..5fc112f --- /dev/null +++ b/test-scripts/src/index.ts @@ -0,0 +1,23 @@ +import * as setupContracts from './scripts/setupContracts'; +import * as testContracts from './scripts/testContracts'; + +(async () => { + const mode = process.env.npm_config_mode || ""; + switch (mode) { + case "testnet_setup_mixer": + await setupContracts.setupMixer(); + break; + case "testnet_test_mixer": + await testContracts.testMixer(); + break; + case "testnet_setup_anchor": + await setupContracts.setupAnchor(); + break; + case "testnet_test_anchor": + await testContracts.testAnchor(); + break; + default: + console.log("Invalid command"); + break; + } +})(); \ No newline at end of file diff --git a/test-scripts/src/scripts/setupContracts.ts b/test-scripts/src/scripts/setupContracts.ts new file mode 100644 index 0000000..da6ef50 --- /dev/null +++ b/test-scripts/src/scripts/setupContracts.ts @@ -0,0 +1,111 @@ +import { + LCDClient, + MnemonicKey, + Wallet, +} from "@terra-money/terra.js"; +import chalk from "chalk"; +import config from "../config"; +import { storeCode, instantiateContract, } from '../utils'; + +// Variables +let terra: LCDClient; +let deployer: Wallet; + +let mixer: string; +let anchor: string; +let vanchor: string; +let cw20: string; + +function initialize() { + terra = new LCDClient({ + URL: config.networkInfo.lcd_url, + chainID: config.networkInfo.chainId, + gasPrices: { uluna: config.networkInfo.gasPrice }, + gasAdjustment: config.networkInfo.gasAdjustment, + }); + deployer = terra.wallet(new MnemonicKey({ mnemonic: config.mnemonicKeys.deployer })); + + console.log(`Use ${chalk.cyan(deployer.key.accAddress)} as wallet(deployer)`); + + mixer = config.contracts.mixer; + anchor = config.contracts.anchor; + vanchor = config.contracts.vanchor; + cw20 = config.contracts.cw20; + + console.log(`Use ${chalk.cyan(cw20)} as Cw20 token contract`); + console.log(`Use ${chalk.cyan(mixer)} as Mixer`); + console.log(`Use ${chalk.cyan(anchor)} as Anchor`); + console.log(`Use ${chalk.cyan(vanchor)} as Vanchor`); + +} + +export async function setupMixer(): Promise { + // Initialize environment info + console.log("1. Setup Environment"); + initialize(); + + // Setup mixer + console.log("2. Setup mixer"); + + // upload mixer wasm + const mixerCodeId = await storeCode(terra, deployer, "cosmwasm_mixer.wasm"); + console.log(chalk.green("Done!", `${chalk.blue("codeId")} = ${mixerCodeId}`)); + + // instantiate mixer + const mixerResult = await instantiateContract( + terra, + deployer, + deployer, + mixerCodeId, + { + "deposit_size": "1000000", + "merkletree_levels": 30, + "cw20_address": undefined, + "native_token_denom": "uusd", + } + ); + mixer = mixerResult.logs[0].events + .find((event) => { + return event.type == "instantiate_contract"; + }) + ?.attributes.find((attribute) => { + return attribute.key == "contract_address"; + })?.value as string; + console.log(chalk.green("Done!"), `${chalk.blue("contractAddress")} = ${mixer}`); +} + +export async function setupAnchor(): Promise { + // Initialize environment info + console.log("1. Setup Environment"); + initialize(); + + // Setup anchor + console.log("2. Setup Anchor"); + + // upload anchor wasm + const anchorCodeId = await storeCode(terra, deployer, "cosmwasm_anchor.wasm"); + console.log(chalk.green("Done!", `${chalk.blue("codeId")} = ${anchorCodeId}`)); + + // instantiate anchor + const anchorResult = await instantiateContract( + terra, + deployer, + deployer, + anchorCodeId, + { + "max_edges": 2, + "chain_id": 1, + "levels": 30, + "deposit_size": "1000000", + "cw20_address": cw20, + } + ); + anchor = anchorResult.logs[0].events + .find((event) => { + return event.type == "instantiate_contract"; + }) + ?.attributes.find((attribute) => { + return attribute.key == "contract_address"; + })?.value as string; + console.log(chalk.green("Done!"), `${chalk.blue("contractAddress")}=${anchor}`); +} diff --git a/test-scripts/src/scripts/testContracts.ts b/test-scripts/src/scripts/testContracts.ts new file mode 100644 index 0000000..c6c2240 --- /dev/null +++ b/test-scripts/src/scripts/testContracts.ts @@ -0,0 +1,158 @@ +import { + LCDClient, + MnemonicKey, + Wallet, + MsgExecuteContract +} from "@terra-money/terra.js"; +import chalk from "chalk"; +import config from "../config"; +import { strict as assert } from 'assert'; +import { sendTransaction, encodeObjBinary, queryCw20Balance, queryNativeBalance, } from '../utils'; + +// Variables +let terra: LCDClient; +let deployer: Wallet; + +let mixer: string; +let anchor: string; +let vanchor: string; + +function initialize() { + terra = new LCDClient({ + URL: config.networkInfo.lcd_url, + chainID: config.networkInfo.chainId, + gasPrices: { uluna: config.networkInfo.gasPrice }, + gasAdjustment: config.networkInfo.gasAdjustment, + }); + deployer = terra.wallet(new MnemonicKey({ mnemonic: config.mnemonicKeys.deployer })); + + console.log(`Use ${chalk.cyan(deployer.key.accAddress)} as wallet(deployer)`); + + mixer = config.contracts.mixer; + anchor = config.contracts.anchor; + vanchor = config.contracts.vanchor; + + console.log(`Use ${chalk.cyan(mixer)} as Mixer`); + console.log(`Use ${chalk.cyan(anchor)} as Anchor`); + console.log(`Use ${chalk.cyan(vanchor)} as Vanchor`); +} + +export async function testMixer() { + // Initialize environment info + console.log("Setup Environment"); + initialize(); + + // mixer "DEPOSIT" + const mixer_deposit_native_msg = { + "deposit": { + "commitment": [60, 193, 57, 161, 207, 107, 11, 192, 51, 187, 64, 70, 168, 216, 155, 216, 187, 112, 123, 6, 14, 101, 174, 89, 250, 120, 41, 24, 101, 151, 110, 24], + } + }; + const fund = { uusd: 1000000 }; + await sendTransaction(terra, deployer, [new MsgExecuteContract( + deployer.key.accAddress, //sender + mixer, //contract + mixer_deposit_native_msg, // ExecMsg to execute contract + fund + )]); + console.log(chalk.green("Mixer deposit Done!")); + + const recipientBalanceBefore = await queryNativeBalance( + terra, + "uusd", + config.contracts.recipient, + ); + + // mixer "WITHDRAW + const mixer_withdraw_native_msg = { + "withdraw": { + "proof_bytes": [229, 214, 117, 134, 217, 67, 12, 236, 196, 111, 110, 244, 116, 12, 30, 219, 27, 206, 151, 233, 126, 189, 160, 237, 55, 126, 47, 5, 16, 214, 38, 40, 73, 190, 123, 2, 2, 209, 193, 209, 130, 242, 27, 207, 132, 223, 159, 121, 241, 109, 55, 190, 251, 72, 255, 132, 221, 100, 139, 132, 94, 57, 26, 3, 127, 190, 105, 168, 228, 222, 91, 22, 209, 99, 227, 6, 130, 238, 109, 47, 20, 85, 125, 67, 77, 26, 176, 24, 95, 6, 159, 150, 5, 229, 254, 144, 188, 203, 207, 201, 167, 255, 5, 93, 210, 27, 38, 151, 73, 234, 247, 124, 71, 103, 23, 101, 83, 90, 109, 120, 10, 58, 150, 8, 211, 218, 219, 155], + "root": [82, 25, 2, 85, 65, 173, 18, 5, 74, 175, 108, 14, 232, 197, 174, 9, 242, 59, 105, 48, 104, 169, 204, 128, 253, 150, 15, 102, 108, 214, 81, 33], + "nullifier_hash": [183, 160, 141, 89, 98, 241, 220, 87, 120, 249, 242, 56, 92, 41, 28, 230, 247, 111, 155, 7, 94, 2, 142, 101, 0, 243, 39, 32, 59, 235, 198, 31], + "recipient": config.contracts.recipient, + "relayer": config.contracts.relayer, + "fee": "0", + "refund": "0", + "cw20_address": undefined, + } + }; + await sendTransaction(terra, deployer, [new MsgExecuteContract( + deployer.key.accAddress, //sender + mixer, //contract + mixer_withdraw_native_msg, // ExecMsg to execute contract + {} // fund + )]); + + const recipientBalanceAfter = await queryNativeBalance( + terra, + "uusd", + config.contracts.recipient, + ); + assert.strictEqual(recipientBalanceAfter, recipientBalanceBefore + 1000000); + + console.log(chalk.green("Mixer withdraw Done!")); +} + +export async function testAnchor() { + // Initialize environment info + console.log("Setup Environment"); + initialize(); + + // anchor "DEPOSIT" + const anchor_deposit_cw20_msg = { + "deposit_cw20": { + "commitment": [114, 225, 36, 85, 19, 71, 228, 164, 174, 20, 198, 64, 177, 251, 100, 45, 249, 58, 6, 169, 158, 208, 56, 145, 80, 123, 65, 223, 143, 88, 145, 33] + } + }; + const msg = { + "send": { + "amount": "1000000", + "contract": anchor, + "msg": encodeObjBinary(anchor_deposit_cw20_msg), + } + }; + + await sendTransaction(terra, deployer, [new MsgExecuteContract( + deployer.key.accAddress, //sender + config.contracts.cw20, //contract + msg, // ExecMsg to execute contract + {} + )]); + console.log(chalk.green("anchor deposit Done!")); + + const recipientBalanceBefore = await queryCw20Balance( + terra, + config.contracts.cw20, + config.contracts.recipient, + ); + + // anchor "WITHDRAW + const anchor_withdraw_cw20_msg = { + "withdraw": { + "proof_bytes": [90, 249, 64, 247, 109, 43, 39, 43, 127, 147, 229, 67, 15, 213, 234, 24, 187, 126, 198, 37, 194, 70, 161, 33, 62, 18, 134, 53, 129, 165, 5, 10, 168, 232, 41, 122, 186, 111, 104, 142, 47, 66, 50, 172, 97, 255, 75, 254, 11, 254, 30, 154, 158, 24, 149, 136, 232, 227, 166, 90, 154, 212, 3, 39, 30, 20, 127, 166, 129, 102, 51, 233, 7, 46, 39, 179, 184, 10, 32, 148, 194, 253, 52, 33, 176, 125, 46, 157, 117, 52, 208, 18, 212, 0, 151, 136, 102, 212, 236, 123, 36, 167, 9, 133, 186, 37, 128, 123, 240, 179, 90, 33, 173, 96, 94, 98, 147, 11, 62, 131, 179, 3, 221, 162, 149, 147, 49, 160], + "roots": [[214, 149, 9, 63, 241, 232, 4, 209, 158, 207, 198, 252, 199, 227, 63, 215, 195, 25, 146, 122, 246, 212, 133, 210, 59, 166, 233, 91, 229, 28, 227, 23], [214, 149, 9, 63, 241, 232, 4, 209, 158, 207, 198, 252, 199, 227, 63, 215, 195, 25, 146, 122, 246, 212, 133, 210, 59, 166, 233, 91, 229, 28, 227, 23]], + "nullifier_hash": [20, 1, 74, 40, 205, 32, 60, 43, 111, 84, 9, 48, 56, 57, 117, 133, 54, 244, 112, 62, 103, 114, 20, 112, 43, 35, 144, 27, 227, 150, 56, 46], + "recipient": config.contracts.recipient, + "relayer": "terra17cz29kl6z5wj04ledes9jdmn6pgkelffjxglky", + "fee": "0", + "refund": "0", + "commitment": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "cw20_address": config.contracts.cw20, + } + }; + await sendTransaction(terra, deployer, [new MsgExecuteContract( + deployer.key.accAddress, //sender + anchor, //contract + anchor_withdraw_cw20_msg, // ExecMsg to execute contract + {} // fund + )]); + + const recipientBalanceAfter = await queryCw20Balance( + terra, + config.contracts.cw20, + config.contracts.recipient, + ); + assert.strictEqual(recipientBalanceAfter, recipientBalanceBefore + 1000000); + + console.log(chalk.green("anchor withdraw Done!")); +} diff --git a/test-scripts/src/utils.ts b/test-scripts/src/utils.ts new file mode 100644 index 0000000..dc8c9ec --- /dev/null +++ b/test-scripts/src/utils.ts @@ -0,0 +1,129 @@ +import { + LCDClient, + Wallet, + isTxError, + Msg, + MsgInstantiateContract, + MsgStoreCode, +} from "@terra-money/terra.js"; +import chalk from "chalk"; +import * as fs from "fs"; + +/** + * @notice Upload contract code to LocalTerra. Return code ID. + */ +export async function storeCode( + terra: LCDClient, + deployer: Wallet, + filepath: string +): Promise { + const code = fs.readFileSync('./wasm_contracts/' + filepath).toString("base64"); + const result = await sendTransaction(terra, deployer, [ + new MsgStoreCode(deployer.key.accAddress, code), + ]); + return parseInt(result.logs[0].eventsByType.store_code.code_id[0]); +} + +/** + * @notice Instantiate a contract from an existing code ID. Return contract address. + */ +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types +export async function instantiateContract( + terra: LCDClient, + deployer: Wallet, + admin: Wallet, // leave this emtpy then contract is not migratable + codeId: number, + instantiateMsg: Record +) { + const result = await sendTransaction(terra, deployer, [ + new MsgInstantiateContract( + deployer.key.accAddress, + admin.key.accAddress, + codeId, + instantiateMsg + ), + ]); + return result; +} + + +/** + * @notice Send a transaction. Return result if successful, throw error if failed. + */ +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types +export async function sendTransaction( + terra: LCDClient, + sender: Wallet, + msgs: Msg[], + verbose = false +): Promise { // eslint-disable-line @typescript-eslint/no-explicit-any + const tx = await sender.createAndSignTx({ msgs }); + const result = await terra.tx.broadcast(tx); + + // Print the log info + if (verbose) { + console.log(chalk.magenta("\nTxHash:"), result.txhash); + try { + console.log( + chalk.magenta("Raw log:"), + JSON.stringify(JSON.parse(result.raw_log), null, 2) + ); + } catch { + console.log(chalk.magenta("Failed to parse log! Raw log:"), result.raw_log); + } + } + + if (isTxError(result)) { + throw new Error( + chalk.red("Transaction failed!") + + `\n${chalk.yellow("code")}: ${result.code}` + + `\n${chalk.yellow("codespace")}: ${result.codespace}` + + `\n${chalk.yellow("raw_log")}: ${result.raw_log}` + ); + } + + return result; +} + +export async function queryNativeBalance( + terra: LCDClient, + denom: string, + wallet: string, +): Promise { + try { + const res = await terra.bank.balance(wallet); + const amount = res[0].get(denom)?.amount; + if (!amount) { + console.error("Invalid amount"); + } else { + return parseInt(amount.toString()); + } + } catch { + console.error("Unable to query the native balance!"); + } +} + +export async function queryCw20Balance( + terra: LCDClient, + cw20Contract: string, + wallet: string, +): Promise { + try { + const result: { balance: string } = await terra.wasm.contractQuery( + cw20Contract, + { + "balance": { + "address": wallet, + }, + } + ); + return parseInt(result.balance); + } catch { + console.error("Unable to query the Cw20 balance!"); + } +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function encodeObjBinary(obj: any) { + return Buffer.from(JSON.stringify(obj)).toString("base64"); +} diff --git a/test-scripts/tsconfig.json b/test-scripts/tsconfig.json new file mode 100755 index 0000000..c1460ec --- /dev/null +++ b/test-scripts/tsconfig.json @@ -0,0 +1,32 @@ +{ + "include": ["src"], + "exclude": ["/node_modules/", "./src/**/*.spec.ts"], + "compilerOptions": { + "allowSyntheticDefaultImports": true, + "alwaysStrict": true, + "baseUrl": "./", + "declaration": true, + "esModuleInterop": true, + "lib": ["es2015", "es2016", "es2017", "dom"], + "module": "commonjs", + "moduleResolution": "node", + "noFallthroughCasesInSwitch": true, + "noImplicitAny": false, + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedLocals": false, + "noUnusedParameters": true, + "outDir": "dist", + "rootDir": "src", + "sourceMap": true, + "strict": true, + "strictFunctionTypes": true, + "strictNullChecks": true, + "strictPropertyInitialization": true, + "target": "es5", + "paths": { + "*": ["src/*"] + }, + "resolveJsonModule": true, + } +} \ No newline at end of file diff --git a/test-scripts/wasm_contracts/cosmwasm_anchor.wasm b/test-scripts/wasm_contracts/cosmwasm_anchor.wasm new file mode 100644 index 0000000..c2cee2d Binary files /dev/null and b/test-scripts/wasm_contracts/cosmwasm_anchor.wasm differ diff --git a/test-scripts/wasm_contracts/cosmwasm_mixer.wasm b/test-scripts/wasm_contracts/cosmwasm_mixer.wasm new file mode 100644 index 0000000..cb4ade3 Binary files /dev/null and b/test-scripts/wasm_contracts/cosmwasm_mixer.wasm differ diff --git a/test-scripts/yarn.lock b/test-scripts/yarn.lock new file mode 100644 index 0000000..a7987ad --- /dev/null +++ b/test-scripts/yarn.lock @@ -0,0 +1,1361 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@cspotcode/source-map-consumer@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" + integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg== + +"@cspotcode/source-map-support@0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5" + integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA== + dependencies: + "@cspotcode/source-map-consumer" "0.8.0" + +"@eslint/eslintrc@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.1.tgz#8b5e1c49f4077235516bc9ec7d41378c0f69b8c6" + integrity sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.3.1" + globals "^13.9.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + +"@humanwhocodes/config-array@^0.9.2": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7" + integrity sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= + +"@terra-money/terra.js@^2.0.14": + version "2.1.23" + resolved "https://registry.yarnpkg.com/@terra-money/terra.js/-/terra.js-2.1.23.tgz#6e7ee7477b8cc5895ddcb2e4eb0446e71bb0e575" + integrity sha512-nSAR35zqjKUn1Jzqevf30s47XRlW/VXU01YgK3n9ndmX15lkdlgFvqaV7UezK0xAmCpm+7xWIrtBTMmZpVBkMQ== + dependencies: + "@terra-money/terra.proto" "^0.1.7" + axios "^0.21.1" + bech32 "^2.0.0" + bip32 "^2.0.6" + bip39 "^3.0.3" + bufferutil "^4.0.3" + decimal.js "^10.2.1" + jscrypto "^1.0.1" + readable-stream "^3.6.0" + secp256k1 "^4.0.2" + tmp "^0.2.1" + utf-8-validate "^5.0.5" + ws "^7.4.2" + +"@terra-money/terra.proto@^0.1.7": + version "0.1.7" + resolved "https://registry.yarnpkg.com/@terra-money/terra.proto/-/terra.proto-0.1.7.tgz#59c18f30da10d43200bab3ba8feb5b17e43a365f" + integrity sha512-NXD7f6pQCulvo6+mv6MAPzhOkUzRjgYVuHZE/apih+lVnPG5hDBU0rRYnOGGofwvKT5/jQoOENnFn/gioWWnyQ== + dependencies: + google-protobuf "^3.17.3" + long "^4.0.0" + protobufjs "~6.11.2" + +"@tsconfig/node10@^1.0.7": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" + integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg== + +"@tsconfig/node12@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c" + integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw== + +"@tsconfig/node14@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2" + integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg== + +"@tsconfig/node16@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" + integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== + +"@types/json-schema@^7.0.9": + version "7.0.11" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + +"@types/long@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" + integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== + +"@types/node@10.12.18": + version "10.12.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" + integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== + +"@types/node@11.11.6": + version "11.11.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" + integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== + +"@types/node@>=13.7.0": + version "17.0.23" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.23.tgz#3b41a6e643589ac6442bdbd7a4a3ded62f33f7da" + integrity sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw== + +"@typescript-eslint/eslint-plugin@^5.19.0": + version "5.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.19.0.tgz#9608a4b6d0427104bccf132f058cba629a6553c0" + integrity sha512-w59GpFqDYGnWFim9p6TGJz7a3qWeENJuAKCqjGSx+Hq/bwq3RZwXYqy98KIfN85yDqz9mq6QXiY5h0FjGQLyEg== + dependencies: + "@typescript-eslint/scope-manager" "5.19.0" + "@typescript-eslint/type-utils" "5.19.0" + "@typescript-eslint/utils" "5.19.0" + debug "^4.3.2" + functional-red-black-tree "^1.0.1" + ignore "^5.1.8" + regexpp "^3.2.0" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/parser@^5.19.0": + version "5.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.19.0.tgz#05e587c1492868929b931afa0cb5579b0f728e75" + integrity sha512-yhktJjMCJX8BSBczh1F/uY8wGRYrBeyn84kH6oyqdIJwTGKmzX5Qiq49LRQ0Jh0LXnWijEziSo6BRqny8nqLVQ== + dependencies: + "@typescript-eslint/scope-manager" "5.19.0" + "@typescript-eslint/types" "5.19.0" + "@typescript-eslint/typescript-estree" "5.19.0" + debug "^4.3.2" + +"@typescript-eslint/scope-manager@5.19.0": + version "5.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.19.0.tgz#97e59b0bcbcb54dbcdfba96fc103b9020bbe9cb4" + integrity sha512-Fz+VrjLmwq5fbQn5W7cIJZ066HxLMKvDEmf4eu1tZ8O956aoX45jAuBB76miAECMTODyUxH61AQM7q4/GOMQ5g== + dependencies: + "@typescript-eslint/types" "5.19.0" + "@typescript-eslint/visitor-keys" "5.19.0" + +"@typescript-eslint/type-utils@5.19.0": + version "5.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.19.0.tgz#80f2125b0dfe82494bbae1ea99f1c0186d420282" + integrity sha512-O6XQ4RI4rQcBGshTQAYBUIGsKqrKeuIOz9v8bckXZnSeXjn/1+BDZndHLe10UplQeJLXDNbaZYrAytKNQO2T4Q== + dependencies: + "@typescript-eslint/utils" "5.19.0" + debug "^4.3.2" + tsutils "^3.21.0" + +"@typescript-eslint/types@5.19.0": + version "5.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.19.0.tgz#12d3d600d754259da771806ee8b2c842d3be8d12" + integrity sha512-zR1ithF4Iyq1wLwkDcT+qFnhs8L5VUtjgac212ftiOP/ZZUOCuuF2DeGiZZGQXGoHA50OreZqLH5NjDcDqn34w== + +"@typescript-eslint/typescript-estree@5.19.0": + version "5.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.19.0.tgz#fc987b8f62883f9ea6a5b488bdbcd20d33c0025f" + integrity sha512-dRPuD4ocXdaE1BM/dNR21elSEUPKaWgowCA0bqJ6YbYkvtrPVEvZ+zqcX5a8ECYn3q5iBSSUcBBD42ubaOp0Hw== + dependencies: + "@typescript-eslint/types" "5.19.0" + "@typescript-eslint/visitor-keys" "5.19.0" + debug "^4.3.2" + globby "^11.0.4" + is-glob "^4.0.3" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/utils@5.19.0": + version "5.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.19.0.tgz#fe87f1e3003d9973ec361ed10d36b4342f1ded1e" + integrity sha512-ZuEckdupXpXamKvFz/Ql8YnePh2ZWcwz7APICzJL985Rp5C2AYcHO62oJzIqNhAMtMK6XvrlBTZeNG8n7gS3lQ== + dependencies: + "@types/json-schema" "^7.0.9" + "@typescript-eslint/scope-manager" "5.19.0" + "@typescript-eslint/types" "5.19.0" + "@typescript-eslint/typescript-estree" "5.19.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/visitor-keys@5.19.0": + version "5.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.19.0.tgz#c84ebc7f6c744707a361ca5ec7f7f64cd85b8af6" + integrity sha512-Ym7zZoMDZcAKWsULi2s7UMLREdVQdScPQ/fKWMYefarCztWlHPFVJo8racf8R0Gc8FAEJ2eD4of8As1oFtnQlQ== + dependencies: + "@typescript-eslint/types" "5.19.0" + eslint-visitor-keys "^3.0.0" + +acorn-jsx@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^8.4.1, acorn@^8.7.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" + integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== + +ajv@^6.10.0, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +axios@^0.21.1: + version "0.21.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== + dependencies: + follow-redirects "^1.14.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base-x@^3.0.2: + version "3.0.9" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" + integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== + dependencies: + safe-buffer "^5.0.1" + +bech32@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-2.0.0.tgz#078d3686535075c8c79709f054b1b226a133b355" + integrity sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg== + +bindings@^1.3.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bip32@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/bip32/-/bip32-2.0.6.tgz#6a81d9f98c4cd57d05150c60d8f9e75121635134" + integrity sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA== + dependencies: + "@types/node" "10.12.18" + bs58check "^2.1.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + tiny-secp256k1 "^1.1.3" + typeforce "^1.11.5" + wif "^2.0.6" + +bip39@^3.0.3: + version "3.0.4" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.0.4.tgz#5b11fed966840b5e1b8539f0f54ab6392969b2a0" + integrity sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw== + dependencies: + "@types/node" "11.11.6" + create-hash "^1.1.0" + pbkdf2 "^3.0.9" + randombytes "^2.0.1" + +bn.js@^4.11.8, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +bs58@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= + dependencies: + base-x "^3.0.2" + +bs58check@<3.0.0, bs58check@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" + integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== + dependencies: + bs58 "^4.0.0" + create-hash "^1.1.0" + safe-buffer "^5.1.2" + +bufferutil@^4.0.3: + version "4.0.6" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.6.tgz#ebd6c67c7922a0e902f053e5d8be5ec850e48433" + integrity sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw== + dependencies: + node-gyp-build "^4.3.0" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +chalk@4.1.2, chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@^4.1.1, debug@^4.3.2: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decimal.js@^10.2.1: + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +elliptic@^6.4.0, elliptic@^6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-scope@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" + integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" + integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== + +eslint@^8.13.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.13.0.tgz#6fcea43b6811e655410f5626cfcf328016badcd7" + integrity sha512-D+Xei61eInqauAyTJ6C0q6x9mx7kTUC1KZ0m0LSEexR0V+e94K12LmWX076ZIsldwfQ2RONdaJe0re0TRGQbRQ== + dependencies: + "@eslint/eslintrc" "^1.2.1" + "@humanwhocodes/config-array" "^0.9.2" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.1.1" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.3.0" + espree "^9.3.1" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^6.0.1" + globals "^13.6.0" + ignore "^5.2.0" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + regexpp "^3.2.0" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^9.3.1: + version "9.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.1.tgz#8793b4bc27ea4c778c19908e0719e7b8f4115bcd" + integrity sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ== + dependencies: + acorn "^8.7.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^3.3.0" + +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.2.5" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" + integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== + +follow-redirects@^1.14.0: + version "1.14.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" + integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fs@^0.0.1-security: + version "0.0.1-security" + resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.1-security.tgz#8a7bd37186b6dddf3813f23858b57ecaaf5e41d4" + integrity sha1-invTcYa23d84E/I4WLV+yq9eQdQ= + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@^7.1.3: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^13.6.0, globals@^13.9.0: + version "13.13.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.13.0.tgz#ac32261060d8070e2719dd6998406e27d2b5727b" + integrity sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A== + dependencies: + type-fest "^0.20.2" + +globby@^11.0.4: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +google-protobuf@^3.17.3: + version "3.20.0" + resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.20.0.tgz#8705ab5fb7e91e9578250a4a8ac533a3cc0bc0bb" + integrity sha512-hhXv5IKLDIkb0pEm53G053UZGhRAhw3wM5Jk7ly5sGIQRkO1s63FaDqM9QjlrPHygKEE2awUlLP9fFrG6M9vfQ== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +ignore@^5.1.8, ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jscrypto@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/jscrypto/-/jscrypto-1.0.3.tgz#598febca2a939d6f679c54f56e1fe364cef30cc9" + integrity sha512-lryZl0flhodv4SZHOqyb1bx5sKcJxj0VBo0Kzb4QMAg3L021IC9uGpl0RCZa+9KJwlRGSK2C80ITcwbe19OKLQ== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + +lru-cache@^7.4.0: + version "7.8.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.8.1.tgz#68ee3f4807a57d2ba185b7fd90827d5c21ce82bb" + integrity sha512-E1v547OCgJvbvevfjgK9sNKIVXO96NnsTsFPBlg4ZxjhsJSODoH9lk8Bm0OxvHNm6Vm5Yqkl/1fErDxhYL8Skg== + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@^3.0.4: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +nan@^2.13.2: + version "2.15.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" + integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +node-addon-api@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" + integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== + +node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.4.0.tgz#42e99687ce87ddeaf3a10b99dc06abc11021f3f4" + integrity sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pbkdf2@^3.0.9: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +protobufjs@~6.11.2: + version "6.11.2" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.2.tgz#de39fabd4ed32beaa08e9bb1e30d08544c1edf8b" + integrity sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" ">=13.7.0" + long "^4.0.0" + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +randombytes@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +regexpp@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +secp256k1@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303" + integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== + dependencies: + elliptic "^6.5.4" + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + +semver@^7.3.5: + version "7.3.6" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.6.tgz#5d73886fb9c0c6602e79440b97165c29581cbb2b" + integrity sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w== + dependencies: + lru-cache "^7.4.0" + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +tiny-secp256k1@^1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz#7e224d2bee8ab8283f284e40e6b4acb74ffe047c" + integrity sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA== + dependencies: + bindings "^1.3.0" + bn.js "^4.11.8" + create-hmac "^1.1.7" + elliptic "^6.4.0" + nan "^2.13.2" + +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +ts-node@^10.4.0: + version "10.7.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.7.0.tgz#35d503d0fab3e2baa672a0e94f4b40653c2463f5" + integrity sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A== + dependencies: + "@cspotcode/source-map-support" "0.7.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.0" + yn "3.1.1" + +tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +typeforce@^1.11.5: + version "1.18.0" + resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc" + integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== + +typescript@^4.4.4: + version "4.6.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" + integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +utf-8-validate@^5.0.5: + version "5.0.9" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.9.tgz#ba16a822fbeedff1a58918f2a6a6b36387493ea3" + integrity sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q== + dependencies: + node-gyp-build "^4.3.0" + +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +v8-compile-cache-lib@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz#0582bcb1c74f3a2ee46487ceecf372e46bce53e8" + integrity sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA== + +v8-compile-cache@^2.0.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wif@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704" + integrity sha1-CNP1IFbGZnkplyb63g1DKudLRwQ= + dependencies: + bs58check "<3.0.0" + +word-wrap@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@^7.4.2: + version "7.5.7" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" + integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==