From 3cbc227491cbde256a180310b6f1c59bcbe63047 Mon Sep 17 00:00:00 2001 From: Armani Ferrante Date: Wed, 24 Mar 2021 20:19:29 -0700 Subject: [PATCH] Events (#89) --- .travis.yml | 1 + CHANGELOG.md | 5 + Cargo.lock | 29 +- client/Cargo.toml | 6 +- client/example/Cargo.toml | 3 +- client/example/run-test.sh | 8 +- client/example/src/main.rs | 45 +- client/src/cluster.rs | 102 +++ client/src/lib.rs | 218 ++++++- .../composite/programs/composite/Cargo.toml | 2 +- examples/events/Anchor.toml | 2 + examples/events/Cargo.toml | 4 + examples/events/migrations/deploy.js | 12 + examples/events/programs/events/Cargo.toml | 18 + examples/events/programs/events/Xargo.toml | 2 + examples/events/programs/events/src/lib.rs | 25 + examples/events/tests/events.js | 25 + .../basic-2/programs/basic-2/Cargo.toml | 2 +- lang/Cargo.toml | 2 + lang/attribute/account/src/lib.rs | 6 + lang/attribute/event/Cargo.toml | 18 + lang/attribute/event/src/lib.rs | 63 ++ lang/attribute/state/src/lib.rs | 4 +- lang/src/lib.rs | 18 +- lang/syn/src/idl.rs | 16 + lang/syn/src/parser/file.rs | 62 +- ts/package.json | 5 +- ts/src/coder.ts | 51 ++ ts/src/idl.ts | 12 + ts/src/program.ts | 160 ++++- ts/src/utils.ts | 45 +- ts/tsconfig.json | 14 +- ts/yarn.lock | 597 ++---------------- 33 files changed, 937 insertions(+), 645 deletions(-) create mode 100644 client/src/cluster.rs create mode 100644 examples/events/Anchor.toml create mode 100644 examples/events/Cargo.toml create mode 100644 examples/events/migrations/deploy.js create mode 100644 examples/events/programs/events/Cargo.toml create mode 100644 examples/events/programs/events/Xargo.toml create mode 100644 examples/events/programs/events/src/lib.rs create mode 100644 examples/events/tests/events.js create mode 100644 lang/attribute/event/Cargo.toml create mode 100644 lang/attribute/event/src/lib.rs diff --git a/.travis.yml b/.travis.yml index 80c80857..5bf07829 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,6 +55,7 @@ jobs: - pushd examples/interface && anchor test && popd - pushd examples/lockup && anchor test && popd - pushd examples/misc && anchor test && popd + - pushd examples/events && anchor test && popd - pushd examples/cashiers-check && anchor test && popd - <<: *examples name: Runs the examples 2 diff --git a/CHANGELOG.md b/CHANGELOG.md index c0c8a96d..d3909bf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,11 @@ incremented for features. * cli: Specify test files to run ([#118](https://github.com/project-serum/anchor/pull/118)). * lang: Allow overriding the `#[state]` account's size ([#121](https://github.com/project-serum/anchor/pull/121)). +* lang, client, ts: Add event emission and subscriptions ([#89](https://github.com/project-serum/anchor/pull/89)). + +## Breaking Changes + +* client: Replace url str with `Cluster` struct when constructing clients ([#89](https://github.com/project-serum/anchor/pull/89)). ## [0.3.0] - 2021-03-12 diff --git a/Cargo.lock b/Cargo.lock index 3d940531..13ba3bd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,6 +75,17 @@ dependencies = [ "syn 1.0.57", ] +[[package]] +name = "anchor-attribute-event" +version = "0.3.0" +dependencies = [ + "anchor-syn", + "anyhow", + "proc-macro2 1.0.24", + "quote 1.0.9", + "syn 1.0.57", +] + [[package]] name = "anchor-attribute-interface" version = "0.3.0" @@ -138,6 +149,8 @@ name = "anchor-client" version = "0.3.0" dependencies = [ "anchor-lang", + "anyhow", + "regex", "solana-client", "solana-sdk", "thiserror", @@ -161,10 +174,12 @@ dependencies = [ "anchor-attribute-access-control", "anchor-attribute-account", "anchor-attribute-error", + "anchor-attribute-event", "anchor-attribute-interface", "anchor-attribute-program", "anchor-attribute-state", "anchor-derive-accounts", + "base64 0.13.0", "borsh", "solana-program", "thiserror", @@ -2367,14 +2382,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.4.3" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" +checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19" dependencies = [ "aho-corasick", "memchr", "regex-syntax", - "thread_local", ] [[package]] @@ -3487,15 +3501,6 @@ dependencies = [ "syn 1.0.57", ] -[[package]] -name = "thread_local" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" -dependencies = [ - "once_cell", -] - [[package]] name = "time" version = "0.1.43" diff --git a/client/Cargo.toml b/client/Cargo.toml index ac0f2be5..600d84f1 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -8,6 +8,8 @@ description = "Rust client for Anchor programs" [dependencies] anchor-lang = { path = "../lang", version = "0.3.0" } -solana-client = "1.5.8" -solana-sdk = "1.5.8" +anyhow = "1.0.32" +regex = "1.4.5" +solana-client = "=1.5.15" +solana-sdk = "=1.5.15" thiserror = "1.0.20" diff --git a/client/example/Cargo.toml b/client/example/Cargo.toml index 353b8bc6..f9034967 100644 --- a/client/example/Cargo.toml +++ b/client/example/Cargo.toml @@ -7,9 +7,10 @@ edition = "2018" [workspace] [dependencies] -anchor-client = { git = "https://github.com/project-serum/anchor" } +anchor-client = { path = "../" } basic-2 = { path = "../../examples/tutorial/basic-2/programs/basic-2", features = ["no-entrypoint"] } composite = { path = "../../examples/composite/programs/composite", features = ["no-entrypoint"] } +events = { path = "../../examples/events/programs/events", features = ["no-entrypoint"] } shellexpand = "2.1.0" anyhow = "1.0.32" rand = "0.7.3" diff --git a/client/example/run-test.sh b/client/example/run-test.sh index acb80da4..7178858a 100755 --- a/client/example/run-test.sh +++ b/client/example/run-test.sh @@ -38,11 +38,15 @@ main() { anchor deploy local basic_2_pid=$(cat target/idl/basic_2.json | jq -r .metadata.address) popd - + pushd ../../examples/events + anchor build + anchor deploy + local events_pid=$(cat target/idl/events.json | jq -r .metadata.address) + popd # # Run Test. # - cargo run -- --composite-pid $composite_pid --basic-2-pid $basic_2_pid + cargo run -- --composite-pid $composite_pid --basic-2-pid $basic_2_pid --events-pid $events_pid } cleanup() { diff --git a/client/example/src/main.rs b/client/example/src/main.rs index 12968e77..39dbd8cf 100644 --- a/client/example/src/main.rs +++ b/client/example/src/main.rs @@ -4,18 +4,21 @@ use anchor_client::solana_sdk::signature::read_keypair_file; use anchor_client::solana_sdk::signature::{Keypair, Signer}; use anchor_client::solana_sdk::system_instruction; use anchor_client::solana_sdk::sysvar; -use anchor_client::Client; +use anchor_client::{Client, Cluster, EventContext}; use anyhow::Result; // The `accounts` and `instructions` modules are generated by the framework. use basic_2::accounts as basic_2_accounts; use basic_2::instruction as basic_2_instruction; use basic_2::Counter; +use events::instruction as events_instruction; +use events::MyEvent; // The `accounts` and `instructions` modules are generated by the framework. use clap::Clap; use composite::accounts::{Bar, CompositeUpdate, Foo, Initialize}; use composite::instruction as composite_instruction; use composite::{DummyA, DummyB}; use rand::rngs::OsRng; +use std::time::Duration; #[derive(Clap)] pub struct Opts { @@ -23,6 +26,8 @@ pub struct Opts { composite_pid: Pubkey, #[clap(long)] basic_2_pid: Pubkey, + #[clap(long)] + events_pid: Pubkey, } // This example assumes a local validator is running with the programs @@ -33,7 +38,10 @@ fn main() -> Result<()> { // Wallet and cluster params. let payer = read_keypair_file(&*shellexpand::tilde("~/.config/solana/id.json")) .expect("Example requires a keypair file"); - let url = "http://localhost:8899"; + let url = Cluster::Custom( + "http://localhost:8899".to_string(), + "ws://127.0.0.1:8900".to_string(), + ); // Client. let client = Client::new_with_options(url, payer, CommitmentConfig::processed()); @@ -41,6 +49,7 @@ fn main() -> Result<()> { // Run tests. composite(&client, opts.composite_pid)?; basic_2(&client, opts.basic_2_pid)?; + events(&client, opts.events_pid)?; // Success. Ok(()) @@ -155,3 +164,35 @@ fn basic_2(client: &Client, pid: Pubkey) -> Result<()> { Ok(()) } + +fn events(client: &Client, pid: Pubkey) -> Result<()> { + let program = client.program(pid); + + let (sender, receiver) = std::sync::mpsc::channel(); + let handle = program.on(move |_ctx: &EventContext, event: MyEvent| { + sender.send(event).unwrap(); + })?; + + std::thread::sleep(Duration::from_millis(1000)); + + program + .request() + .args(events_instruction::Initialize {}) + .send()?; + + let event = receiver.recv().unwrap(); + assert_eq!(event.data, 5); + assert_eq!(event.label, "hello".to_string()); + + // TODO: remove once https://github.com/solana-labs/solana/issues/16102 + // is addressed. Until then, drop the subscription handle in another + // thread so that we deadlock in the other thread as to not block + // this thread. + std::thread::spawn(move || { + drop(handle); + }); + + println!("Success!"); + + Ok(()) +} diff --git a/client/src/cluster.rs b/client/src/cluster.rs new file mode 100644 index 00000000..5177cca1 --- /dev/null +++ b/client/src/cluster.rs @@ -0,0 +1,102 @@ +use anyhow::Result; +use std::str::FromStr; + +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum Cluster { + Testnet, + Mainnet, + VipMainnet, + Devnet, + Localnet, + Debug, + Custom(String, String), +} + +impl Default for Cluster { + fn default() -> Self { + Cluster::Localnet + } +} + +impl FromStr for Cluster { + type Err = anyhow::Error; + fn from_str(s: &str) -> Result { + match s.to_lowercase().as_str() { + "t" | "testnet" => Ok(Cluster::Testnet), + "m" | "mainnet" => Ok(Cluster::Mainnet), + "v" | "vipmainnet" => Ok(Cluster::VipMainnet), + "d" | "devnet" => Ok(Cluster::Devnet), + "l" | "localnet" => Ok(Cluster::Localnet), + "g" | "debug" => Ok(Cluster::Debug), + _ => Err(anyhow::Error::msg( + "Cluster must be one of [localnet, testnet, mainnet, devnet] or be an http or https url\n", + )), + } + } +} + +impl std::fmt::Display for Cluster { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + let clust_str = match self { + Cluster::Testnet => "testnet", + Cluster::Mainnet => "mainnet", + Cluster::VipMainnet => "vipmainnet", + Cluster::Devnet => "devnet", + Cluster::Localnet => "localnet", + Cluster::Debug => "debug", + Cluster::Custom(url, _ws_url) => url, + }; + write!(f, "{}", clust_str) + } +} + +impl Cluster { + pub fn url(&self) -> &str { + match self { + Cluster::Devnet => "https://devnet.solana.com", + Cluster::Testnet => "https://testnet.solana.com", + Cluster::Mainnet => "https://api.mainnet-beta.solana.com", + Cluster::VipMainnet => "https://vip-api.mainnet-beta.solana.com", + Cluster::Localnet => "http://127.0.0.1:8899", + Cluster::Debug => "http://34.90.18.145:8899", + Cluster::Custom(url, _ws_url) => url, + } + } + pub fn ws_url(&self) -> &str { + match self { + Cluster::Devnet => "wss://devnet.solana.com", + Cluster::Testnet => "wss://testnet.solana.com", + Cluster::Mainnet => "wss://api.mainnet-beta.solana.com", + Cluster::VipMainnet => "wss://vip-api.mainnet-beta.solana.com", + Cluster::Localnet => "ws://127.0.0.1:9000", + Cluster::Debug => "ws://34.90.18.145:9000", + Cluster::Custom(_url, ws_url) => ws_url, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn test_cluster(name: &str, cluster: Cluster) { + assert_eq!(Cluster::from_str(name).unwrap(), cluster); + } + + #[test] + fn test_cluster_parse() { + test_cluster("testnet", Cluster::Testnet); + test_cluster("mainnet", Cluster::Mainnet); + test_cluster("vipmainnet", Cluster::VipMainnet); + test_cluster("devnet", Cluster::Devnet); + test_cluster("localnet", Cluster::Localnet); + test_cluster("debug", Cluster::Debug); + } + + #[test] + #[should_panic] + fn test_cluster_bad_parse() { + let bad_url = "httq://my_custom_url.test.net"; + Cluster::from_str(bad_url).unwrap(); + } +} diff --git a/client/src/lib.rs b/client/src/lib.rs index 481e1f28..9f45a9fb 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -5,8 +5,12 @@ use anchor_lang::solana_program::instruction::{AccountMeta, Instruction}; use anchor_lang::solana_program::program_error::ProgramError; use anchor_lang::solana_program::pubkey::Pubkey; use anchor_lang::{AccountDeserialize, InstructionData, ToAccountMetas}; +use regex::Regex; use solana_client::client_error::ClientError as SolanaClientError; +use solana_client::pubsub_client::{PubsubClient, PubsubClientError, PubsubClientSubscription}; use solana_client::rpc_client::RpcClient; +use solana_client::rpc_config::{RpcTransactionLogsConfig, RpcTransactionLogsFilter}; +use solana_client::rpc_response::{Response as RpcResponse, RpcLogsResponse}; use solana_sdk::commitment_config::CommitmentConfig; use solana_sdk::signature::{Keypair, Signature, Signer}; use solana_sdk::transaction::Transaction; @@ -14,9 +18,15 @@ use std::convert::Into; use thiserror::Error; pub use anchor_lang; +pub use cluster::Cluster; pub use solana_client; pub use solana_sdk; +mod cluster; + +/// EventHandle unsubscribes from a program event stream on drop. +pub type EventHandle = PubsubClientSubscription>; + /// Client defines the base configuration for building RPC clients to /// communitcate with Anchor programs running on a Solana cluster. It's /// primary use is to build a `Program` client via the `program` method. @@ -25,20 +35,20 @@ pub struct Client { } impl Client { - pub fn new(cluster: &str, payer: Keypair) -> Self { + pub fn new(cluster: Cluster, payer: Keypair) -> Self { Self { cfg: Config { - cluster: cluster.to_string(), + cluster, payer, options: None, }, } } - pub fn new_with_options(cluster: &str, payer: Keypair, options: CommitmentConfig) -> Self { + pub fn new_with_options(cluster: Cluster, payer: Keypair, options: CommitmentConfig) -> Self { Self { cfg: Config { - cluster: cluster.to_string(), + cluster, payer, options: Some(options), }, @@ -59,7 +69,7 @@ impl Client { // Internal configuration for a client. struct Config { - cluster: String, + cluster: Cluster, payer: Keypair, options: Option, } @@ -79,7 +89,7 @@ impl Program { pub fn request(&self) -> RequestBuilder { RequestBuilder::new( self.program_id, - &self.cfg.cluster, + &self.cfg.cluster.url(), Keypair::from_bytes(&self.cfg.payer.to_bytes()).unwrap(), self.cfg.options, ) @@ -88,7 +98,7 @@ impl Program { /// Returns the account at the given address. pub fn account(&self, address: Pubkey) -> Result { let rpc_client = RpcClient::new_with_commitment( - self.cfg.cluster.clone(), + self.cfg.cluster.url().to_string(), self.cfg.options.unwrap_or_default(), ); let account = rpc_client @@ -101,7 +111,7 @@ impl Program { pub fn rpc(&self) -> RpcClient { RpcClient::new_with_commitment( - self.cfg.cluster.clone(), + self.cfg.cluster.url().to_string(), self.cfg.options.unwrap_or_default(), ) } @@ -109,6 +119,163 @@ impl Program { pub fn id(&self) -> Pubkey { self.program_id } + + pub fn on( + &self, + f: impl Fn(&EventContext, T) -> () + Send + 'static, + ) -> Result { + let addresses = vec![self.program_id.to_string()]; + let filter = RpcTransactionLogsFilter::Mentions(addresses); + let ws_url = self.cfg.cluster.ws_url().to_string(); + let cfg = RpcTransactionLogsConfig { + commitment: self.cfg.options, + }; + let self_program_str = self.program_id.to_string(); + let (client, receiver) = PubsubClient::logs_subscribe(&ws_url, filter.clone(), cfg)?; + std::thread::spawn(move || { + loop { + match receiver.recv() { + Ok(logs) => { + let ctx = EventContext { + signature: logs.value.signature.parse().unwrap(), + slot: logs.context.slot, + }; + let mut logs = &logs.value.logs[..]; + if logs.len() > 0 { + if let Ok(mut execution) = Execution::new(&mut logs) { + for l in logs { + // Parse the log. + let (event, new_program, did_pop) = { + if self_program_str == execution.program() { + handle_program_log(&self_program_str, &l) + .unwrap_or_else(|e| { + println!( + "Unable to parse log: {}", + e.to_string() + ); + std::process::exit(1); + }) + } else { + let (program, did_pop) = + handle_system_log(&self_program_str, &l); + (None, program, did_pop) + } + }; + // Emit the event. + if let Some(e) = event { + f(&ctx, e); + } + // Switch program context on CPI. + if let Some(new_program) = new_program { + execution.push(new_program); + } + // Program returned. + if did_pop { + execution.pop(); + } + } + } + } + } + Err(_err) => { + return; + } + } + } + }); + Ok(client) + } +} + +fn handle_program_log( + self_program_str: &str, + l: &str, +) -> Result<(Option, Option, bool), ClientError> { + // Log emitted from the current program. + if l.starts_with("Program log:") { + let log = l.to_string().split_off("Program log: ".len()); + let borsh_bytes = anchor_lang::__private::base64::decode(log) + .map_err(|_| ClientError::LogParseError(l.to_string()))?; + + let mut slice: &[u8] = &borsh_bytes[..]; + let disc: [u8; 8] = { + let mut disc = [0; 8]; + disc.copy_from_slice(&borsh_bytes[..8]); + slice = &slice[8..]; + disc + }; + let mut event = None; + if disc == T::discriminator() { + let e: T = anchor_lang::AnchorDeserialize::deserialize(&mut slice) + .map_err(|e| ClientError::LogParseError(e.to_string()))?; + event = Some(e); + } + Ok((event, None, false)) + } + // System log. + else { + let (program, did_pop) = handle_system_log(&self_program_str, &l); + Ok((None, program, did_pop)) + } +} + +fn handle_system_log(this_program_str: &str, log: &str) -> (Option, bool) { + if log.starts_with(&format!("Program {} log:", this_program_str)) { + (Some(this_program_str.to_string()), false) + } else if log.contains("invoke") { + (Some("cpi".to_string()), false) // Any string will do. + } else { + let re = Regex::new(r"^Program (.*) success*$").unwrap(); + if re.is_match(log) { + (None, true) + } else { + (None, false) + } + } +} + +struct Execution { + stack: Vec, +} + +impl Execution { + pub fn new(logs: &mut &[String]) -> Result { + let l = &logs[0]; + *logs = &logs[1..]; + + let re = Regex::new(r"^Program (.*) invoke.*$").unwrap(); + let c = re + .captures(l) + .ok_or(ClientError::LogParseError(l.to_string()))?; + let program = c + .get(1) + .ok_or(ClientError::LogParseError(l.to_string()))? + .as_str() + .to_string(); + Ok(Self { + stack: vec![program], + }) + } + + pub fn program(&self) -> String { + assert!(self.stack.len() > 0); + self.stack[self.stack.len() - 1].clone() + } + + pub fn push(&mut self, new_program: String) { + self.stack.push(new_program); + } + + pub fn pop(&mut self) { + assert!(self.stack.len() > 0); + self.stack.pop().unwrap(); + } +} + +#[derive(Debug)] +pub struct EventContext { + pub signature: Signature, + pub slot: u64, } #[derive(Debug, Error)] @@ -119,6 +286,10 @@ pub enum ClientError { ProgramError(#[from] ProgramError), #[error("{0}")] SolanaClientError(#[from] SolanaClientError), + #[error("{0}")] + SolanaClientPubsubError(#[from] PubsubClientError), + #[error("Unable to parse log: {0}")] + LogParseError(String), } /// `RequestBuilder` provides a builder interface to create and send @@ -225,3 +396,34 @@ impl<'a> RequestBuilder<'a> { .map_err(Into::into) } } + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn new_execution() { + let mut logs: &[String] = + &["Program 7Y8VDzehoewALqJfyxZYMgYCnMTCDhWuGfJKUvjYWATw invoke [1]".to_string()]; + let exe = Execution::new(&mut logs).unwrap(); + assert_eq!( + exe.stack[0], + "7Y8VDzehoewALqJfyxZYMgYCnMTCDhWuGfJKUvjYWATw".to_string() + ); + } + + #[test] + fn handle_system_log_pop() { + let log = "Program 7Y8VDzehoewALqJfyxZYMgYCnMTCDhWuGfJKUvjYWATw success"; + let (program, did_pop) = handle_system_log("asdf", log); + assert_eq!(program, None); + assert_eq!(did_pop, true); + } + + #[test] + fn handle_system_log_no_pop() { + let log = "Program 7swsTUiQ6KUK4uFYquQKg4epFRsBnvbrTf2fZQCa2sTJ qwer"; + let (program, did_pop) = handle_system_log("asdf", log); + assert_eq!(program, None); + assert_eq!(did_pop, false); + } +} diff --git a/examples/composite/programs/composite/Cargo.toml b/examples/composite/programs/composite/Cargo.toml index c78f75bc..32eb1514 100644 --- a/examples/composite/programs/composite/Cargo.toml +++ b/examples/composite/programs/composite/Cargo.toml @@ -13,4 +13,4 @@ no-entrypoint = [] cpi = ["no-entrypoint"] [dependencies] -anchor-lang = { git = "https://github.com/project-serum/anchor", features = ["derive"] } +anchor-lang = { path = "../../../../lang" } diff --git a/examples/events/Anchor.toml b/examples/events/Anchor.toml new file mode 100644 index 00000000..2ebd5af9 --- /dev/null +++ b/examples/events/Anchor.toml @@ -0,0 +1,2 @@ +cluster = "localnet" +wallet = "~/.config/solana/id.json" diff --git a/examples/events/Cargo.toml b/examples/events/Cargo.toml new file mode 100644 index 00000000..a60de986 --- /dev/null +++ b/examples/events/Cargo.toml @@ -0,0 +1,4 @@ +[workspace] +members = [ + "programs/*" +] diff --git a/examples/events/migrations/deploy.js b/examples/events/migrations/deploy.js new file mode 100644 index 00000000..325cf3d0 --- /dev/null +++ b/examples/events/migrations/deploy.js @@ -0,0 +1,12 @@ +// Migrations are an early feature. Currently, they're nothing more than this +// single deploy script that's invoked from the CLI, injecting a provider +// configured from the workspace's Anchor.toml. + +const anchor = require("@project-serum/anchor"); + +module.exports = async function (provider) { + // Configure client to use the provider. + anchor.setProvider(provider); + + // Add your deploy script here. +} diff --git a/examples/events/programs/events/Cargo.toml b/examples/events/programs/events/Cargo.toml new file mode 100644 index 00000000..8c113a1e --- /dev/null +++ b/examples/events/programs/events/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "events" +version = "0.1.0" +description = "Created with Anchor" +edition = "2018" + +[lib] +crate-type = ["cdylib", "lib"] +name = "events" + +[features] +no-entrypoint = [] +no-idl = [] +cpi = ["no-entrypoint"] +default = [] + +[dependencies] +anchor-lang = { path = "../../../../lang" } diff --git a/examples/events/programs/events/Xargo.toml b/examples/events/programs/events/Xargo.toml new file mode 100644 index 00000000..1744f098 --- /dev/null +++ b/examples/events/programs/events/Xargo.toml @@ -0,0 +1,2 @@ +[target.bpfel-unknown-unknown.dependencies.std] +features = [] \ No newline at end of file diff --git a/examples/events/programs/events/src/lib.rs b/examples/events/programs/events/src/lib.rs new file mode 100644 index 00000000..7e1e45c4 --- /dev/null +++ b/examples/events/programs/events/src/lib.rs @@ -0,0 +1,25 @@ +#![feature(proc_macro_hygiene)] + +use anchor_lang::prelude::*; + +#[program] +pub mod events { + use super::*; + pub fn initialize(_ctx: Context) -> ProgramResult { + emit!(MyEvent { + data: 5, + label: "hello".to_string(), + }); + Ok(()) + } +} + +#[derive(Accounts)] +pub struct Initialize {} + +#[event] +pub struct MyEvent { + pub data: u64, + #[index] + pub label: String, +} diff --git a/examples/events/tests/events.js b/examples/events/tests/events.js new file mode 100644 index 00000000..8f70f9ae --- /dev/null +++ b/examples/events/tests/events.js @@ -0,0 +1,25 @@ +const anchor = require('@project-serum/anchor'); +const assert = require("assert"); + +describe("events", () => { + // Configure the client to use the local cluster. + anchor.setProvider(anchor.Provider.env()); + + it("Is initialized!", async () => { + const program = anchor.workspace.Events; + + let listener = null; + + let [event, slot] = await new Promise((resolve, _reject) => { + listener = program.addEventListener("MyEvent", (event, slot) => { + resolve([event, slot]); + }); + program.rpc.initialize(); + }); + await program.removeEventListener(listener); + + assert.ok(slot > 0); + assert.ok(event.data.toNumber() === 5); + assert.ok(event.label === "hello"); + }); +}); diff --git a/examples/tutorial/basic-2/programs/basic-2/Cargo.toml b/examples/tutorial/basic-2/programs/basic-2/Cargo.toml index 3152224e..c7902493 100644 --- a/examples/tutorial/basic-2/programs/basic-2/Cargo.toml +++ b/examples/tutorial/basic-2/programs/basic-2/Cargo.toml @@ -13,4 +13,4 @@ no-entrypoint = [] cpi = ["no-entrypoint"] [dependencies] -anchor-lang = { git = "https://github.com/project-serum/anchor", features = ["derive"] } +anchor-lang = { path = "../../../../../lang" } diff --git a/lang/Cargo.toml b/lang/Cargo.toml index cee6f66c..342b1e6f 100644 --- a/lang/Cargo.toml +++ b/lang/Cargo.toml @@ -19,6 +19,8 @@ anchor-attribute-program = { path = "./attribute/program", version = "0.3.0" } anchor-attribute-state = { path = "./attribute/state", version = "0.3.0" } anchor-attribute-interface = { path = "./attribute/interface", version = "0.3.0" } anchor-derive-accounts = { path = "./derive/accounts", version = "0.3.0" } +anchor-attribute-event = { path = "./attribute/event", version = "0.3.0" } borsh = "0.8.2" solana-program = "=1.5.15" thiserror = "1.0.20" +base64 = "0.13.0" diff --git a/lang/attribute/account/src/lib.rs b/lang/attribute/account/src/lib.rs index fe41be1d..3f0ca4af 100644 --- a/lang/attribute/account/src/lib.rs +++ b/lang/attribute/account/src/lib.rs @@ -66,6 +66,12 @@ pub fn account( .map_err(|_| ProgramError::InvalidAccountData) } } + + impl anchor_lang::Discriminator for #account_name { + fn discriminator() -> [u8; 8] { + #discriminator + } + } }; proc_macro::TokenStream::from(quote! { diff --git a/lang/attribute/event/Cargo.toml b/lang/attribute/event/Cargo.toml new file mode 100644 index 00000000..c6215575 --- /dev/null +++ b/lang/attribute/event/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "anchor-attribute-event" +version = "0.3.0" +authors = ["Serum Foundation "] +repository = "https://github.com/project-serum/anchor" +license = "Apache-2.0" +description = "Anchor attribute macro for defining an event" +edition = "2018" + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1.0" +quote = "1.0" +syn = { version = "=1.0.57", features = ["full"] } +anyhow = "1.0.32" +anchor-syn = { path = "../../syn", version = "0.3.0", features = ["hash"] } diff --git a/lang/attribute/event/src/lib.rs b/lang/attribute/event/src/lib.rs new file mode 100644 index 00000000..89ad2714 --- /dev/null +++ b/lang/attribute/event/src/lib.rs @@ -0,0 +1,63 @@ +extern crate proc_macro; + +use quote::quote; +use syn::parse_macro_input; + +/// A data structure representing a Solana account. +#[proc_macro_attribute] +pub fn event( + _args: proc_macro::TokenStream, + input: proc_macro::TokenStream, +) -> proc_macro::TokenStream { + let event_strct = parse_macro_input!(input as syn::ItemStruct); + + let event_name = &event_strct.ident; + + let discriminator: proc_macro2::TokenStream = { + let discriminator_preimage = format!("event:{}", event_name.to_string()); + let mut discriminator = [0u8; 8]; + discriminator.copy_from_slice( + &anchor_syn::hash::hash(discriminator_preimage.as_bytes()).to_bytes()[..8], + ); + format!("{:?}", discriminator).parse().unwrap() + }; + + proc_macro::TokenStream::from(quote! { + #[derive(anchor_lang::EventIndex, AnchorSerialize, AnchorDeserialize)] + #event_strct + + impl anchor_lang::EventData for #event_name { + fn data(&self) -> Vec { + let mut d = #discriminator.to_vec(); + d.append(&mut self.try_to_vec().unwrap()); + d + } + } + + impl anchor_lang::Discriminator for #event_name { + fn discriminator() -> [u8; 8] { + #discriminator + } + } + }) +} + +#[proc_macro] +pub fn emit(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let data: proc_macro2::TokenStream = input.into(); + proc_macro::TokenStream::from(quote! { + { + let data = anchor_lang::EventData::data(&#data); + let msg_str = &anchor_lang::__private::base64::encode(data); + anchor_lang::solana_program::msg!(msg_str); + } + }) +} + +// EventIndex is a marker macro. It functionally does nothing other than +// allow one to mark fields with the `#[index]` inert attribute, which is +// used to add metadata to IDLs. +#[proc_macro_derive(EventIndex, attributes(index))] +pub fn derive_event(_item: proc_macro::TokenStream) -> proc_macro::TokenStream { + proc_macro::TokenStream::from(quote! {}) +} diff --git a/lang/attribute/state/src/lib.rs b/lang/attribute/state/src/lib.rs index f2fd479b..50269810 100644 --- a/lang/attribute/state/src/lib.rs +++ b/lang/attribute/state/src/lib.rs @@ -26,7 +26,7 @@ pub fn state( // as the initialized value. Use the default implementation. quote! { impl anchor_lang::AccountSize for #struct_ident { - fn size(&self) -> Result { + fn size(&self) -> std::result::Result { Ok(8 + self .try_to_vec() .map_err(|_| ProgramError::Custom(1))? @@ -39,7 +39,7 @@ pub fn state( // Size override given to the macro. Use it. quote! { impl anchor_lang::AccountSize for #struct_ident { - fn size(&self) -> Result { + fn size(&self) -> std::result::Result { Ok(#size) } } diff --git a/lang/src/lib.rs b/lang/src/lib.rs index 648f7c11..621cd0f2 100644 --- a/lang/src/lib.rs +++ b/lang/src/lib.rs @@ -41,6 +41,11 @@ mod state; mod sysvar; mod vec; +// Internal module used by macros. +pub mod __private { + pub use base64; +} + pub use crate::context::{Context, CpiContext}; pub use crate::cpi_account::CpiAccount; pub use crate::ctor::Ctor; @@ -50,6 +55,7 @@ pub use crate::sysvar::Sysvar; pub use anchor_attribute_access_control::access_control; pub use anchor_attribute_account::account; pub use anchor_attribute_error::error; +pub use anchor_attribute_event::{emit, event, EventIndex}; pub use anchor_attribute_interface::interface; pub use anchor_attribute_program::program; pub use anchor_attribute_state::state; @@ -175,11 +181,21 @@ pub trait AccountSize: AnchorSerialize { fn size(&self) -> Result; } +/// The serialized event data to be emitted via a Solana log. +pub trait EventData: AnchorSerialize + Discriminator { + fn data(&self) -> Vec; +} + +/// 8 byte identifier for a type. +pub trait Discriminator { + fn discriminator() -> [u8; 8]; +} + /// The prelude contains all commonly used components of the crate. /// All programs should include it via `anchor_lang::prelude::*;`. pub mod prelude { pub use super::{ - access_control, account, error, interface, program, state, AccountDeserialize, + access_control, account, emit, error, event, interface, program, state, AccountDeserialize, AccountSerialize, Accounts, AccountsExit, AccountsInit, AnchorDeserialize, AnchorSerialize, Context, CpiAccount, CpiContext, Ctor, ProgramAccount, ProgramState, Sysvar, ToAccountInfo, ToAccountInfos, ToAccountMetas, diff --git a/lang/syn/src/idl.rs b/lang/syn/src/idl.rs index 2c9438f4..f96fac07 100644 --- a/lang/syn/src/idl.rs +++ b/lang/syn/src/idl.rs @@ -12,6 +12,8 @@ pub struct Idl { #[serde(skip_serializing_if = "Vec::is_empty", default)] pub types: Vec, #[serde(skip_serializing_if = "Option::is_none", default)] + pub events: Option>, + #[serde(skip_serializing_if = "Option::is_none", default)] pub errors: Option>, #[serde(skip_serializing_if = "Option::is_none", default)] pub metadata: Option, @@ -64,6 +66,20 @@ pub struct IdlField { pub ty: IdlType, } +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct IdlEvent { + pub name: String, + pub fields: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct IdlEventField { + pub name: String, + #[serde(rename = "type")] + pub ty: IdlType, + pub index: bool, +} + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct IdlTypeDef { pub name: String, diff --git a/lang/syn/src/parser/file.rs b/lang/syn/src/parser/file.rs index b8583227..e1f40252 100644 --- a/lang/syn/src/parser/file.rs +++ b/lang/syn/src/parser/file.rs @@ -176,6 +176,36 @@ pub fn parse(filename: impl AsRef) -> Result { }) .collect::>(); + let events = parse_events(&f) + .iter() + .map(|e: &&syn::ItemStruct| { + let fields = match &e.fields { + syn::Fields::Named(n) => n, + _ => panic!("Event fields must be named"), + }; + let fields = fields + .named + .iter() + .map(|f: &syn::Field| { + let index = match f.attrs.iter().next() { + None => false, + Some(i) => parser::tts_to_string(&i.path) == "index", + }; + IdlEventField { + name: f.ident.clone().unwrap().to_string(), + ty: parser::tts_to_string(&f.ty).to_string().parse().unwrap(), + index, + } + }) + .collect::>(); + + IdlEvent { + name: e.ident.to_string(), + fields, + } + }) + .collect::>(); + // All user defined types. let mut accounts = vec![]; let mut types = vec![]; @@ -188,7 +218,7 @@ pub fn parse(filename: impl AsRef) -> Result { if ty_def.name != error_name { if acc_names.contains(&ty_def.name) { accounts.push(ty_def); - } else { + } else if events.iter().position(|e| e.name == ty_def.name).is_none() { types.push(ty_def); } } @@ -201,6 +231,11 @@ pub fn parse(filename: impl AsRef) -> Result { instructions, types, accounts, + events: if events.is_empty() { + None + } else { + Some(events) + }, errors: error_codes, metadata: None, }) @@ -256,6 +291,31 @@ fn parse_error_enum(f: &syn::File) -> Option { .next() .cloned() } + +fn parse_events(f: &syn::File) -> Vec<&syn::ItemStruct> { + f.items + .iter() + .filter_map(|i| match i { + syn::Item::Struct(item_strct) => { + let attrs_count = item_strct + .attrs + .iter() + .filter(|attr| { + let segment = attr.path.segments.last().unwrap(); + segment.ident == "event" + }) + .count(); + match attrs_count { + 0 => None, + 1 => Some(item_strct), + _ => panic!("Invalid syntax: one event attribute allowed"), + } + } + _ => None, + }) + .collect() +} + // Parse all structs implementing the `Accounts` trait. fn parse_accounts(f: &syn::File) -> HashMap { f.items diff --git a/ts/package.json b/ts/package.json index 166def00..bdea8903 100644 --- a/ts/package.json +++ b/ts/package.json @@ -1,6 +1,6 @@ { "name": "@project-serum/anchor", - "version": "0.3.0", + "version": "0.3.1-beta.2", "description": "Anchor client", "main": "dist/cjs/index.js", "module": "dist/esm/index.js", @@ -24,11 +24,12 @@ }, "dependencies": { "@project-serum/borsh": "^0.1.0", - "@solana/web3.js": "^0.90.4", + "@solana/web3.js": "^1.1.0", "@types/bn.js": "^4.11.6", "@types/bs58": "^4.0.1", "@types/crypto-hash": "^1.1.2", "@types/pako": "^1.0.1", + "base64-js": "^1.5.1", "bn.js": "^5.1.2", "bs58": "^4.0.1", "buffer-layout": "^1.2.0", diff --git a/ts/src/coder.ts b/ts/src/coder.ts index dd4639ef..58d3bfb3 100644 --- a/ts/src/coder.ts +++ b/ts/src/coder.ts @@ -51,10 +51,16 @@ export default class Coder { */ readonly state: StateCoder; + /** + * Coder for events. + */ + readonly events: EventCoder; + constructor(idl: Idl) { this.instruction = new InstructionCoder(idl); this.accounts = new AccountsCoder(idl); this.types = new TypesCoder(idl); + this.events = new EventCoder(idl); if (idl.state) { this.state = new StateCoder(idl); } @@ -201,6 +207,46 @@ class TypesCoder { } } +class EventCoder { + /** + * Maps account type identifier to a layout. + */ + private layouts: Map; + + public constructor(idl: Idl) { + if (idl.events === undefined) { + this.layouts = new Map(); + return; + } + const layouts = idl.events.map((event) => { + let eventTypeDef: IdlTypeDef = { + name: event.name, + type: { + kind: "struct", + fields: event.fields.map((f) => { + return { name: f.name, type: f.type }; + }), + }, + }; + return [event.name, IdlCoder.typeDefLayout(eventTypeDef, idl.types)]; + }); + // @ts-ignore + this.layouts = new Map(layouts); + } + + public encode(eventName: string, account: T): Buffer { + const buffer = Buffer.alloc(1000); // TODO: use a tighter buffer. + const layout = this.layouts.get(eventName); + const len = layout.encode(account, buffer); + return buffer.slice(0, len); + } + + public decode(eventName: string, ix: Buffer): T { + const layout = this.layouts.get(eventName); + return layout.decode(ix); + } +} + class StateCoder { private layout: Layout; @@ -364,6 +410,11 @@ export async function stateDiscriminator(name: string): Promise { return Buffer.from(sha256.digest(`account:${name}`)).slice(0, 8); } +export function eventDiscriminator(name: string): Buffer { + // @ts-ignore + return Buffer.from(sha256.digest(`event:${name}`)).slice(0, 8); +} + // Returns the size of the type in bytes. For variable length types, just return // 1. Users should override this value in such cases. function typeSize(idl: Idl, ty: IdlType): number { diff --git a/ts/src/idl.ts b/ts/src/idl.ts index 375549c8..8ff02544 100644 --- a/ts/src/idl.ts +++ b/ts/src/idl.ts @@ -8,9 +8,21 @@ export type Idl = { state?: IdlState; accounts?: IdlTypeDef[]; types?: IdlTypeDef[]; + events?: IdlEvent[]; errors?: IdlErrorCode[]; }; +export type IdlEvent = { + name: string; + fields: IdlEventField[]; +}; + +export type IdlEventField = { + name: string; + type: IdlType; + index: boolean; +}; + export type IdlInstruction = { name: string; accounts: IdlAccountItem[]; diff --git a/ts/src/program.ts b/ts/src/program.ts index 8ec7e135..993c2642 100644 --- a/ts/src/program.ts +++ b/ts/src/program.ts @@ -3,9 +3,11 @@ import { inflate } from "pako"; import Provider from "./provider"; import { RpcFactory } from "./rpc"; import { Idl, idlAddress, decodeIdlAccount } from "./idl"; -import Coder from "./coder"; +import Coder, { eventDiscriminator } from "./coder"; import { Rpcs, Ixs, Txs, Accounts, State } from "./rpc"; import { getProvider } from "./"; +import * as base64 from "base64-js"; +import * as assert from "assert"; /** * Program is the IDL deserialized representation of a Solana program. @@ -100,6 +102,162 @@ export class Program { const inflatedIdl = inflate(idlAccount.data); return JSON.parse(decodeUtf8(inflatedIdl)); } + + /** + * Invokes the given callback everytime the given event is emitted. + */ + public addEventListener( + eventName: string, + callback: (event: T, slot: number) => void + ): Promise { + // Values shared across log handlers. + const thisProgramStr = this.programId.toString(); + const discriminator = eventDiscriminator(eventName); + const logStartIndex = "Program log: ".length; + + // Handles logs when the current program being executing is *not* this. + const handleSystemLog = (log: string): [string | null, boolean] => { + // System component. + const logStart = log.split(":")[0]; + // Recursive call. + if (logStart.startsWith(`Program ${this.programId.toString()} invoke`)) { + return [this.programId.toString(), false]; + } + // Cpi call. + else if (logStart.includes("invoke")) { + return ["cpi", false]; // Any string will do. + } else { + // Did the program finish executing? + if (logStart.match(/^Program (.*) consumed .*$/g) !== null) { + return [null, true]; + } + return [null, false]; + } + }; + + // Handles logs from *this* program. + const handleProgramLog = ( + log: string + ): [T | null, string | null, boolean] => { + // This is a `msg!` log. + if (log.startsWith("Program log:")) { + const logStr = log.slice(logStartIndex); + const logArr = Buffer.from(base64.toByteArray(logStr)); + const disc = logArr.slice(0, 8); + // Only deserialize if the discriminator implies a proper event. + let event = null; + if (disc.equals(discriminator)) { + event = this.coder.events.decode(eventName, logArr.slice(8)); + } + return [event, null, false]; + } + // System log. + else { + return [null, ...handleSystemLog(log)]; + } + }; + + // Main log handler. Returns a three element array of the event, the + // next program that was invoked for CPI, and a boolean indicating if + // a program has completed execution (and thus should be popped off the + // execution stack). + const handleLog = ( + execution: ExecutionContext, + log: string + ): [T | null, string | null, boolean] => { + // Executing program is this program. + if (execution.program() === thisProgramStr) { + return handleProgramLog(log); + } + // Executing program is not this program. + else { + return [null, ...handleSystemLog(log)]; + } + }; + + // Each log given, represents an array of messages emitted by + // a single transaction, which can execute many different programs across + // CPI boundaries. However, the subscription is only interested in the + // events emitted by *this* program. In achieving this, we keep track of the + // program execution context by parsing each log and looking for a CPI + // `invoke` call. If one exists, we know a new program is executing. So we + // push the programId onto a stack and switch the program context. This + // allows us to track, for a given log, which program was executing during + // its emission, thereby allowing us to know if a given log event was + // emitted by *this* program. If it was, then we parse the raw string and + // emit the event if the string matches the event being subscribed to. + // + // @ts-ignore + return this.provider.connection.onLogs(this.programId, (logs, ctx) => { + if (logs.err) { + console.error(logs); + return; + } + + const logScanner = new LogScanner(logs.logs); + const execution = new ExecutionContext(logScanner.next() as string); + + let log = logScanner.next(); + while (log !== null) { + let [event, newProgram, didPop] = handleLog(execution, log); + if (event) { + callback(event, ctx.slot); + } + if (newProgram) { + execution.push(newProgram); + } + if (didPop) { + execution.pop(); + } + log = logScanner.next(); + } + }); + } + + public async removeEventListener(listener: number): Promise { + // @ts-ignore + return this.provider.connection.removeOnLogsListener(listener); + } +} + +// Stack frame execution context, allowing one to track what program is +// executing for a given log. +class ExecutionContext { + stack: string[]; + + constructor(log: string) { + // Assumes the first log in every transaction is an `invoke` log from the + // runtime. + const program = /^Program (.*) invoke.*$/g.exec(log)[1]; + this.stack = [program]; + } + + program(): string { + assert.ok(this.stack.length > 0); + return this.stack[this.stack.length - 1]; + } + + push(newProgram: string) { + this.stack.push(newProgram); + } + + pop() { + assert.ok(this.stack.length > 0); + this.stack.pop(); + } +} + +class LogScanner { + constructor(public logs: string[]) {} + + next(): string | null { + if (this.logs.length === 0) { + return null; + } + let l = this.logs[0]; + this.logs = this.logs.slice(1); + return l; + } } function decodeUtf8(array: Uint8Array): string { diff --git a/ts/src/utils.ts b/ts/src/utils.ts index e33319fd..047d9064 100644 --- a/ts/src/utils.ts +++ b/ts/src/utils.ts @@ -1,9 +1,8 @@ import * as bs58 from "bs58"; import { sha256 } from "crypto-hash"; -import { struct } from "superstruct"; import assert from "assert"; import { PublicKey, AccountInfo, Connection } from "@solana/web3.js"; -import { idlAddress } from './idl'; +import { idlAddress } from "./idl"; export const TOKEN_PROGRAM_ID = new PublicKey( "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" @@ -16,9 +15,7 @@ async function getMultipleAccounts( Array }> > { const args = [publicKeys.map((k) => k.toBase58()), { commitment: "recent" }]; - // @ts-ignore - const unsafeRes = await connection._rpcRequest("getMultipleAccounts", args); - const res = GetMultipleAccountsAndContextRpcResult(unsafeRes); + const res = await connection._rpcRequest("getMultipleAccounts", args); if (res.error) { throw new Error( "failed to get info about accounts " + @@ -71,44 +68,6 @@ async function getMultipleAccounts( }); } -function jsonRpcResult(resultDescription: any) { - const jsonRpcVersion = struct.literal("2.0"); - return struct.union([ - struct({ - jsonrpc: jsonRpcVersion, - id: "string", - error: "any", - }), - struct({ - jsonrpc: jsonRpcVersion, - id: "string", - error: "null?", - result: resultDescription, - }), - ]); -} - -function jsonRpcResultAndContext(resultDescription: any) { - return jsonRpcResult({ - context: struct({ - slot: "number", - }), - value: resultDescription, - }); -} - -const AccountInfoResult = struct({ - executable: "boolean", - owner: "string", - lamports: "number", - data: "any", - rentEpoch: "number?", -}); - -const GetMultipleAccountsAndContextRpcResult = jsonRpcResultAndContext( - struct.array([struct.union(["null", AccountInfoResult])]) -); - const utils = { bs58, sha256, diff --git a/ts/tsconfig.json b/ts/tsconfig.json index af9edf92..85591d4f 100644 --- a/ts/tsconfig.json +++ b/ts/tsconfig.json @@ -1,27 +1,27 @@ { "include": ["src"], - "compilerOptions": { - "moduleResolution": "node", + "compilerOptions": { + "moduleResolution": "node", "module": "es6", "target": "es2019", "outDir": "dist/esm/", "rootDir": "./src", - "declarationDir": "dist", + "declarationDir": "dist", "sourceMap": true, "declaration": true, "allowSyntheticDefaultImports": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, - "noImplicitAny": true, + "noImplicitAny": false, "esModuleInterop": true, "composite": true, - "baseUrl": ".", - "typeRoots": ["types/", "node_modules/@types"], + "baseUrl": ".", + "typeRoots": ["types/", "node_modules/@types"], "paths": { - "@solana/web3.js": ["../../node_modules/@solana/web3.js/lib"] + "@solana/web3.js": ["./node_modules/@solana/web3.js/lib"] } } } diff --git a/ts/yarn.lock b/ts/yarn.lock index affb3881..a75644f0 100644 --- a/ts/yarn.lock +++ b/ts/yarn.lock @@ -241,7 +241,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/runtime@^7.11.2", "@babel/runtime@^7.3.1": +"@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5": version "7.13.10" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== @@ -676,28 +676,24 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@solana/web3.js@^0.90.4": - version "0.90.5" - resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-0.90.5.tgz#5be7d78a19f0b5e01bf82c52e3cbf0bb72a38cfd" - integrity sha512-2elnwfIkdtrUjLdTBKu7Rc3mTv95k2cn+JtNtmO2fY/PFRZm7mnGS/gk/wWzGCpBVLiqz2o6o21oONqyDtLG/w== +"@solana/web3.js@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.1.0.tgz#b31815c9fa7cabeefe8175034bfe300b9d4011e7" + integrity sha512-n8O5wvoogrwQJWe9rQml/QlN+lQu9VaBGueeSR/9oyefktzchZS9ar1hsatybCvqNSRQCnmTme9zQwY1kJkMGw== dependencies: - "@babel/runtime" "^7.3.1" + "@babel/runtime" "^7.12.5" bn.js "^5.0.0" bs58 "^4.0.1" - buffer "^6.0.1" + buffer "6.0.1" buffer-layout "^1.2.0" crypto-hash "^1.2.2" - esdoc-inject-style-plugin "^1.0.0" - jayson "^3.0.1" - keccak "^3.0.1" - mz "^2.7.0" - node-fetch "^2.2.0" - npm-run-all "^4.1.5" + jayson "^3.4.4" + js-sha3 "^0.8.0" + node-fetch "^2.6.1" rpc-websockets "^7.4.2" secp256k1 "^4.0.2" - superstruct "^0.8.3" + superstruct "^0.14.2" tweetnacl "^1.0.0" - ws "^7.0.0" "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7": version "7.1.12" @@ -1030,11 +1026,6 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -any-promise@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= - anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -1230,7 +1221,7 @@ base-x@^3.0.2, base-x@^3.0.6: dependencies: safe-buffer "^5.0.1" -base64-js@^1.3.1: +base64-js@^1.3.1, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -1270,11 +1261,6 @@ bn.js@^5.1.2: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== -boolbase@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1347,10 +1333,10 @@ buffer-layout@^1.2.0: resolved "https://registry.yarnpkg.com/buffer-layout/-/buffer-layout-1.2.0.tgz#ee1f5ef05a8afd5db6b3a8fe2056c111bc69c737" integrity sha512-iiyRoho/ERzBUv6kFvfsrLNgTlVwOkqQcSQN7WrO3Y+c5SeuEhCn6+y1KwhM0V3ndptF5mI/RI44zkw0qcR5Jg== -buffer@^6.0.1: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== +buffer@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.1.tgz#3cbea8c1463e5a0779e30b66d4c88c6ffa182ac2" + integrity sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ== dependencies: base64-js "^1.3.1" ieee754 "^1.2.1" @@ -1377,14 +1363,6 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -1429,7 +1407,7 @@ chalk@4.1.0, chalk@^4.0.0, chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^2.0.0, chalk@^2.4.1: +chalk@^2.0.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1443,28 +1421,6 @@ char-regex@^1.0.2: resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== -cheerio@0.22.0: - version "0.22.0" - resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e" - integrity sha1-qbqoYKP5tZWmuBsahocxIe06Jp4= - dependencies: - css-select "~1.2.0" - dom-serializer "~0.1.0" - entities "~1.1.1" - htmlparser2 "^3.9.1" - lodash.assignin "^4.0.9" - lodash.bind "^4.1.4" - lodash.defaults "^4.0.1" - lodash.filter "^4.4.0" - lodash.flatten "^4.2.0" - lodash.foreach "^4.3.0" - lodash.map "^4.4.0" - lodash.merge "^4.4.0" - lodash.pick "^4.2.1" - lodash.reduce "^4.4.0" - lodash.reject "^4.4.0" - lodash.some "^4.4.0" - ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" @@ -1679,7 +1635,7 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cross-spawn@^6.0.0, cross-spawn@^6.0.5: +cross-spawn@^6.0.0: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -1704,21 +1660,6 @@ crypto-hash@*, crypto-hash@^1.2.2, crypto-hash@^1.3.0: resolved "https://registry.yarnpkg.com/crypto-hash/-/crypto-hash-1.3.0.tgz#b402cb08f4529e9f4f09346c3e275942f845e247" integrity sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg== -css-select@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" - integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= - dependencies: - boolbase "~1.0.0" - css-what "2.1" - domutils "1.5.1" - nth-check "~1.0.1" - -css-what@2.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" - integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== - cssom@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" @@ -1816,13 +1757,6 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== -define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" @@ -1879,32 +1813,6 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dom-serializer@0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" - integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== - dependencies: - domelementtype "^2.0.1" - entities "^2.0.0" - -dom-serializer@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" - integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== - dependencies: - domelementtype "^1.3.0" - entities "^1.1.1" - -domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" - integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== - -domelementtype@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.1.0.tgz#a851c080a6d1c3d94344aed151d99f669edf585e" - integrity sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w== - domexception@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" @@ -1912,29 +1820,6 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" -domhandler@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" - integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== - dependencies: - domelementtype "1" - -domutils@1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" - integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= - dependencies: - dom-serializer "0" - domelementtype "1" - -domutils@^1.5.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" - integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== - dependencies: - dom-serializer "0" - domelementtype "1" - dot-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" @@ -1995,16 +1880,6 @@ enquirer@^2.3.5, enquirer@^2.3.6: dependencies: ansi-colors "^4.1.1" -entities@^1.1.1, entities@~1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" - integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== - -entities@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" - integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== - error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" @@ -2012,37 +1887,6 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.18.0-next.2: - version "1.18.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0.tgz#ab80b359eecb7ede4c298000390bc5ac3ec7b5a4" - integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.2" - is-callable "^1.2.3" - is-negative-zero "^2.0.1" - is-regex "^1.1.2" - is-string "^1.0.5" - object-inspect "^1.9.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.4" - string.prototype.trimstart "^1.0.4" - unbox-primitive "^1.0.0" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - es6-promise@^4.0.3: version "4.2.8" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" @@ -2077,14 +1921,6 @@ escodegen@^1.14.1: optionalDependencies: source-map "~0.6.1" -esdoc-inject-style-plugin@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/esdoc-inject-style-plugin/-/esdoc-inject-style-plugin-1.0.0.tgz#a13597368bb9fb89c365e066495caf97a4decbb1" - integrity sha1-oTWXNou5+4nDZeBmSVyvl6Tey7E= - dependencies: - cheerio "0.22.0" - fs-extra "1.0.0" - eslint-config-prettier@^6.15.0: version "6.15.0" resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz#7f93f6cb7d45a92f1537a70ecc06366e1ac6fed9" @@ -2461,15 +2297,6 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" -fs-extra@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950" - integrity sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA= - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - fs-extra@^9.0.0: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" @@ -2510,15 +2337,6 @@ get-caller-file@^2.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" @@ -2631,7 +2449,7 @@ globby@^11.0.1: merge2 "^1.3.0" slash "^3.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: +graceful-fs@^4.1.6: version "4.2.6" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== @@ -2664,11 +2482,6 @@ hard-rejection@^2.1.0: resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== -has-bigints@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" - integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -2679,11 +2492,6 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-symbols@^1.0.0, has-symbols@^1.0.1, has-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" - integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== - has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" @@ -2763,18 +2571,6 @@ html-escaper@^2.0.0: resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -htmlparser2@^3.9.1: - version "3.10.1" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" - integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== - dependencies: - domelementtype "^1.3.1" - domhandler "^2.3.0" - domutils "^1.5.1" - entities "^1.1.1" - inherits "^2.0.1" - readable-stream "^3.1.1" - http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -2861,7 +2657,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -2895,28 +2691,11 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= -is-bigint@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.1.tgz#6923051dfcbc764278540b9ce0e6b3213aa5ebc2" - integrity sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg== - -is-boolean-object@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.0.tgz#e2aaad3a3a8fca34c28f6eee135b156ed2587ff0" - integrity sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA== - dependencies: - call-bind "^1.0.0" - is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-callable@^1.1.4, is-callable@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" - integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== - is-capitalized@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-capitalized/-/is-capitalized-1.0.0.tgz#4c8464b4d91d3e4eeb44889dd2cd8f1b0ac4c136" @@ -2955,11 +2734,6 @@ is-data-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== - is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" @@ -3017,16 +2791,6 @@ is-glob@^4.0.0, is-glob@^4.0.1: dependencies: is-extglob "^2.1.1" -is-negative-zero@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" - integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== - -is-number-object@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" - integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw== - is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -3066,14 +2830,6 @@ is-potential-custom-element-name@^1.0.0: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397" integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c= -is-regex@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" - integrity sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg== - dependencies: - call-bind "^1.0.2" - has-symbols "^1.0.1" - is-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" @@ -3089,18 +2845,6 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== -is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== - dependencies: - has-symbols "^1.0.1" - is-text-path@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" @@ -3193,7 +2937,7 @@ istanbul-reports@^3.0.2: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jayson@^3.0.1: +jayson@^3.4.4: version "3.4.4" resolved "https://registry.yarnpkg.com/jayson/-/jayson-3.4.4.tgz#dcedffba0c02785c4aa22dbff8c28966cae59773" integrity sha512-fgQflh+Qnhdv9fjxTnpTsa2WUG/dgyeKQzIh5MJ77Qv2sqFyyAZn7mTUYgPjJMFjsKfb4HNsSBh6ktJeeQiAGQ== @@ -3612,6 +3356,11 @@ js-sha256@^0.9.0: resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" integrity sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA== +js-sha3@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -3667,11 +3416,6 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - json-parse-even-better-errors@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" @@ -3704,13 +3448,6 @@ json5@2.x, json5@^2.1.2: dependencies: minimist "^1.2.5" -jsonfile@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= - optionalDependencies: - graceful-fs "^4.1.6" - jsonfile@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" @@ -3735,14 +3472,6 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -keccak@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.1.tgz#ae30a0e94dbe43414f741375cff6d64c8bea0bff" - integrity sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA== - dependencies: - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - keypather@^1.10.2: version "1.10.2" resolved "https://registry.yarnpkg.com/keypather/-/keypather-1.10.2.tgz#e0449632d4b3e516f21cc014ce7c5644fddce614" @@ -3774,13 +3503,6 @@ kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= - optionalDependencies: - graceful-fs "^4.1.9" - kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" @@ -3847,16 +3569,6 @@ listr2@^3.2.2: rxjs "^6.6.3" through "^2.3.8" -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -3876,71 +3588,11 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= -lodash.assignin@^4.0.9: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" - integrity sha1-uo31+4QesKPoBEIysOJjqNxqKKI= - -lodash.bind@^4.1.4: - version "4.2.1" - resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35" - integrity sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU= - -lodash.defaults@^4.0.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" - integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= - -lodash.filter@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace" - integrity sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4= - -lodash.flatten@^4.2.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" - integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= - -lodash.foreach@^4.3.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" - integrity sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM= - -lodash.map@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" - integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM= - lodash.memoize@4.x: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= -lodash.merge@^4.4.0: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash.pick@^4.2.1: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" - integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= - -lodash.reduce@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b" - integrity sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs= - -lodash.reject@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415" - integrity sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU= - -lodash.some@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" - integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= - lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -4043,11 +3695,6 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -memorystream@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" - integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= - meow@^8.0.0: version "8.1.0" resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.0.tgz#0fcaa267e35e4d58584b8205923df6021ddcc7ba" @@ -4178,15 +3825,6 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -mz@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" - integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== - dependencies: - any-promise "^1.0.0" - object-assign "^4.0.1" - thenify-all "^1.0.0" - nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -4227,7 +3865,7 @@ node-addon-api@^2.0.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== -node-fetch@^2.2.0: +node-fetch@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== @@ -4259,7 +3897,7 @@ node-notifier@^8.0.0: uuid "^8.3.0" which "^2.0.2" -normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: +normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== @@ -4291,21 +3929,6 @@ normalize-path@^3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -npm-run-all@^4.1.5: - version "4.1.5" - resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" - integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ== - dependencies: - ansi-styles "^3.2.1" - chalk "^2.4.1" - cross-spawn "^6.0.5" - memorystream "^0.3.1" - minimatch "^3.0.4" - pidtree "^0.3.0" - read-pkg "^3.0.0" - shell-quote "^1.6.1" - string.prototype.padend "^3.0.0" - npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -4320,13 +3943,6 @@ npm-run-path@^4.0.0: dependencies: path-key "^3.0.0" -nth-check@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" - integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== - dependencies: - boolbase "~1.0.0" - nwsapi@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" @@ -4337,11 +3953,6 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - object-copy@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" @@ -4351,16 +3962,6 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" - integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== - -object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" @@ -4368,16 +3969,6 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" -object.assign@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" - object-keys "^1.1.1" - object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -4490,14 +4081,6 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - parse-json@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.1.0.tgz#f96088cdf24a8faa9aea9a009f2d9d942c999646" @@ -4543,13 +4126,6 @@ path-parse@^1.0.6: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -4565,16 +4141,6 @@ picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== -pidtree@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a" - integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA== - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - pirates@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" @@ -4691,15 +4257,6 @@ read-pkg-up@^7.0.1: read-pkg "^5.2.0" type-fest "^0.8.1" -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - read-pkg@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" @@ -4710,7 +4267,7 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.1.1: +readable-stream@3, readable-stream@^3.0.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== @@ -5051,11 +4608,6 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shell-quote@^1.6.1: - version "1.7.2" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" - integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== - shellwords@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" @@ -5280,31 +4832,6 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string.prototype.padend@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.2.tgz#6858ca4f35c5268ebd5e8615e1327d55f59ee311" - integrity sha512-/AQFLdYvePENU3W5rgurfWSMU6n+Ww8n/3cUt7E+vPBB/D7YDG8x+qjoFs4M/alR2bW7Qg6xMjVwWUOvuQ0XpQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.2" - -string.prototype.trimend@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" - integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string.prototype.trimstart@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" - integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -5335,11 +4862,6 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - strip-bom@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" @@ -5367,13 +4889,10 @@ strip-json-comments@^3.1.0, strip-json-comments@^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== -superstruct@^0.8.3: - version "0.8.4" - resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.8.4.tgz#478a19649f6b02c6319c02044db6a1f5863c391f" - integrity sha512-48Ors8IVWZm/tMr8r0Si6+mJiB7mkD7jqvIzktjJ4+EnP5tBp0qOpiM1J8sCUorKx+TXWrfb3i1UcjdD1YK/wA== - dependencies: - kind-of "^6.0.2" - tiny-invariant "^1.0.6" +superstruct@^0.14.2: + version "0.14.2" + resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.14.2.tgz#0dbcdf3d83676588828f1cf5ed35cda02f59025b" + integrity sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ== supports-color@^5.3.0: version "5.5.0" @@ -5439,20 +4958,6 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= -thenify-all@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" - integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= - dependencies: - thenify ">= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.1" - resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" - integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== - dependencies: - any-promise "^1.0.0" - throat@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" @@ -5478,11 +4983,6 @@ through2@^4.0.0: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= -tiny-invariant@^1.0.6: - version "1.1.0" - resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875" - integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== - tmpl@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" @@ -5683,16 +5183,6 @@ typescript@^4.0.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7" integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg== -unbox-primitive@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.0.tgz#eeacbc4affa28e9b3d36b5eaeccc50b3251b1d3f" - integrity sha512-P/51NX+JXyxK/aigg1/ZgyccdAxm5K1+n8+tvqSntjOivPt19gvm1VC49RWYetsiub8WViUchdxl/KWHHB0kzA== - dependencies: - function-bind "^1.1.1" - has-bigints "^1.0.0" - has-symbols "^1.0.0" - which-boxed-primitive "^1.0.1" - union-value@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" @@ -5838,17 +5328,6 @@ whatwg-url@^8.0.0: tr46 "^2.0.2" webidl-conversions "^6.1.0" -which-boxed-primitive@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" @@ -5902,16 +5381,16 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -ws@^7.0.0, ws@^7.3.1: - version "7.4.4" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59" - integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw== - ws@^7.2.3: version "7.4.2" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.2.tgz#782100048e54eb36fe9843363ab1c68672b261dd" integrity sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA== +ws@^7.3.1: + version "7.4.4" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59" + integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw== + xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"