From ce3b7f0d4201416135c318bfe3b8764510504466 Mon Sep 17 00:00:00 2001 From: DaughterOfMars Date: Mon, 16 Dec 2024 03:47:58 -0500 Subject: [PATCH 01/14] chore(lints): Use expect over allow (#4402) * chore(clippy): Use expect over allow * add comment * fix release warning * revert type complexity allow * review * revert trait config * another revert --------- Co-authored-by: Thibault Martinez --- consensus/core/src/authority_node.rs | 6 +- consensus/core/src/base_committer.rs | 12 +-- consensus/core/src/block_verifier.rs | 3 +- consensus/core/src/commit.rs | 1 - consensus/core/src/core.rs | 2 +- consensus/core/src/leader_schedule.rs | 2 +- consensus/core/src/leader_scoring_strategy.rs | 2 +- consensus/core/src/network/metrics_layer.rs | 2 +- consensus/core/src/stake_aggregator.rs | 3 +- consensus/core/src/storage/mem_store.rs | 3 - consensus/core/src/storage/mod.rs | 6 +- consensus/core/src/storage/rocksdb_store.rs | 8 +- consensus/core/src/synchronizer.rs | 13 +-- consensus/core/src/test_dag_builder.rs | 21 ++-- consensus/core/src/transaction.rs | 3 +- consensus/core/src/universal_committer.rs | 2 +- .../src/analytics_processor.rs | 4 +- crates/iota-archival/src/lib.rs | 2 +- crates/iota-aws-orchestrator/src/benchmark.rs | 1 - crates/iota-aws-orchestrator/src/monitor.rs | 3 +- crates/iota-benchmark/src/drivers/mod.rs | 1 - crates/iota-benchmark/src/lib.rs | 2 +- crates/iota-bridge/src/action_executor.rs | 97 ++++++++----------- .../iota-bridge/src/e2e_tests/test_utils.rs | 1 - crates/iota-bridge/src/eth_syncer.rs | 1 - crates/iota-bridge/src/iota_mock_client.rs | 2 +- crates/iota-bridge/src/monitor.rs | 2 +- crates/iota-bridge/src/orchestrator.rs | 2 +- crates/iota-bridge/src/server/mock_handler.rs | 2 +- crates/iota-cluster-test/src/lib.rs | 1 - .../iota-common/src/sync/async_once_cell.rs | 2 +- crates/iota-common/src/sync/notify_once.rs | 2 +- crates/iota-config/src/genesis.rs | 2 +- crates/iota-core/src/authority.rs | 7 +- .../authority/authority_per_epoch_store.rs | 15 ++- .../src/authority/authority_store.rs | 2 +- .../src/authority/authority_store_types.rs | 16 +-- .../authority/epoch_start_configuration.rs | 2 +- crates/iota-core/src/authority_aggregator.rs | 4 +- .../checkpoints/checkpoint_executor/mod.rs | 2 +- crates/iota-core/src/checkpoints/mod.rs | 4 +- crates/iota-core/src/connection_monitor.rs | 4 +- crates/iota-core/src/consensus_adapter.rs | 3 +- crates/iota-core/src/epoch/randomness.rs | 5 +- crates/iota-core/src/overload_monitor.rs | 2 +- crates/iota-core/src/stake_aggregator.rs | 2 +- crates/iota-core/src/test_utils.rs | 7 +- crates/iota-core/src/transaction_manager.rs | 3 +- .../iota-core/src/transaction_orchestrator.rs | 2 +- .../unit_tests/authority_aggregator_tests.rs | 4 +- .../src/unit_tests/execution_driver_tests.rs | 2 +- .../unit_tests/transaction_manager_tests.rs | 2 +- .../unit_tests/transfer_to_object_tests.rs | 2 +- .../tests/dynamic_committee_tests.rs | 6 +- .../tests/shared_objects_tests.rs | 1 - .../iota-faucet/src/faucet/simple_faucet.rs | 2 +- crates/iota-genesis-builder/src/lib.rs | 2 +- .../src/stardust/migration/mod.rs | 2 +- crates/iota-graphql-config/src/lib.rs | 2 +- .../iota-graphql-rpc-client/src/response.rs | 4 +- .../src/simple_client.rs | 2 +- crates/iota-graphql-rpc/src/raw_query.rs | 1 - crates/iota-graphql-rpc/src/server/version.rs | 2 +- crates/iota-graphql-rpc/src/types/epoch.rs | 1 - .../iota-graphql-rpc/src/types/move_object.rs | 2 +- crates/iota-graphql-rpc/src/types/object.rs | 4 +- crates/iota-graphql-rpc/src/types/owner.rs | 2 +- .../src/apis/transaction_builder_api.rs | 2 +- crates/iota-indexer/src/models/tx_indices.rs | 2 +- .../iota-indexer/src/store/indexer_store.rs | 2 +- .../src/store/pg_indexer_store.rs | 2 +- crates/iota-indexer/tests/ingestion_tests.rs | 2 +- crates/iota-indexer/tests/rpc-tests/main.rs | 2 +- crates/iota-json-rpc/src/authority_state.rs | 1 - crates/iota-json-rpc/src/axum_router.rs | 1 - .../src/transaction_execution_api.rs | 2 +- .../iota-light-client/src/bin/light_client.rs | 2 +- crates/iota-macros/src/lib.rs | 2 - crates/iota-metrics/src/metrics_network.rs | 2 +- crates/iota-metrics/src/monitored_mpsc.rs | 2 +- crates/iota-network/src/discovery/builder.rs | 1 - crates/iota-network/src/randomness/mod.rs | 4 +- crates/iota-network/src/state_sync/builder.rs | 2 +- crates/iota-network/src/state_sync/server.rs | 2 +- crates/iota-node/src/lib.rs | 2 +- crates/iota-proc-macros/src/lib.rs | 2 +- crates/iota-protocol-config-macros/src/lib.rs | 4 +- crates/iota-protocol-config/src/lib.rs | 2 +- crates/iota-replay/src/fuzz.rs | 2 +- crates/iota-replay/src/replay.rs | 6 +- crates/iota-replay/src/types.rs | 1 - crates/iota-rest-api/src/reader.rs | 2 +- crates/iota-rosetta/src/errors.rs | 1 - crates/iota-rosetta/src/types.rs | 3 - crates/iota-rosetta/tests/gas_budget_tests.rs | 4 +- crates/iota-rpc-loadgen/src/payload/mod.rs | 1 - crates/iota-sdk/examples/utils.rs | 2 +- .../tests/tests.rs | 2 +- crates/iota-swarm/src/memory/swarm.rs | 2 +- crates/iota-tool/src/commands.rs | 1 - crates/iota-tool/src/lib.rs | 3 +- .../iota-transactional-test-runner/src/lib.rs | 1 - crates/iota-types/src/authenticator_state.rs | 3 +- crates/iota-types/src/crypto.rs | 2 +- crates/iota-types/src/effects/effects_v1.rs | 1 - crates/iota-types/src/effects/mod.rs | 1 - crates/iota-types/src/error.rs | 4 +- crates/iota-types/src/gas.rs | 2 +- crates/iota-types/src/gas_model/gas_v1.rs | 3 +- crates/iota-types/src/gas_model/tables.rs | 3 +- crates/iota-types/src/messages_checkpoint.rs | 3 +- crates/iota-types/src/messages_consensus.rs | 1 - crates/iota-types/src/object.rs | 3 - crates/iota-types/src/timelock/mod.rs | 2 +- crates/iota-util-mem-derive/lib.rs | 2 +- crates/iota/src/client_ptb/builder.rs | 2 +- crates/iota/src/genesis_inspector.rs | 5 +- crates/iota/src/iota_commands.rs | 1 - crates/iota/src/keytool.rs | 1 - crates/simulacrum/src/lib.rs | 4 +- crates/simulacrum/src/store/in_mem_store.rs | 1 - crates/telemetry-subscribers/src/lib.rs | 3 +- crates/typed-store-derive/src/lib.rs | 8 +- crates/typed-store/src/rocks/mod.rs | 8 +- examples/tic-tac-toe/cli/src/turn_cap.rs | 7 +- .../latest/iota-adapter/src/gas_charger.rs | 6 +- .../programmable_transactions/execution.rs | 2 +- .../src/object_runtime/object_store.rs | 1 - 128 files changed, 213 insertions(+), 279 deletions(-) diff --git a/consensus/core/src/authority_node.rs b/consensus/core/src/authority_node.rs index b07c487bfac..70f81c271fb 100644 --- a/consensus/core/src/authority_node.rs +++ b/consensus/core/src/authority_node.rs @@ -36,8 +36,8 @@ use crate::{ /// ConsensusAuthority is used by Iota to manage the lifetime of AuthorityNode. /// It hides the details of the implementation from the caller, /// MysticetiManager. -#[allow(private_interfaces)] pub enum ConsensusAuthority { + #[expect(private_interfaces)] WithTonic(AuthorityNode), } @@ -100,7 +100,7 @@ impl ConsensusAuthority { } } - #[allow(unused)] + #[cfg(test)] fn sync_last_known_own_block_enabled(&self) -> bool { match self { Self::WithTonic(authority) => authority.sync_last_known_own_block, @@ -124,6 +124,7 @@ where broadcaster: Option, subscriber: Option>>, network_manager: N, + #[cfg(test)] sync_last_known_own_block: bool, } @@ -306,6 +307,7 @@ where broadcaster, subscriber, network_manager, + #[cfg(test)] sync_last_known_own_block, } } diff --git a/consensus/core/src/base_committer.rs b/consensus/core/src/base_committer.rs index 2440f2c513a..bdc9188d1b1 100644 --- a/consensus/core/src/base_committer.rs +++ b/consensus/core/src/base_committer.rs @@ -427,19 +427,19 @@ mod base_committer_builder { } } - #[allow(unused)] + #[expect(unused)] pub(crate) fn with_wave_length(mut self, wave_length: u32) -> Self { self.wave_length = wave_length; self } - #[allow(unused)] + #[expect(unused)] pub(crate) fn with_leader_offset(mut self, leader_offset: u32) -> Self { self.leader_offset = leader_offset; self } - #[allow(unused)] + #[expect(unused)] pub(crate) fn with_round_offset(mut self, round_offset: u32) -> Self { self.round_offset = round_offset; self @@ -447,9 +447,9 @@ mod base_committer_builder { pub(crate) fn build(self) -> BaseCommitter { let options = BaseCommitterOptions { - wave_length: DEFAULT_WAVE_LENGTH, - leader_offset: 0, - round_offset: 0, + wave_length: self.wave_length, + leader_offset: self.leader_offset, + round_offset: self.round_offset, }; BaseCommitter::new( self.context.clone(), diff --git a/consensus/core/src/block_verifier.rs b/consensus/core/src/block_verifier.rs index 74b7a8e4583..843a495fe4d 100644 --- a/consensus/core/src/block_verifier.rs +++ b/consensus/core/src/block_verifier.rs @@ -206,9 +206,10 @@ impl BlockVerifier for SignedBlockVerifier { } } -#[allow(unused)] +#[cfg(test)] pub(crate) struct NoopBlockVerifier; +#[cfg(test)] impl BlockVerifier for NoopBlockVerifier { fn verify(&self, _block: &SignedBlock) -> ConsensusResult<()> { Ok(()) diff --git a/consensus/core/src/commit.rs b/consensus/core/src/commit.rs index 9135fd342e1..fc2221a84b0 100644 --- a/consensus/core/src/commit.rs +++ b/consensus/core/src/commit.rs @@ -91,7 +91,6 @@ impl Commit { pub(crate) trait CommitAPI { fn round(&self) -> Round; fn index(&self) -> CommitIndex; - #[allow(dead_code)] fn previous_digest(&self) -> CommitDigest; fn timestamp_ms(&self) -> BlockTimestampMs; fn leader(&self) -> BlockRef; diff --git a/consensus/core/src/core.rs b/consensus/core/src/core.rs index 8031ddd064a..1446fb656e4 100644 --- a/consensus/core/src/core.rs +++ b/consensus/core/src/core.rs @@ -849,7 +849,7 @@ pub(crate) struct CoreTextFixture { pub core: Core, pub signal_receivers: CoreSignalsReceivers, pub block_receiver: broadcast::Receiver, - #[allow(unused)] + #[expect(unused)] pub commit_receiver: UnboundedReceiver, pub store: Arc, } diff --git a/consensus/core/src/leader_schedule.rs b/consensus/core/src/leader_schedule.rs index 62b9e522b98..871f9f5c1ea 100644 --- a/consensus/core/src/leader_schedule.rs +++ b/consensus/core/src/leader_schedule.rs @@ -298,7 +298,7 @@ impl LeaderSwapTable { context: Arc, // Ignore linter warning in simtests. // TODO: maybe override protocol configs in tests for swap_stake_threshold, and call new(). - #[allow(unused_variables)] swap_stake_threshold: u64, + #[cfg_attr(msim, expect(unused_variables))] swap_stake_threshold: u64, commit_index: CommitIndex, reputation_scores: ReputationScores, ) -> Self { diff --git a/consensus/core/src/leader_scoring_strategy.rs b/consensus/core/src/leader_scoring_strategy.rs index 72b54eb4e9a..366ad857bdf 100644 --- a/consensus/core/src/leader_scoring_strategy.rs +++ b/consensus/core/src/leader_scoring_strategy.rs @@ -11,13 +11,13 @@ use crate::{ stake_aggregator::{QuorumThreshold, StakeAggregator}, }; -#[allow(unused)] pub(crate) trait ScoringStrategy: Send + Sync { fn calculate_scores_for_leader(&self, subdag: &UnscoredSubdag, leader_slot: Slot) -> Vec; // Based on the scoring strategy there is a minimum number of rounds required // for the scores to be calculated. This method allows that to be set by the // scoring strategy. + #[expect(unused)] fn leader_scoring_round_range(&self, min_round: u32, max_round: u32) -> Range; } diff --git a/consensus/core/src/network/metrics_layer.rs b/consensus/core/src/network/metrics_layer.rs index c9949830dcf..01c35cc31c5 100644 --- a/consensus/core/src/network/metrics_layer.rs +++ b/consensus/core/src/network/metrics_layer.rs @@ -79,7 +79,7 @@ impl MetricsCallbackMaker { pub(crate) struct MetricsResponseCallback { metrics: Arc, // The timer is held on to and "observed" once dropped - #[allow(unused)] + #[expect(unused)] timer: HistogramTimer, route: String, excessive_message_size: usize, diff --git a/consensus/core/src/stake_aggregator.rs b/consensus/core/src/stake_aggregator.rs index 4c2a1c8c06a..330939c2873 100644 --- a/consensus/core/src/stake_aggregator.rs +++ b/consensus/core/src/stake_aggregator.rs @@ -12,7 +12,7 @@ pub(crate) trait CommitteeThreshold { pub(crate) struct QuorumThreshold; -#[allow(unused)] +#[cfg(test)] pub(crate) struct ValidityThreshold; impl CommitteeThreshold for QuorumThreshold { @@ -21,6 +21,7 @@ impl CommitteeThreshold for QuorumThreshold { } } +#[cfg(test)] impl CommitteeThreshold for ValidityThreshold { fn is_threshold(committee: &Committee, amount: Stake) -> bool { committee.reached_validity(amount) diff --git a/consensus/core/src/storage/mem_store.rs b/consensus/core/src/storage/mem_store.rs index 656837433f7..602fd2ba4f9 100644 --- a/consensus/core/src/storage/mem_store.rs +++ b/consensus/core/src/storage/mem_store.rs @@ -21,12 +21,10 @@ use crate::{ }; /// In-memory storage for testing. -#[allow(unused)] pub(crate) struct MemStore { inner: RwLock, } -#[allow(unused)] struct Inner { blocks: BTreeMap<(Round, AuthorityIndex, BlockDigest), VerifiedBlock>, digests_by_authorities: BTreeSet<(AuthorityIndex, Round, BlockDigest)>, @@ -36,7 +34,6 @@ struct Inner { } impl MemStore { - #[cfg(test)] pub(crate) fn new() -> Self { MemStore { inner: RwLock::new(Inner { diff --git a/consensus/core/src/storage/mod.rs b/consensus/core/src/storage/mod.rs index d83d49cb89e..925ed467fbb 100644 --- a/consensus/core/src/storage/mod.rs +++ b/consensus/core/src/storage/mod.rs @@ -2,6 +2,7 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +#[cfg(test)] pub(crate) mod mem_store; pub(crate) mod rocksdb_store; @@ -12,13 +13,12 @@ use consensus_config::AuthorityIndex; use crate::{ CommitIndex, - block::{BlockRef, Round, Slot, VerifiedBlock}, + block::{BlockRef, Round, VerifiedBlock}, commit::{CommitInfo, CommitRange, CommitRef, TrustedCommit}, error::ConsensusResult, }; /// A common interface for consensus storage. -#[allow(unused)] pub(crate) trait Store: Send + Sync { /// Writes blocks, consensus commits and other data to store atomically. fn write(&self, write_batch: WriteBatch) -> ConsensusResult<()>; @@ -31,7 +31,7 @@ pub(crate) trait Store: Send + Sync { /// Checks whether there is any block at the given slot #[allow(dead_code)] - fn contains_block_at_slot(&self, slot: Slot) -> ConsensusResult; + fn contains_block_at_slot(&self, slot: crate::block::Slot) -> ConsensusResult; /// Reads blocks for an authority, from start_round. fn scan_blocks_by_author( diff --git a/consensus/core/src/storage/rocksdb_store.rs b/consensus/core/src/storage/rocksdb_store.rs index 39f18a906b7..aa06216318a 100644 --- a/consensus/core/src/storage/rocksdb_store.rs +++ b/consensus/core/src/storage/rocksdb_store.rs @@ -2,7 +2,7 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use std::{collections::VecDeque, ops::Bound::Included, time::Duration}; +use std::{ops::Bound::Included, time::Duration}; use bytes::Bytes; use consensus_config::AuthorityIndex; @@ -16,7 +16,7 @@ use typed_store::{ use super::{CommitInfo, Store, WriteBatch}; use crate::{ - block::{BlockAPI as _, BlockDigest, BlockRef, Round, SignedBlock, Slot, VerifiedBlock}, + block::{BlockAPI as _, BlockDigest, BlockRef, Round, SignedBlock, VerifiedBlock}, commit::{CommitAPI as _, CommitDigest, CommitIndex, CommitRange, CommitRef, TrustedCommit}, error::{ConsensusError, ConsensusResult}, }; @@ -176,7 +176,7 @@ impl Store for RocksDBStore { Ok(exist) } - fn contains_block_at_slot(&self, slot: Slot) -> ConsensusResult { + fn contains_block_at_slot(&self, slot: crate::block::Slot) -> ConsensusResult { let found = self .digests_by_authorities .safe_range_iter(( @@ -222,7 +222,7 @@ impl Store for RocksDBStore { before_round: Option, ) -> ConsensusResult> { let before_round = before_round.unwrap_or(Round::MAX); - let mut refs = VecDeque::new(); + let mut refs = std::collections::VecDeque::new(); for kv in self .digests_by_authorities .safe_range_iter(( diff --git a/consensus/core/src/synchronizer.rs b/consensus/core/src/synchronizer.rs index e928dd246c7..de1c0568960 100644 --- a/consensus/core/src/synchronizer.rs +++ b/consensus/core/src/synchronizer.rs @@ -975,21 +975,16 @@ impl Synchronizer>(); - #[allow(unused_mut)] + #[cfg_attr(test, expect(unused_mut))] let mut peers = context .committee .authorities() .filter_map(|(peer_index, _)| (peer_index != context.own_index).then_some(peer_index)) .collect::>(); - // TODO: probably inject the RNG to allow unit testing - this is a work around - // for now. - cfg_if::cfg_if! { - if #[cfg(not(test))] { - // Shuffle the peers - peers.shuffle(&mut ThreadRng::default()); - } - } + // In test, the order is not randomized + #[cfg(not(test))] + peers.shuffle(&mut ThreadRng::default()); let mut peers = peers.into_iter(); let mut request_futures = FuturesUnordered::new(); diff --git a/consensus/core/src/test_dag_builder.rs b/consensus/core/src/test_dag_builder.rs index 20e4ebe8d79..607c5d65dc8 100644 --- a/consensus/core/src/test_dag_builder.rs +++ b/consensus/core/src/test_dag_builder.rs @@ -76,7 +76,6 @@ use crate::{ /// dag_builder.layer(1).build(); /// dag_builder.print(); // pretty print the entire DAG /// ``` -#[allow(unused)] pub(crate) struct DagBuilder { pub(crate) context: Arc, pub(crate) leader_schedule: LeaderSchedule, @@ -93,7 +92,6 @@ pub(crate) struct DagBuilder { pipeline: bool, } -#[allow(unused)] impl DagBuilder { pub(crate) fn new(context: Arc) -> Self { let leader_schedule = LeaderSchedule::new(context.clone(), LeaderSwapTable::default()); @@ -206,25 +204,26 @@ impl DagBuilder { !self.blocks.is_empty(), "No blocks have been created, please make sure that you have called build method" ); - self.blocks - .iter() - .find(|(block_ref, block)| { - block_ref.round == round - && block_ref.author == self.leader_schedule.elect_leader(round, 0) - }) - .map(|(_block_ref, block)| block.clone()) + self.blocks.iter().find_map(|(block_ref, block)| { + (block_ref.round == round + && block_ref.author == self.leader_schedule.elect_leader(round, 0)) + .then_some(block.clone()) + }) } + #[expect(unused)] pub(crate) fn with_wave_length(mut self, wave_length: Round) -> Self { self.wave_length = wave_length; self } + #[expect(unused)] pub(crate) fn with_number_of_leaders(mut self, number_of_leaders: u32) -> Self { self.number_of_leaders = number_of_leaders; self } + #[expect(unused)] pub(crate) fn with_pipeline(mut self, pipeline: bool) -> Self { self.pipeline = pipeline; self @@ -290,7 +289,7 @@ impl DagBuilder { /// Gets all uncommitted blocks in a slot. pub(crate) fn get_uncommitted_blocks_at_slot(&self, slot: Slot) -> Vec { let mut blocks = vec![]; - for (block_ref, block) in self.blocks.range(( + for (_block_ref, block) in self.blocks.range(( Included(BlockRef::new(slot.round, slot.authority, BlockDigest::MIN)), Included(BlockRef::new(slot.round, slot.authority, BlockDigest::MAX)), )) { @@ -366,7 +365,7 @@ pub struct LayerBuilder<'a> { blocks: Vec, } -#[allow(unused)] +#[expect(unused)] impl<'a> LayerBuilder<'a> { fn new(dag_builder: &'a mut DagBuilder, start_round: Round) -> Self { assert!(start_round > 0, "genesis round is created by default"); diff --git a/consensus/core/src/transaction.rs b/consensus/core/src/transaction.rs index d2df8a87fe9..f22eeeba635 100644 --- a/consensus/core/src/transaction.rs +++ b/consensus/core/src/transaction.rs @@ -240,9 +240,10 @@ pub enum ValidationError { } /// `NoopTransactionVerifier` accepts all transactions. -#[allow(unused)] +#[cfg(test)] pub(crate) struct NoopTransactionVerifier; +#[cfg(test)] impl TransactionVerifier for NoopTransactionVerifier { fn verify_batch(&self, _batch: &[&[u8]]) -> Result<(), ValidationError> { Ok(()) diff --git a/consensus/core/src/universal_committer.rs b/consensus/core/src/universal_committer.rs index bee37eef92e..970638e868d 100644 --- a/consensus/core/src/universal_committer.rs +++ b/consensus/core/src/universal_committer.rs @@ -182,7 +182,7 @@ pub(crate) mod universal_committer_builder { } } - #[allow(unused)] + #[expect(unused)] pub(crate) fn with_wave_length(mut self, wave_length: Round) -> Self { self.wave_length = wave_length; self diff --git a/crates/iota-analytics-indexer/src/analytics_processor.rs b/crates/iota-analytics-indexer/src/analytics_processor.rs index 7203f5dfe5c..036b25ad188 100644 --- a/crates/iota-analytics-indexer/src/analytics_processor.rs +++ b/crates/iota-analytics-indexer/src/analytics_processor.rs @@ -41,9 +41,9 @@ pub struct AnalyticsProcessor { metrics: AnalyticsMetrics, config: AnalyticsIndexerConfig, sender: mpsc::Sender, - #[allow(dead_code)] + #[expect(dead_code)] kill_sender: oneshot::Sender<()>, - #[allow(dead_code)] + #[expect(dead_code)] max_checkpoint_sender: oneshot::Sender<()>, } diff --git a/crates/iota-archival/src/lib.rs b/crates/iota-archival/src/lib.rs index e4a783b5b25..21938964cc6 100644 --- a/crates/iota-archival/src/lib.rs +++ b/crates/iota-archival/src/lib.rs @@ -52,7 +52,7 @@ use tracing::{error, info}; use crate::reader::{ArchiveReader, ArchiveReaderMetrics}; -#[allow(rustdoc::invalid_html_tags)] +#[expect(rustdoc::invalid_html_tags)] /// Checkpoints and summaries are persisted as blob files. Files are committed /// to local store by duration or file size. Committed files are synced with the /// remote store continuously. Files are optionally compressed with the zstd diff --git a/crates/iota-aws-orchestrator/src/benchmark.rs b/crates/iota-aws-orchestrator/src/benchmark.rs index d53d42e225d..733537adfe7 100644 --- a/crates/iota-aws-orchestrator/src/benchmark.rs +++ b/crates/iota-aws-orchestrator/src/benchmark.rs @@ -103,7 +103,6 @@ pub enum LoadType { /// Search for the breaking point of the L-graph. // TODO: Doesn't work very well, use tps regression as additional signal. - #[allow(dead_code)] Search { /// The initial load to test (and use a baseline). starting_load: usize, diff --git a/crates/iota-aws-orchestrator/src/monitor.rs b/crates/iota-aws-orchestrator/src/monitor.rs index 3a3da4f7a43..335960f8b96 100644 --- a/crates/iota-aws-orchestrator/src/monitor.rs +++ b/crates/iota-aws-orchestrator/src/monitor.rs @@ -220,7 +220,6 @@ impl Grafana { } } -#[allow(dead_code)] /// Bootstrap the grafana with datasource to connect to the given instances. /// NOTE: Only for macOS. Grafana must be installed through homebrew (and not /// from source). Deeper grafana configuration can be done through the @@ -228,7 +227,7 @@ impl Grafana { /// (~/Library/LaunchAgents/homebrew.mxcl.grafana.plist). pub struct LocalGrafana; -#[allow(dead_code)] +#[expect(dead_code)] impl LocalGrafana { /// The default grafana home directory (macOS, homebrew install). const DEFAULT_GRAFANA_HOME: &'static str = "/opt/homebrew/opt/grafana/share/grafana/"; diff --git a/crates/iota-benchmark/src/drivers/mod.rs b/crates/iota-benchmark/src/drivers/mod.rs index d242d6723a3..f442d30a3b8 100644 --- a/crates/iota-benchmark/src/drivers/mod.rs +++ b/crates/iota-benchmark/src/drivers/mod.rs @@ -55,7 +55,6 @@ impl std::fmt::Display for Interval { } // wrapper which implements serde -#[allow(dead_code)] #[derive(Debug)] pub struct HistogramWrapper { histogram: Histogram, diff --git a/crates/iota-benchmark/src/lib.rs b/crates/iota-benchmark/src/lib.rs index 2b807952799..f715a56f18f 100644 --- a/crates/iota-benchmark/src/lib.rs +++ b/crates/iota-benchmark/src/lib.rs @@ -72,7 +72,7 @@ use tracing::{error, info}; #[derive(Debug)] /// A wrapper on execution results to accommodate different types of /// responses from LocalValidatorAggregatorProxy and FullNodeProxy -#[allow(clippy::large_enum_variant)] +#[expect(clippy::large_enum_variant)] pub enum ExecutionEffects { CertifiedTransactionEffects(CertifiedTransactionEffects, TransactionEvents), IotaTransactionBlockEffects(IotaTransactionBlockEffects), diff --git a/crates/iota-bridge/src/action_executor.rs b/crates/iota-bridge/src/action_executor.rs index be81c44ed10..a1070ae3aab 100644 --- a/crates/iota-bridge/src/action_executor.rs +++ b/crates/iota-bridge/src/action_executor.rs @@ -695,9 +695,8 @@ mod tests { #[tokio::test] #[ignore = "https://github.com/iotaledger/iota/issues/3224"] async fn test_onchain_execution_loop() { - let ( + let SetupData { signing_tx, - _execution_tx, iota_client_mock, mut tx_subscription, store, @@ -707,12 +706,11 @@ mod tests { mock1, mock2, mock3, - _handles, gas_object_ref, iota_address, iota_token_type_tags, - _bridge_pause_tx, - ) = setup().await; + .. + } = setup().await; let (action_certificate, _, _) = get_bridge_authority_approved_action( vec![&mock0, &mock1, &mock2, &mock3], vec![&secrets[0], &secrets[1], &secrets[2], &secrets[3]], @@ -903,9 +901,8 @@ mod tests { #[tokio::test] #[ignore = "https://github.com/iotaledger/iota/issues/3224"] async fn test_signature_aggregation_loop() { - let ( + let SetupData { signing_tx, - _execution_tx, iota_client_mock, mut tx_subscription, store, @@ -915,12 +912,11 @@ mod tests { mock1, mock2, mock3, - _handles, gas_object_ref, iota_address, iota_token_type_tags, - _bridge_pause_tx, - ) = setup().await; + .. + } = setup().await; let id_token_map = (*iota_token_type_tags.load().clone()).clone(); let (action_certificate, iota_tx_digest, iota_tx_event_index) = get_bridge_authority_approved_action( @@ -1030,24 +1026,17 @@ mod tests { #[tokio::test] #[ignore = "https://github.com/iotaledger/iota/issues/3224"] async fn test_skip_request_signature_if_already_processed_on_chain() { - let ( + let SetupData { signing_tx, - _execution_tx, iota_client_mock, mut tx_subscription, store, - _secrets, - _dummy_iota_key, mock0, mock1, mock2, mock3, - _handles, - _gas_object_ref, - _iota_address, - _iota_token_type_tags, - _bridge_pause_tx, - ) = setup().await; + .. + } = setup().await; let iota_tx_digest = TransactionDigest::random(); let iota_tx_event_index = 0; @@ -1101,8 +1090,7 @@ mod tests { #[tokio::test] #[ignore = "https://github.com/iotaledger/iota/issues/3224"] async fn test_skip_tx_submission_if_already_processed_on_chain() { - let ( - _signing_tx, + let SetupData { execution_tx, iota_client_mock, mut tx_subscription, @@ -1113,12 +1101,11 @@ mod tests { mock1, mock2, mock3, - _handles, gas_object_ref, iota_address, iota_token_type_tags, - _bridge_pause_tx, - ) = setup().await; + .. + } = setup().await; let id_token_map = (*iota_token_type_tags.load().clone()).clone(); let (action_certificate, _, _) = get_bridge_authority_approved_action( vec![&mock0, &mock1, &mock2, &mock3], @@ -1188,8 +1175,7 @@ mod tests { #[tokio::test] #[ignore = "https://github.com/iotaledger/iota/issues/3224"] async fn test_skip_tx_submission_if_bridge_is_paused() { - let ( - _signing_tx, + let SetupData { execution_tx, iota_client_mock, mut tx_subscription, @@ -1200,12 +1186,12 @@ mod tests { mock1, mock2, mock3, - _handles, gas_object_ref, iota_address, iota_token_type_tags, bridge_pause_tx, - ) = setup().await; + .. + } = setup().await; let id_token_map: HashMap = (*iota_token_type_tags.load().clone()).clone(); let (action_certificate, _, _) = get_bridge_authority_approved_action( vec![&mock0, &mock1, &mock2, &mock3], @@ -1290,24 +1276,21 @@ mod tests { async fn test_action_executor_handle_new_token() { let new_token_id = 255u8; // token id that does not exist let new_type_tag = TypeTag::from_str("0xbeef::beef::BEEF").unwrap(); - let ( - _signing_tx, + let SetupData { execution_tx, iota_client_mock, mut tx_subscription, - _store, secrets, dummy_iota_key, mock0, mock1, mock2, mock3, - _handles, gas_object_ref, iota_address, iota_token_type_tags, - _bridge_pause_tx, - ) = setup().await; + .. + } = setup().await; let mut id_token_map: HashMap = (*iota_token_type_tags.load().clone()).clone(); let (action_certificate, _, _) = get_bridge_authority_approved_action( vec![&mock0, &mock1, &mock2, &mock3], @@ -1501,25 +1484,27 @@ mod tests { } } - #[allow(clippy::type_complexity)] - async fn setup() -> ( - iota_metrics::metered_channel::Sender, - iota_metrics::metered_channel::Sender, - IotaMockClient, - tokio::sync::broadcast::Receiver, - Arc, - Vec, - IotaKeyPair, - BridgeRequestMockHandler, - BridgeRequestMockHandler, - BridgeRequestMockHandler, - BridgeRequestMockHandler, - Vec>, - ObjectRef, - IotaAddress, - Arc>>, - tokio::sync::watch::Sender, - ) { + struct SetupData { + signing_tx: iota_metrics::metered_channel::Sender, + execution_tx: iota_metrics::metered_channel::Sender, + iota_client_mock: IotaMockClient, + tx_subscription: tokio::sync::broadcast::Receiver, + store: Arc, + secrets: Vec, + dummy_iota_key: IotaKeyPair, + mock0: BridgeRequestMockHandler, + mock1: BridgeRequestMockHandler, + mock2: BridgeRequestMockHandler, + mock3: BridgeRequestMockHandler, + #[expect(unused)] + handles: Vec>, + gas_object_ref: ObjectRef, + iota_address: IotaAddress, + iota_token_type_tags: Arc>>, + bridge_pause_tx: tokio::sync::watch::Sender, + } + + async fn setup() -> SetupData { telemetry_subscribers::init_for_testing(); let registry = Registry::new(); iota_metrics::init_metrics(®istry); @@ -1578,7 +1563,7 @@ mod tests { let (executor_handle, signing_tx, execution_tx) = executor.run_inner(); handles.extend(executor_handle); - ( + SetupData { signing_tx, execution_tx, iota_client_mock, @@ -1595,6 +1580,6 @@ mod tests { iota_address, iota_token_type_tags, bridge_pause_tx, - ) + } } } diff --git a/crates/iota-bridge/src/e2e_tests/test_utils.rs b/crates/iota-bridge/src/e2e_tests/test_utils.rs index 35195b89d22..a836ae9888f 100644 --- a/crates/iota-bridge/src/e2e_tests/test_utils.rs +++ b/crates/iota-bridge/src/e2e_tests/test_utils.rs @@ -434,7 +434,6 @@ pub async fn get_eth_signer_client_e2e_test_only( Ok((signer_0, private_key_0.to_string())) } -#[allow(dead_code)] #[derive(Debug, Clone)] pub struct DeployedSolContracts { pub iota_bridge: EthAddress, diff --git a/crates/iota-bridge/src/eth_syncer.rs b/crates/iota-bridge/src/eth_syncer.rs index cdbd7bf59a6..2fb109dd0da 100644 --- a/crates/iota-bridge/src/eth_syncer.rs +++ b/crates/iota-bridge/src/eth_syncer.rs @@ -36,7 +36,6 @@ pub struct EthSyncer

{ /// Map from contract address to their start block. pub type EthTargetAddresses = HashMap; -#[allow(clippy::new_without_default)] impl

EthSyncer

where P: ethers::providers::JsonRpcClient + 'static, diff --git a/crates/iota-bridge/src/iota_mock_client.rs b/crates/iota-bridge/src/iota_mock_client.rs index 178e631de03..acf4fa4fd27 100644 --- a/crates/iota-bridge/src/iota_mock_client.rs +++ b/crates/iota-bridge/src/iota_mock_client.rs @@ -30,7 +30,7 @@ use crate::{ }; /// Mock client used in test environments. -#[allow(clippy::type_complexity)] +#[expect(clippy::type_complexity)] #[derive(Clone, Debug)] pub struct IotaMockClient { // the top two fields do not change during tests so we don't need them to be Arc> diff --git a/crates/iota-bridge/src/monitor.rs b/crates/iota-bridge/src/monitor.rs index f2b0a551e51..3d483d216be 100644 --- a/crates/iota-bridge/src/monitor.rs +++ b/crates/iota-bridge/src/monitor.rs @@ -906,7 +906,7 @@ mod tests { .unwrap(); } - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] fn setup() -> ( iota_metrics::metered_channel::Sender, iota_metrics::metered_channel::Receiver, diff --git a/crates/iota-bridge/src/orchestrator.rs b/crates/iota-bridge/src/orchestrator.rs index e0193d15230..8604d0fe28d 100644 --- a/crates/iota-bridge/src/orchestrator.rs +++ b/crates/iota-bridge/src/orchestrator.rs @@ -485,7 +485,7 @@ mod tests { assert_eq!(digests.len(), 2); } - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] fn setup() -> ( iota_metrics::metered_channel::Sender<(Identifier, Vec)>, iota_metrics::metered_channel::Receiver<(Identifier, Vec)>, diff --git a/crates/iota-bridge/src/server/mock_handler.rs b/crates/iota-bridge/src/server/mock_handler.rs index c986cf4e143..39505eba88f 100644 --- a/crates/iota-bridge/src/server/mock_handler.rs +++ b/crates/iota-bridge/src/server/mock_handler.rs @@ -26,7 +26,7 @@ use crate::{ types::SignedBridgeAction, }; -#[allow(clippy::type_complexity)] +#[expect(clippy::type_complexity)] #[derive(Clone)] pub struct BridgeRequestMockHandler { signer: Arc>>, diff --git a/crates/iota-cluster-test/src/lib.rs b/crates/iota-cluster-test/src/lib.rs index b107bc08f3f..855ab846157 100644 --- a/crates/iota-cluster-test/src/lib.rs +++ b/crates/iota-cluster-test/src/lib.rs @@ -50,7 +50,6 @@ pub mod wallet_client; pub use iota_genesis_builder::SnapshotUrl as MigrationSnapshotUrl; -#[allow(unused)] pub struct TestContext { /// Cluster handle that allows access to various components in a cluster cluster: Box, diff --git a/crates/iota-common/src/sync/async_once_cell.rs b/crates/iota-common/src/sync/async_once_cell.rs index b2759e4ba62..68cf5583271 100644 --- a/crates/iota-common/src/sync/async_once_cell.rs +++ b/crates/iota-common/src/sync/async_once_cell.rs @@ -42,7 +42,7 @@ impl AsyncOnceCell { } /// Sets the value and notifies waiters. Return error if called twice - #[allow(clippy::result_unit_err)] + #[expect(clippy::result_unit_err)] pub fn set(&self, value: T) -> Result<(), ()> { let mut writer = self.writer.lock(); match writer.take() { diff --git a/crates/iota-common/src/sync/notify_once.rs b/crates/iota-common/src/sync/notify_once.rs index dfeb264ab4b..2c6b2b5eac8 100644 --- a/crates/iota-common/src/sync/notify_once.rs +++ b/crates/iota-common/src/sync/notify_once.rs @@ -35,7 +35,7 @@ impl NotifyOnce { /// After this method all pending and future calls to .wait() will return /// /// This method returns errors if called more then once - #[allow(clippy::result_unit_err)] + #[expect(clippy::result_unit_err)] pub fn notify(&self) -> Result<(), ()> { let Some(notify) = self.notify.lock().take() else { return Err(()); diff --git a/crates/iota-config/src/genesis.rs b/crates/iota-config/src/genesis.rs index 3cb724e34b6..d7c850ca148 100644 --- a/crates/iota-config/src/genesis.rs +++ b/crates/iota-config/src/genesis.rs @@ -586,7 +586,7 @@ pub struct TokenDistributionScheduleBuilder { } impl TokenDistributionScheduleBuilder { - #[allow(clippy::new_without_default)] + #[expect(clippy::new_without_default)] pub fn new() -> Self { Self { pre_minted_supply: 0, diff --git a/crates/iota-core/src/authority.rs b/crates/iota-core/src/authority.rs index bd968065e99..d85c217974f 100644 --- a/crates/iota-core/src/authority.rs +++ b/crates/iota-core/src/authority.rs @@ -784,7 +784,7 @@ pub struct AuthorityState { transaction_manager: Arc, /// Shuts down the execution task. Used only in testing. - #[allow(unused)] + #[cfg_attr(not(test), expect(unused))] tx_execution_shutdown: Mutex>>, pub metrics: Arc, @@ -1593,7 +1593,7 @@ impl AuthorityState { let transaction_data = &certificate.data().intent_message().value; let (kind, signer, gas) = transaction_data.execution_parts(); - #[allow(unused_mut)] + #[expect(unused_mut)] let (inner_temp_store, _, mut effects, execution_error_opt) = epoch_store.executor().execute_transaction_to_effects( self.get_backing_store().as_ref(), @@ -1860,7 +1860,6 @@ impl AuthorityState { } /// The object ID for gas can be any object ID, even for an uncreated object - #[allow(clippy::collapsible_else_if)] pub async fn dev_inspect_transaction_block( &self, sender: IotaAddress, @@ -2610,7 +2609,7 @@ impl AuthorityState { } } - #[allow(clippy::disallowed_methods)] // allow unbounded_channel() + #[expect(clippy::disallowed_methods)] // allow unbounded_channel() pub async fn new( name: AuthorityName, secret: StableSyncAuthoritySigner, diff --git a/crates/iota-core/src/authority/authority_per_epoch_store.rs b/crates/iota-core/src/authority/authority_per_epoch_store.rs index cc6340a840e..cf080a649d9 100644 --- a/crates/iota-core/src/authority/authority_per_epoch_store.rs +++ b/crates/iota-core/src/authority/authority_per_epoch_store.rs @@ -131,8 +131,8 @@ pub(crate) type EncG = bls12381::G2Element; // retain a distinction anyway. If we need to support distributed object // storage, having this distinction will be useful, as we will most likely have // to re-implement a retry / write-ahead-log at that point. -pub struct CertLockGuard(#[allow(unused)] MutexGuard); -pub struct CertTxGuard(#[allow(unused)] CertLockGuard); +pub struct CertLockGuard(#[expect(unused)] MutexGuard); +pub struct CertTxGuard(#[expect(unused)] CertLockGuard); impl CertTxGuard { pub fn release(self) {} @@ -2273,7 +2273,6 @@ impl AuthorityPerEpochStore { /// /// In addition to the early termination guarantee, this function also /// prevents epoch_terminated() if future is being executed. - #[allow(clippy::result_unit_err)] pub async fn within_alive_epoch(&self, f: F) -> Result { // This guard is kept in the future until it resolves, preventing // `epoch_terminated` to acquire a write lock @@ -2911,7 +2910,7 @@ impl AuthorityPerEpochStore { /// VerifiedCertificates for each executable certificate /// - Or update the state for checkpoint or epoch change protocol. #[instrument(level = "debug", skip_all)] - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] pub(crate) async fn process_consensus_transactions( &self, output: &mut ConsensusCommitOutput, @@ -4103,8 +4102,8 @@ impl LockDetailsWrapper { match self { Self::V1(v1) => v1, - // can remove #[allow] when there are multiple versions - #[allow(unreachable_patterns)] + // can remove #[expect] when there are multiple versions + #[expect(unreachable_patterns)] _ => panic!("lock details should have been migrated to latest version at read time"), } } @@ -4112,8 +4111,8 @@ impl LockDetailsWrapper { match self { Self::V1(v1) => v1, - // can remove #[allow] when there are multiple versions - #[allow(unreachable_patterns)] + // can remove #[expect] when there are multiple versions + #[expect(unreachable_patterns)] _ => panic!("lock details should have been migrated to latest version at read time"), } } diff --git a/crates/iota-core/src/authority/authority_store.rs b/crates/iota-core/src/authority/authority_store.rs index 98d68d84ae1..2ae0de3fb71 100644 --- a/crates/iota-core/src/authority/authority_store.rs +++ b/crates/iota-core/src/authority/authority_store.rs @@ -163,7 +163,7 @@ impl AuthorityStore { let epoch_start_configuration = if perpetual_tables.database_is_empty()? { info!("Creating new epoch start config from genesis"); - #[allow(unused_mut)] + #[expect(unused_mut)] let mut initial_epoch_flags = EpochFlag::default_flags_for_new_epoch(config); fail_point_arg!("initial_epoch_flags", |flags: Vec| { info!("Setting initial epoch flags to {:?}", flags); diff --git a/crates/iota-core/src/authority/authority_store_types.rs b/crates/iota-core/src/authority/authority_store_types.rs index b50904ea5c6..d46bd084eca 100644 --- a/crates/iota-core/src/authority/authority_store_types.rs +++ b/crates/iota-core/src/authority/authority_store_types.rs @@ -65,8 +65,8 @@ impl StoreObjectWrapper { match self { Self::V1(v1) => v1, - // can remove #[allow] when there are multiple versions - #[allow(unreachable_patterns)] + // can remove #[expect] when there are multiple versions + #[expect(unreachable_patterns)] _ => panic!("object should have been migrated to latest version at read time"), } } @@ -74,8 +74,8 @@ impl StoreObjectWrapper { match self { Self::V1(v1) => v1, - // can remove #[allow] when there are multiple versions - #[allow(unreachable_patterns)] + // can remove #[expect] when there are multiple versions + #[expect(unreachable_patterns)] _ => panic!("object should have been migrated to latest version at read time"), } } @@ -145,8 +145,8 @@ impl StoreMoveObjectWrapper { match self { Self::V1(v1) => v1, - // can remove #[allow] when there are multiple versions - #[allow(unreachable_patterns)] + // can remove #[expect] when there are multiple versions + #[expect(unreachable_patterns)] _ => panic!("object should have been migrated to latest version at read time"), } } @@ -154,8 +154,8 @@ impl StoreMoveObjectWrapper { match self { Self::V1(v1) => v1, - // can remove #[allow] when there are multiple versions - #[allow(unreachable_patterns)] + // can remove #[expect] when there are multiple versions + #[expect(unreachable_patterns)] _ => panic!("object should have been migrated to latest version at read time"), } } diff --git a/crates/iota-core/src/authority/epoch_start_configuration.rs b/crates/iota-core/src/authority/epoch_start_configuration.rs index 7ae6446577a..26df7d243ae 100644 --- a/crates/iota-core/src/authority/epoch_start_configuration.rs +++ b/crates/iota-core/src/authority/epoch_start_configuration.rs @@ -127,7 +127,7 @@ impl EpochStartConfiguration { })) } - #[allow(unreachable_patterns)] + #[expect(unreachable_patterns)] pub fn new_at_next_epoch_for_testing(&self) -> Self { // We only need to implement this function for the latest version. // When a new version is introduced, this function should be updated. diff --git a/crates/iota-core/src/authority_aggregator.rs b/crates/iota-core/src/authority_aggregator.rs index d7a3f8b6251..f42945e4990 100644 --- a/crates/iota-core/src/authority_aggregator.rs +++ b/crates/iota-core/src/authority_aggregator.rs @@ -287,7 +287,7 @@ pub enum AggregatorProcessCertificateError { /// Groups the errors by error type and stake. pub fn group_errors(errors: Vec<(IotaError, Vec, StakeUnit)>) -> GroupedErrors { - #[allow(clippy::mutable_key_type)] + #[expect(clippy::mutable_key_type)] let mut grouped_errors = HashMap::new(); for (error, names, stake) in errors { let entry = grouped_errors.entry(error).or_insert((0, vec![])); @@ -382,7 +382,7 @@ struct ProcessTransactionState { impl ProcessTransactionState { /// Returns the conflicting transaction digest and its validators with the /// most stake. - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] pub fn conflicting_tx_digest_with_most_stake( &self, ) -> Option<( diff --git a/crates/iota-core/src/checkpoints/checkpoint_executor/mod.rs b/crates/iota-core/src/checkpoints/checkpoint_executor/mod.rs index bac30e2396c..d1266c66400 100644 --- a/crates/iota-core/src/checkpoints/checkpoint_executor/mod.rs +++ b/crates/iota-core/src/checkpoints/checkpoint_executor/mod.rs @@ -1002,7 +1002,7 @@ fn extract_end_of_epoch_tx( // Given a checkpoint, filter out any already executed transactions, then return // the remaining execution digests, transaction digests, transactions to be // executed, and randomness rounds (if any) included in the checkpoint. -#[allow(clippy::type_complexity)] +#[expect(clippy::type_complexity)] fn get_unexecuted_transactions( checkpoint: VerifiedCheckpoint, cache_reader: &dyn TransactionCacheRead, diff --git a/crates/iota-core/src/checkpoints/mod.rs b/crates/iota-core/src/checkpoints/mod.rs index 3c819e3c8c6..9ab63227779 100644 --- a/crates/iota-core/src/checkpoints/mod.rs +++ b/crates/iota-core/src/checkpoints/mod.rs @@ -1238,7 +1238,7 @@ impl CheckpointBuilder { Ok(()) } - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] fn split_checkpoint_chunks( &self, effects_and_transaction_sizes: Vec<(TransactionEffects, usize)>, @@ -1924,7 +1924,7 @@ impl CheckpointAggregator { } impl CheckpointSignatureAggregator { - #[allow(clippy::result_unit_err)] + #[expect(clippy::result_unit_err)] pub fn try_aggregate( &mut self, data: CheckpointSignatureMessage, diff --git a/crates/iota-core/src/connection_monitor.rs b/crates/iota-core/src/connection_monitor.rs index a15afd715c4..33224315332 100644 --- a/crates/iota-core/src/connection_monitor.rs +++ b/crates/iota-core/src/connection_monitor.rs @@ -109,9 +109,7 @@ impl ConnectionMonitor { rx.receiver.recv().await } else { // If no shutdown receiver is provided, wait forever. - let future = future::pending(); - #[allow(clippy::let_unit_value)] - let () = future.await; + future::pending::<()>().await; Ok(()) } } diff --git a/crates/iota-core/src/consensus_adapter.rs b/crates/iota-core/src/consensus_adapter.rs index 46e8e9b6875..eb25d7b5137 100644 --- a/crates/iota-core/src/consensus_adapter.rs +++ b/crates/iota-core/src/consensus_adapter.rs @@ -280,7 +280,7 @@ impl ConsensusAdapter { // be a big deal but can be optimized let mut recovered = epoch_store.get_all_pending_consensus_transactions(); - #[allow(clippy::collapsible_if)] // This if can be collapsed but it will be ugly + #[expect(clippy::collapsible_if)] // This if can be collapsed but it will be ugly if epoch_store .get_reconfig_state_read_lock_guard() .is_reject_user_certs() @@ -592,7 +592,6 @@ impl ConsensusAdapter { // care about it } - #[allow(clippy::option_map_unit_fn)] async fn submit_and_wait_inner( self: Arc, transactions: Vec, diff --git a/crates/iota-core/src/epoch/randomness.rs b/crates/iota-core/src/epoch/randomness.rs index e63f4f2a4e8..be323fa4747 100644 --- a/crates/iota-core/src/epoch/randomness.rs +++ b/crates/iota-core/src/epoch/randomness.rs @@ -57,7 +57,6 @@ pub const SINGLETON_KEY: u64 = 0; // Wrappers for DKG messages (to simplify upgrades). #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[allow(clippy::large_enum_variant)] pub enum VersionedProcessedMessage { V1(dkg_v1::ProcessedMessage), } @@ -427,7 +426,7 @@ impl RandomnessManager { info!("random beacon: created {msg:?} with dkg version {dkg_version}"); let transaction = ConsensusTransaction::new_randomness_dkg_message(epoch_store.name, &msg); - #[allow(unused_mut)] + #[expect(unused_mut)] let mut fail_point_skip_sending = false; fail_point_if!("rb-dkg", || { // maybe skip sending in simtests @@ -499,7 +498,7 @@ impl RandomnessManager { &conf, ); - #[allow(unused_mut)] + #[expect(unused_mut)] let mut fail_point_skip_sending = false; fail_point_if!("rb-dkg", || { // maybe skip sending in simtests diff --git a/crates/iota-core/src/overload_monitor.rs b/crates/iota-core/src/overload_monitor.rs index 3f155117282..c4e921d15cf 100644 --- a/crates/iota-core/src/overload_monitor.rs +++ b/crates/iota-core/src/overload_monitor.rs @@ -271,7 +271,7 @@ pub fn overload_monitor_accept_tx( } #[cfg(test)] -#[allow(clippy::disallowed_methods)] // allow unbounded_channel() since tests are simulating txn manager execution +#[expect(clippy::disallowed_methods)] // allow unbounded_channel() since tests are simulating txn manager execution // driver interaction. mod tests { use std::sync::Arc; diff --git a/crates/iota-core/src/stake_aggregator.rs b/crates/iota-core/src/stake_aggregator.rs index b8d8907fca0..3269ba384ac 100644 --- a/crates/iota-core/src/stake_aggregator.rs +++ b/crates/iota-core/src/stake_aggregator.rs @@ -301,7 +301,7 @@ impl MultiStakeAggregator where K: Hash + Eq, { - #[allow(dead_code)] + #[expect(dead_code)] pub fn authorities_for_key(&self, k: &K) -> Option> { self.stake_maps.get(k).map(|(_, agg)| agg.keys()) } diff --git a/crates/iota-core/src/test_utils.rs b/crates/iota-core/src/test_utils.rs index 809ca04d8c5..4a215adf02a 100644 --- a/crates/iota-core/src/test_utils.rs +++ b/crates/iota-core/src/test_utils.rs @@ -11,7 +11,6 @@ use iota_framework::BuiltInFramework; use iota_genesis_builder::{ genesis_build_effects::GenesisBuildEffects, validator_info::ValidatorInfo, }; -use iota_macros::nondeterministic; use iota_move_build::{BuildConfig, CompiledPackage, IotaPackageHooks}; use iota_protocol_config::ProtocolConfig; use iota_types::{ @@ -94,14 +93,12 @@ pub async fn send_and_confirm_transaction( Ok((certificate.into_inner(), result.into_inner())) } -// note: clippy is confused about this being dead - it appears to only be used -// in cfg(test), but adding #[cfg(test)] causes other targets to fail -#[allow(dead_code)] +#[cfg(test)] pub(crate) fn init_state_parameters_from_rng(rng: &mut R) -> (Genesis, AuthorityKeyPair) where R: rand::CryptoRng + rand::RngCore, { - let dir = nondeterministic!(tempfile::TempDir::new().unwrap()); + let dir = iota_macros::nondeterministic!(tempfile::TempDir::new().unwrap()); let network_config = iota_swarm_config::network_config_builder::ConfigBuilder::new(&dir) .rng(rng) .build(); diff --git a/crates/iota-core/src/transaction_manager.rs b/crates/iota-core/src/transaction_manager.rs index 527897c08e1..0192e28bc37 100644 --- a/crates/iota-core/src/transaction_manager.rs +++ b/crates/iota-core/src/transaction_manager.rs @@ -64,7 +64,7 @@ pub struct TransactionManager { #[derive(Clone, Debug)] pub struct PendingCertificateStats { // The time this certificate enters transaction manager. - #[allow(unused)] + #[cfg(test)] pub enqueue_time: Instant, // The time this certificate becomes ready for execution. pub ready_time: Option, @@ -556,6 +556,7 @@ impl TransactionManager { expected_effects_digest, waiting_input_objects: input_object_keys, stats: PendingCertificateStats { + #[cfg(test)] enqueue_time: pending_cert_enqueue_time, ready_time: None, }, diff --git a/crates/iota-core/src/transaction_orchestrator.rs b/crates/iota-core/src/transaction_orchestrator.rs index 5dc3ae32188..9aee380abea 100644 --- a/crates/iota-core/src/transaction_orchestrator.rs +++ b/crates/iota-core/src/transaction_orchestrator.rs @@ -347,7 +347,6 @@ where let digests = [tx_digest]; let effects_await = cache_reader.notify_read_executed_effects(&digests); // let-and-return necessary to satisfy borrow checker. - #[allow(clippy::let_and_return)] let res = match select(ticket, effects_await.boxed()).await { Either::Left((quorum_driver_response, _)) => Ok(quorum_driver_response), Either::Right((_, unfinished_quorum_driver_task)) => { @@ -360,6 +359,7 @@ where Ok(unfinished_quorum_driver_task.await) } }; + #[expect(clippy::let_and_return)] res }) } diff --git a/crates/iota-core/src/unit_tests/authority_aggregator_tests.rs b/crates/iota-core/src/unit_tests/authority_aggregator_tests.rs index bfb2e944747..f0ec7181006 100644 --- a/crates/iota-core/src/unit_tests/authority_aggregator_tests.rs +++ b/crates/iota-core/src/unit_tests/authority_aggregator_tests.rs @@ -661,7 +661,7 @@ async fn test_quorum_once_with_timeout() { ); } -#[allow(clippy::type_complexity)] +#[expect(clippy::type_complexity)] fn get_authorities( count: Arc>, committee_size: u64, @@ -2243,7 +2243,7 @@ async fn test_process_transaction_again() { } } -#[allow(clippy::type_complexity)] +#[expect(clippy::type_complexity)] fn make_fake_authorities() -> ( BTreeMap, BTreeMap, diff --git a/crates/iota-core/src/unit_tests/execution_driver_tests.rs b/crates/iota-core/src/unit_tests/execution_driver_tests.rs index a2a51628601..50363e411c1 100644 --- a/crates/iota-core/src/unit_tests/execution_driver_tests.rs +++ b/crates/iota-core/src/unit_tests/execution_driver_tests.rs @@ -51,7 +51,7 @@ use crate::{ }, }; -#[allow(dead_code)] +#[expect(dead_code)] async fn wait_for_certs( stream: &mut UnboundedReceiver, certs: &[VerifiedCertificate], diff --git a/crates/iota-core/src/unit_tests/transaction_manager_tests.rs b/crates/iota-core/src/unit_tests/transaction_manager_tests.rs index 7868b8d4335..2f6abcaac31 100644 --- a/crates/iota-core/src/unit_tests/transaction_manager_tests.rs +++ b/crates/iota-core/src/unit_tests/transaction_manager_tests.rs @@ -24,7 +24,7 @@ use crate::{ transaction_manager::{PendingCertificate, TransactionManager}, }; -#[allow(clippy::disallowed_methods)] // allow unbounded_channel() +#[expect(clippy::disallowed_methods)] // allow unbounded_channel() fn make_transaction_manager( state: &AuthorityState, ) -> (TransactionManager, UnboundedReceiver) { diff --git a/crates/iota-core/src/unit_tests/transfer_to_object_tests.rs b/crates/iota-core/src/unit_tests/transfer_to_object_tests.rs index 9fab1b9a0ee..61795f7bbf5 100644 --- a/crates/iota-core/src/unit_tests/transfer_to_object_tests.rs +++ b/crates/iota-core/src/unit_tests/transfer_to_object_tests.rs @@ -425,7 +425,7 @@ async fn test_tto_invalid_receiving_arguments() { .find(|(_, owner)| matches!(owner, Owner::ObjectOwner(_))) .unwrap(); - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] let mutations: Vec<( Box ObjectRef>, Box bool>, diff --git a/crates/iota-e2e-tests/tests/dynamic_committee_tests.rs b/crates/iota-e2e-tests/tests/dynamic_committee_tests.rs index 0558a0e0e7e..c76e4922dbe 100644 --- a/crates/iota-e2e-tests/tests/dynamic_committee_tests.rs +++ b/crates/iota-e2e-tests/tests/dynamic_committee_tests.rs @@ -59,7 +59,7 @@ trait StatePredicate { runner: &StressTestRunner, effects: &TransactionEffects, ); - #[allow(unused)] + #[expect(unused)] async fn post_epoch_post_condition( &mut self, runner: &StressTestRunner, @@ -67,7 +67,7 @@ trait StatePredicate { ); } -#[allow(dead_code)] +#[expect(dead_code)] struct StressTestRunner { pub post_epoch_predicates: Vec>, pub test_cluster: TestCluster, @@ -234,7 +234,7 @@ impl StressTestRunner { self.get_from_effects(&effects.created(), name).await } - #[allow(dead_code)] + #[expect(dead_code)] pub async fn get_mutated_object_of_type_name( &self, effects: &TransactionEffects, diff --git a/crates/iota-e2e-tests/tests/shared_objects_tests.rs b/crates/iota-e2e-tests/tests/shared_objects_tests.rs index 8525b378580..cbabd65cf64 100644 --- a/crates/iota-e2e-tests/tests/shared_objects_tests.rs +++ b/crates/iota-e2e-tests/tests/shared_objects_tests.rs @@ -512,7 +512,6 @@ async fn access_clock_object_test() { assert!(event.timestamp_ms <= finish.as_millis() as u64); let mut attempt = 0; - #[allow(clippy::never_loop)] // seem to be a bug in clippy with let else statement loop { let checkpoint = test_cluster .fullnode_handle diff --git a/crates/iota-faucet/src/faucet/simple_faucet.rs b/crates/iota-faucet/src/faucet/simple_faucet.rs index eafb50d4a4a..b130b529e9d 100644 --- a/crates/iota-faucet/src/faucet/simple_faucet.rs +++ b/crates/iota-faucet/src/faucet/simple_faucet.rs @@ -65,7 +65,7 @@ pub struct SimpleFaucet { ttl_expiration: u64, coin_amount: u64, /// Shuts down the batch transfer task. Used only in testing. - #[allow(unused)] + #[cfg_attr(not(test), expect(unused))] batch_transfer_shutdown: parking_lot::Mutex>>, } diff --git a/crates/iota-genesis-builder/src/lib.rs b/crates/iota-genesis-builder/src/lib.rs index b3725eded9b..ac464c309ce 100644 --- a/crates/iota-genesis-builder/src/lib.rs +++ b/crates/iota-genesis-builder/src/lib.rs @@ -470,7 +470,7 @@ impl Builder { } = self.parameters.to_genesis_chain_parameters(); // In non-testing code, genesis type must always be V1. - #[allow(clippy::infallible_destructuring_match)] + #[expect(clippy::infallible_destructuring_match)] let system_state = match unsigned_genesis.iota_system_object() { IotaSystemState::V1(inner) => inner, #[cfg(msim)] diff --git a/crates/iota-genesis-builder/src/stardust/migration/mod.rs b/crates/iota-genesis-builder/src/stardust/migration/mod.rs index d9a04628723..198da0e1561 100644 --- a/crates/iota-genesis-builder/src/stardust/migration/mod.rs +++ b/crates/iota-genesis-builder/src/stardust/migration/mod.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 mod executor; -#[allow(clippy::module_inception)] +#[expect(clippy::module_inception)] mod migration; mod migration_target_network; #[cfg(test)] diff --git a/crates/iota-graphql-config/src/lib.rs b/crates/iota-graphql-config/src/lib.rs index dac6e6ac1b2..236ef925b8f 100644 --- a/crates/iota-graphql-config/src/lib.rs +++ b/crates/iota-graphql-config/src/lib.rs @@ -17,7 +17,7 @@ use syn::{ /// field that ensures that if the field is not present during deserialization, /// it is replaced with its default value, from the `Default` implementation for /// the config struct. -#[allow(non_snake_case)] +#[expect(non_snake_case)] #[proc_macro_attribute] pub fn GraphQLConfig(_attr: TokenStream, input: TokenStream) -> TokenStream { let DeriveInput { diff --git a/crates/iota-graphql-rpc-client/src/response.rs b/crates/iota-graphql-rpc-client/src/response.rs index 40c24e93cf8..d26cab75d80 100644 --- a/crates/iota-graphql-rpc-client/src/response.rs +++ b/crates/iota-graphql-rpc-client/src/response.rs @@ -40,7 +40,7 @@ impl GraphqlResponse { }) } - #[allow(clippy::result_large_err)] + #[expect(clippy::result_large_err)] pub fn graphql_version(&self) -> Result { Ok(self .headers @@ -91,7 +91,7 @@ impl GraphqlResponse { self.full_response.errors.clone() } - #[allow(clippy::result_large_err)] + #[expect(clippy::result_large_err)] pub fn usage(&self) -> Result>, ClientError> { Ok(match self.full_response.extensions.get("usage").cloned() { Some(Value::Object(obj)) => Some( diff --git a/crates/iota-graphql-rpc-client/src/simple_client.rs b/crates/iota-graphql-rpc-client/src/simple_client.rs index f78f8ca3753..2b5dfac4649 100644 --- a/crates/iota-graphql-rpc-client/src/simple_client.rs +++ b/crates/iota-graphql-rpc-client/src/simple_client.rs @@ -117,7 +117,7 @@ impl SimpleClient { } } -#[allow(clippy::type_complexity, clippy::result_large_err)] +#[expect(clippy::type_complexity, clippy::result_large_err)] pub fn resolve_variables( vars: &[GraphqlQueryVariable], ) -> Result<(BTreeMap, BTreeMap), ClientError> { diff --git a/crates/iota-graphql-rpc/src/raw_query.rs b/crates/iota-graphql-rpc/src/raw_query.rs index e6ed4a89b14..ce7bd23b2f6 100644 --- a/crates/iota-graphql-rpc/src/raw_query.rs +++ b/crates/iota-graphql-rpc/src/raw_query.rs @@ -66,7 +66,6 @@ impl RawQuery { /// Adds a `WHERE` condition to the query, combining it with existing /// conditions using `OR`. - #[allow(dead_code)] pub(crate) fn or_filter(mut self, condition: T) -> Self { self.where_ = match self.where_ { Some(where_) => Some(format!("({}) OR {}", where_, condition)), diff --git a/crates/iota-graphql-rpc/src/server/version.rs b/crates/iota-graphql-rpc/src/server/version.rs index ff65114fb7b..b1c58ddcb1d 100644 --- a/crates/iota-graphql-rpc/src/server/version.rs +++ b/crates/iota-graphql-rpc/src/server/version.rs @@ -17,7 +17,7 @@ use crate::{ pub(crate) static VERSION_HEADER: HeaderName = HeaderName::from_static("x-iota-rpc-version"); -#[allow(unused)] +#[expect(unused)] pub(crate) struct IotaRpcVersion(Vec, Vec>); const NAMED_VERSIONS: [&str; 3] = ["beta", "legacy", "stable"]; diff --git a/crates/iota-graphql-rpc/src/types/epoch.rs b/crates/iota-graphql-rpc/src/types/epoch.rs index 20a16d582c8..bbb9607c294 100644 --- a/crates/iota-graphql-rpc/src/types/epoch.rs +++ b/crates/iota-graphql-rpc/src/types/epoch.rs @@ -264,7 +264,6 @@ impl Epoch { ) -> Result> { let page = Page::from_params(ctx.data_unchecked(), first, after, last, before)?; - #[allow(clippy::unnecessary_lazy_evaluations)] // rust-lang/rust-clippy#9422 let Some(filter) = filter .unwrap_or_default() .intersect(TransactionBlockFilter { diff --git a/crates/iota-graphql-rpc/src/types/move_object.rs b/crates/iota-graphql-rpc/src/types/move_object.rs index 8f74494b841..405d9804be7 100644 --- a/crates/iota-graphql-rpc/src/types/move_object.rs +++ b/crates/iota-graphql-rpc/src/types/move_object.rs @@ -52,7 +52,7 @@ pub(crate) enum MoveObjectDowncastError { /// This interface is implemented by types that represent a Move object on-chain /// (A Move value whose type has `key`). -#[allow(clippy::duplicated_attributes)] +#[expect(clippy::duplicated_attributes)] #[derive(Interface)] #[graphql( name = "IMoveObject", diff --git a/crates/iota-graphql-rpc/src/types/object.rs b/crates/iota-graphql-rpc/src/types/object.rs index 4a57b49c764..ae2d53767f3 100644 --- a/crates/iota-graphql-rpc/src/types/object.rs +++ b/crates/iota-graphql-rpc/src/types/object.rs @@ -88,7 +88,7 @@ pub(crate) struct Object { pub(crate) struct ObjectImpl<'o>(pub &'o Object); #[derive(Clone, Debug)] -#[allow(clippy::large_enum_variant)] +#[expect(clippy::large_enum_variant)] pub(crate) enum ObjectKind { /// An object loaded from serialized data, such as the contents of a /// transaction that hasn't been indexed yet. @@ -243,7 +243,7 @@ pub(crate) struct HistoricalObjectCursor { /// Interface implemented by on-chain values that are addressable by an ID (also /// referred to as its address). This includes Move objects and packages. -#[allow(clippy::duplicated_attributes)] +#[expect(clippy::duplicated_attributes)] #[derive(Interface)] #[graphql( name = "IObject", diff --git a/crates/iota-graphql-rpc/src/types/owner.rs b/crates/iota-graphql-rpc/src/types/owner.rs index 8f06599e691..d40b51e39bc 100644 --- a/crates/iota-graphql-rpc/src/types/owner.rs +++ b/crates/iota-graphql-rpc/src/types/owner.rs @@ -56,7 +56,7 @@ pub(crate) struct OwnerImpl { /// either the public key of an account or another object. The same address can /// only refer to an account or an object, never both, but it is not possible to /// know which up-front. -#[allow(clippy::duplicated_attributes)] +#[expect(clippy::duplicated_attributes)] #[derive(Interface)] #[graphql( name = "IOwner", diff --git a/crates/iota-indexer/src/apis/transaction_builder_api.rs b/crates/iota-indexer/src/apis/transaction_builder_api.rs index 274a57a64dc..c72ce245d12 100644 --- a/crates/iota-indexer/src/apis/transaction_builder_api.rs +++ b/crates/iota-indexer/src/apis/transaction_builder_api.rs @@ -21,7 +21,7 @@ pub(crate) struct TransactionBuilderApi { } impl TransactionBuilderApi { - #[allow(clippy::new_ret_no_self)] + #[expect(clippy::new_ret_no_self)] pub fn new(inner: IndexerReader) -> IotaTransactionBuilderApi { IotaTransactionBuilderApi::new_with_data_reader(std::sync::Arc::new(Self { inner })) } diff --git a/crates/iota-indexer/src/models/tx_indices.rs b/crates/iota-indexer/src/models/tx_indices.rs index 7ca593b6218..3bc562d01f8 100644 --- a/crates/iota-indexer/src/models/tx_indices.rs +++ b/crates/iota-indexer/src/models/tx_indices.rs @@ -96,7 +96,7 @@ pub struct StoredTxKind { pub tx_sequence_number: i64, } -#[allow(clippy::type_complexity)] +#[expect(clippy::type_complexity)] impl TxIndex { pub fn split( self: TxIndex, diff --git a/crates/iota-indexer/src/store/indexer_store.rs b/crates/iota-indexer/src/store/indexer_store.rs index 00281bc11cf..b41b250f28e 100644 --- a/crates/iota-indexer/src/store/indexer_store.rs +++ b/crates/iota-indexer/src/store/indexer_store.rs @@ -18,7 +18,7 @@ use crate::{ }, }; -#[allow(clippy::large_enum_variant)] +#[expect(clippy::large_enum_variant)] pub enum ObjectChangeToCommit { MutatedObject(StoredObject), DeletedObject(StoredDeletedObject), diff --git a/crates/iota-indexer/src/store/pg_indexer_store.rs b/crates/iota-indexer/src/store/pg_indexer_store.rs index d721a5e95e4..007fa538120 100644 --- a/crates/iota-indexer/src/store/pg_indexer_store.rs +++ b/crates/iota-indexer/src/store/pg_indexer_store.rs @@ -135,7 +135,7 @@ SET object_version = EXCLUDED.object_version, pub struct PgIndexerStoreConfig { pub parallel_chunk_size: usize, pub parallel_objects_chunk_size: usize, - #[allow(unused)] + #[expect(unused)] pub epochs_to_keep: Option, } diff --git a/crates/iota-indexer/tests/ingestion_tests.rs b/crates/iota-indexer/tests/ingestion_tests.rs index 4ed48a2c0f2..9082703db4c 100644 --- a/crates/iota-indexer/tests/ingestion_tests.rs +++ b/crates/iota-indexer/tests/ingestion_tests.rs @@ -2,7 +2,7 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -#[allow(dead_code)] +#[expect(dead_code)] #[cfg(feature = "pg_integration")] mod common; #[cfg(feature = "pg_integration")] diff --git a/crates/iota-indexer/tests/rpc-tests/main.rs b/crates/iota-indexer/tests/rpc-tests/main.rs index 0479b12703e..2b6e61a280d 100644 --- a/crates/iota-indexer/tests/rpc-tests/main.rs +++ b/crates/iota-indexer/tests/rpc-tests/main.rs @@ -4,7 +4,7 @@ #[cfg(feature = "shared_test_runtime")] mod coin_api; -#[allow(dead_code)] +#[expect(dead_code)] #[path = "../common/mod.rs"] mod common; #[cfg(feature = "shared_test_runtime")] diff --git a/crates/iota-json-rpc/src/authority_state.rs b/crates/iota-json-rpc/src/authority_state.rs index ef03f6576dd..e2b7df71d96 100644 --- a/crates/iota-json-rpc/src/authority_state.rs +++ b/crates/iota-json-rpc/src/authority_state.rs @@ -354,7 +354,6 @@ impl StateRead for AuthorityState { .await?) } - #[allow(clippy::type_complexity)] async fn dry_exec_transaction( &self, transaction: TransactionData, diff --git a/crates/iota-json-rpc/src/axum_router.rs b/crates/iota-json-rpc/src/axum_router.rs index 5957efdcb0d..8037cda0c3f 100644 --- a/crates/iota-json-rpc/src/axum_router.rs +++ b/crates/iota-json-rpc/src/axum_router.rs @@ -446,7 +446,6 @@ pub mod ws { } async fn ws_json_rpc_handler(mut socket: WebSocket, service: JsonRpcService) { - #[allow(clippy::disallowed_methods)] let (tx, mut rx) = mpsc::channel::(MAX_WS_MESSAGE_BUFFER); let sink = MethodSink::new_with_limit(tx, MAX_RESPONSE_SIZE); let bounded_subscriptions = BoundedSubscriptions::new(100); diff --git a/crates/iota-json-rpc/src/transaction_execution_api.rs b/crates/iota-json-rpc/src/transaction_execution_api.rs index 0d128dd1914..32c865b5281 100644 --- a/crates/iota-json-rpc/src/transaction_execution_api.rs +++ b/crates/iota-json-rpc/src/transaction_execution_api.rs @@ -71,7 +71,7 @@ impl TransactionExecutionApi { Ok(data) } - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] fn prepare_execute_transaction_block( &self, tx_bytes: Base64, diff --git a/crates/iota-light-client/src/bin/light_client.rs b/crates/iota-light-client/src/bin/light_client.rs index 64f6f97df0b..1db8daab15f 100644 --- a/crates/iota-light-client/src/bin/light_client.rs +++ b/crates/iota-light-client/src/bin/light_client.rs @@ -142,7 +142,7 @@ mod tests { } // clippy ignore dead-code - #[allow(dead_code)] + #[expect(dead_code)] async fn write_full_checkpoint( checkpoint_path: &Path, checkpoint: &CheckpointData, diff --git a/crates/iota-macros/src/lib.rs b/crates/iota-macros/src/lib.rs index 672b381ceb0..366067ff0a4 100644 --- a/crates/iota-macros/src/lib.rs +++ b/crates/iota-macros/src/lib.rs @@ -413,7 +413,6 @@ mod test { #[test] #[should_panic] fn test_macro_overflow() { - #[allow(arithmetic_overflow)] fn f() { println!("{}", i32::MAX + 1); } @@ -603,7 +602,6 @@ mod test { #[test] #[should_panic] fn test_macro_overflow() { - #[allow(arithmetic_overflow)] fn f() { println!("{}", i32::MAX + 1); } diff --git a/crates/iota-metrics/src/metrics_network.rs b/crates/iota-metrics/src/metrics_network.rs index f5cb37402a4..e8131f2434e 100644 --- a/crates/iota-metrics/src/metrics_network.rs +++ b/crates/iota-metrics/src/metrics_network.rs @@ -364,7 +364,7 @@ impl MakeCallbackHandler for MetricsMakeCallbackHandler { pub struct MetricsResponseHandler { metrics: Arc, // The timer is held on to and "observed" once dropped - #[allow(unused)] + #[expect(unused)] timer: HistogramTimer, route: String, excessive_message_size: usize, diff --git a/crates/iota-metrics/src/monitored_mpsc.rs b/crates/iota-metrics/src/monitored_mpsc.rs index ce15ff7fed3..0806d06590b 100644 --- a/crates/iota-metrics/src/monitored_mpsc.rs +++ b/crates/iota-metrics/src/monitored_mpsc.rs @@ -563,7 +563,7 @@ impl Unpin for UnboundedReceiver {} /// and `UnboundedReceiver` pub fn unbounded_channel(name: &str) -> (UnboundedSender, UnboundedReceiver) { let metrics = get_metrics(); - #[allow(clippy::disallowed_methods)] + #[expect(clippy::disallowed_methods)] let (sender, receiver) = mpsc::unbounded_channel(); ( UnboundedSender { diff --git a/crates/iota-network/src/discovery/builder.rs b/crates/iota-network/src/discovery/builder.rs index 0c7a22ecf86..801d322e1fd 100644 --- a/crates/iota-network/src/discovery/builder.rs +++ b/crates/iota-network/src/discovery/builder.rs @@ -29,7 +29,6 @@ pub struct Builder { } impl Builder { - #[allow(clippy::new_without_default)] pub fn new(trusted_peer_change_rx: watch::Receiver) -> Self { Self { config: None, diff --git a/crates/iota-network/src/randomness/mod.rs b/crates/iota-network/src/randomness/mod.rs index 50ed7c09ee1..3bed5180149 100644 --- a/crates/iota-network/src/randomness/mod.rs +++ b/crates/iota-network/src/randomness/mod.rs @@ -920,7 +920,7 @@ impl RandomnessEventLoop { } } - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] fn remove_partial_sigs_in_range( &mut self, range: ( @@ -952,7 +952,7 @@ impl RandomnessEventLoop { full_sig: Arc>, ) { // For simtests, we may test not sending partial signatures. - #[allow(unused_mut)] + #[expect(unused_mut)] let mut fail_point_skip_sending = false; fail_point_if!("rb-send-partial-signatures", || { fail_point_skip_sending = true; diff --git a/crates/iota-network/src/state_sync/builder.rs b/crates/iota-network/src/state_sync/builder.rs index 6734aceae26..496e65e08e0 100644 --- a/crates/iota-network/src/state_sync/builder.rs +++ b/crates/iota-network/src/state_sync/builder.rs @@ -32,7 +32,7 @@ pub struct Builder { } impl Builder<()> { - #[allow(clippy::new_without_default)] + #[expect(clippy::new_without_default)] pub fn new() -> Self { Self { store: None, diff --git a/crates/iota-network/src/state_sync/server.rs b/crates/iota-network/src/state_sync/server.rs index 507b34310db..a213c44eec3 100644 --- a/crates/iota-network/src/state_sync/server.rs +++ b/crates/iota-network/src/state_sync/server.rs @@ -234,7 +234,7 @@ where } })?; - struct SemaphoreExtension(#[allow(unused)] OwnedSemaphorePermit); + struct SemaphoreExtension(#[expect(unused)] OwnedSemaphorePermit); inner.call(req).await.map(move |mut response| { // Insert permit as extension so it's not dropped until the response is sent. response diff --git a/crates/iota-node/src/lib.rs b/crates/iota-node/src/lib.rs index 1e2282ea92a..58443bb59e6 100644 --- a/crates/iota-node/src/lib.rs +++ b/crates/iota-node/src/lib.rs @@ -1896,7 +1896,7 @@ impl IotaNode { .store(new_value, Ordering::Relaxed); } - #[allow(unused_variables)] + #[expect(unused_variables)] async fn fetch_jwks( authority: AuthorityName, provider: &OIDCProvider, diff --git a/crates/iota-proc-macros/src/lib.rs b/crates/iota-proc-macros/src/lib.rs index 68e16646ae2..e6542663586 100644 --- a/crates/iota-proc-macros/src/lib.rs +++ b/crates/iota-proc-macros/src/lib.rs @@ -234,7 +234,7 @@ pub fn sim_test(args: TokenStream, item: TokenStream) -> TokenStream { let sig = &input.sig; let body = &input.block; quote! { - #[allow(clippy::needless_return)] + #[expect(clippy::needless_return)] #[tokio::test] #ignore #sig { diff --git a/crates/iota-protocol-config-macros/src/lib.rs b/crates/iota-protocol-config-macros/src/lib.rs index 9d2497e6710..a479c8df658 100644 --- a/crates/iota-protocol-config-macros/src/lib.rs +++ b/crates/iota-protocol-config-macros/src/lib.rs @@ -153,7 +153,7 @@ pub fn accessors_macro(input: TokenStream) -> TokenStream { _ => panic!("Only structs supported."), }; - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] let ((getters, (test_setters, value_setters)), (value_lookup, field_names_str)): ( (Vec<_>, (Vec<_>, Vec<_>)), (Vec<_>, Vec<_>), @@ -201,7 +201,7 @@ pub fn accessors_macro(input: TokenStream) -> TokenStream { } } - #[allow(non_camel_case_types)] + #[expect(non_camel_case_types)] #[derive(Clone, Serialize, Debug, PartialEq, Deserialize, schemars::JsonSchema)] pub enum ProtocolConfigValue { #(#inner_types(#inner_types),)* diff --git a/crates/iota-protocol-config/src/lib.rs b/crates/iota-protocol-config/src/lib.rs index a216a4efefb..77c62e282f3 100644 --- a/crates/iota-protocol-config/src/lib.rs +++ b/crates/iota-protocol-config/src/lib.rs @@ -1150,7 +1150,7 @@ impl ProtocolConfig { /// potentially returning a protocol config that is incorrect for some /// feature flags. Definitely safe for testing and for protocol version /// 11 and prior. - #[allow(non_snake_case)] + #[expect(non_snake_case)] pub fn get_for_max_version_UNSAFE() -> Self { if Self::load_poison_get_for_min_version() { panic!("get_for_max_version_UNSAFE called on validator"); diff --git a/crates/iota-replay/src/fuzz.rs b/crates/iota-replay/src/fuzz.rs index cc2d5a09c58..d041e740ce8 100644 --- a/crates/iota-replay/src/fuzz.rs +++ b/crates/iota-replay/src/fuzz.rs @@ -183,7 +183,7 @@ impl ReplayFuzzer { } } -#[allow(clippy::large_enum_variant)] +#[expect(clippy::large_enum_variant)] #[derive(Debug, Error, Clone)] pub enum ReplayFuzzError { #[error( diff --git a/crates/iota-replay/src/replay.rs b/crates/iota-replay/src/replay.rs index 0c40b5c52ff..b012b4c2cfc 100644 --- a/crates/iota-replay/src/replay.rs +++ b/crates/iota-replay/src/replay.rs @@ -512,7 +512,7 @@ impl LocalExec { } // TODO: remove this after `futures::executor::block_on` is removed. - #[allow(clippy::disallowed_methods)] + #[expect(clippy::disallowed_methods)] pub fn download_object( &self, object_id: &ObjectID, @@ -557,7 +557,7 @@ impl LocalExec { } // TODO: remove this after `futures::executor::block_on` is removed. - #[allow(clippy::disallowed_methods)] + #[expect(clippy::disallowed_methods)] pub fn download_latest_object( &self, object_id: &ObjectID, @@ -593,7 +593,7 @@ impl LocalExec { } } - #[allow(clippy::disallowed_methods)] + #[expect(clippy::disallowed_methods)] pub fn download_object_by_upper_bound( &self, object_id: &ObjectID, diff --git a/crates/iota-replay/src/types.rs b/crates/iota-replay/src/types.rs index 05c90fffe71..43efba9777d 100644 --- a/crates/iota-replay/src/types.rs +++ b/crates/iota-replay/src/types.rs @@ -75,7 +75,6 @@ fn unspecified_chain() -> Chain { Chain::Unknown } -#[allow(clippy::large_enum_variant)] #[derive(Debug, Error, Clone)] pub enum ReplayEngineError { #[error("IotaError: {:#?}", err)] diff --git a/crates/iota-rest-api/src/reader.rs b/crates/iota-rest-api/src/reader.rs index b387f30f832..0446a499a3f 100644 --- a/crates/iota-rest-api/src/reader.rs +++ b/crates/iota-rest-api/src/reader.rs @@ -265,7 +265,7 @@ impl Iterator for CheckpointTransactionsIter { pub struct CursorInfo { pub checkpoint: CheckpointSequenceNumber, pub timestamp_ms: u64, - #[allow(unused)] + #[expect(unused)] pub index: u64, // None if there are no more transactions in the store diff --git a/crates/iota-rosetta/src/errors.rs b/crates/iota-rosetta/src/errors.rs index 8cda43d91b5..854be4f1967 100644 --- a/crates/iota-rosetta/src/errors.rs +++ b/crates/iota-rosetta/src/errors.rs @@ -29,7 +29,6 @@ use crate::types::{BlockHash, IotaEnv, OperationType, PublicKey}; derive(Display, EnumIter), strum(serialize_all = "kebab-case") )] -#[allow(clippy::enum_variant_names)] pub enum Error { #[error("Unsupported blockchain: {0}")] UnsupportedBlockchain(String), diff --git a/crates/iota-rosetta/src/types.rs b/crates/iota-rosetta/src/types.rs index 8f84205fa94..eadf326efdd 100644 --- a/crates/iota-rosetta/src/types.rs +++ b/crates/iota-rosetta/src/types.rs @@ -753,7 +753,6 @@ pub struct BalanceExemption { #[derive(Serialize)] #[serde(rename_all = "snake_case")] -#[allow(dead_code)] pub enum ExemptionType { GreaterOrEqual, LessOrEqual, @@ -762,7 +761,6 @@ pub enum ExemptionType { #[derive(Serialize)] #[serde(rename_all = "snake_case")] -#[allow(clippy::enum_variant_names, dead_code)] pub enum Case { UpperCase, LowerCase, @@ -799,7 +797,6 @@ pub struct RelatedTransaction { #[derive(Serialize, Deserialize, Clone, Debug)] #[serde(rename_all = "lowercase")] -#[allow(dead_code)] pub enum Direction { Forward, Backward, diff --git a/crates/iota-rosetta/tests/gas_budget_tests.rs b/crates/iota-rosetta/tests/gas_budget_tests.rs index 2029cfaa9ef..6c4ee97465f 100644 --- a/crates/iota-rosetta/tests/gas_budget_tests.rs +++ b/crates/iota-rosetta/tests/gas_budget_tests.rs @@ -24,13 +24,13 @@ use test_cluster::TestClusterBuilder; use crate::rosetta_client::RosettaEndpoint; -#[allow(dead_code)] +#[expect(dead_code)] mod rosetta_client; #[derive(Deserialize, Debug)] #[serde(untagged)] enum TransactionIdentifierResponseResult { - #[allow(unused)] + #[expect(unused)] Success(TransactionIdentifierResponse), Error(RosettaSubmitGasError), } diff --git a/crates/iota-rpc-loadgen/src/payload/mod.rs b/crates/iota-rpc-loadgen/src/payload/mod.rs index 64dfa96d5df..57ec8890d06 100644 --- a/crates/iota-rpc-loadgen/src/payload/mod.rs +++ b/crates/iota-rpc-loadgen/src/payload/mod.rs @@ -173,7 +173,6 @@ impl Command { } #[derive(Clone)] -#[allow(dead_code)] pub enum CommandData { DryRun(DryRun), GetCheckpoints(GetCheckpoints), diff --git a/crates/iota-sdk/examples/utils.rs b/crates/iota-sdk/examples/utils.rs index 8c6b914143b..d9de6f91187 100644 --- a/crates/iota-sdk/examples/utils.rs +++ b/crates/iota-sdk/examples/utils.rs @@ -320,7 +320,7 @@ pub async fn sign_and_execute_transaction( // this function should not be used. It is only used to make clippy happy, // and to reduce the number of allow(dead_code) annotations to just this one -#[allow(dead_code)] +#[expect(dead_code)] async fn just_for_clippy() -> Result<(), anyhow::Error> { let (client, sender, _recipient) = setup_for_write().await?; let _digest = split_coin_digest(&client, &sender).await?; diff --git a/crates/iota-source-validation-service/tests/tests.rs b/crates/iota-source-validation-service/tests/tests.rs index 75c934b2e41..c0104ccaacc 100644 --- a/crates/iota-source-validation-service/tests/tests.rs +++ b/crates/iota-source-validation-service/tests/tests.rs @@ -38,7 +38,7 @@ use tokio::sync::oneshot; const LOCALNET_PORT: u16 = 9000; const TEST_FIXTURES_DIR: &str = "tests/fixture"; -#[allow(clippy::await_holding_lock)] +#[expect(clippy::await_holding_lock)] #[tokio::test] #[ignore] async fn test_end_to_end() -> anyhow::Result<()> { diff --git a/crates/iota-swarm/src/memory/swarm.rs b/crates/iota-swarm/src/memory/swarm.rs index 0824335e0e2..11d20ab51c2 100644 --- a/crates/iota-swarm/src/memory/swarm.rs +++ b/crates/iota-swarm/src/memory/swarm.rs @@ -69,7 +69,7 @@ pub struct SwarmBuilder { } impl SwarmBuilder { - #[allow(clippy::new_without_default)] + #[expect(clippy::new_without_default)] pub fn new() -> Self { Self { rng: OsRng, diff --git a/crates/iota-tool/src/commands.rs b/crates/iota-tool/src/commands.rs index 18416b2401f..f0c8625a389 100644 --- a/crates/iota-tool/src/commands.rs +++ b/crates/iota-tool/src/commands.rs @@ -488,7 +488,6 @@ async fn check_locked_object( } impl ToolCommand { - #[allow(clippy::format_in_format_args)] pub async fn execute(self, tracing_handle: TracingHandle) -> Result<(), anyhow::Error> { match self { ToolCommand::LockedObject { diff --git a/crates/iota-tool/src/lib.rs b/crates/iota-tool/src/lib.rs index 27fbe1d2839..da8e0de6d03 100644 --- a/crates/iota-tool/src/lib.rs +++ b/crates/iota-tool/src/lib.rs @@ -148,7 +148,7 @@ where } } -#[allow(clippy::type_complexity)] +#[expect(clippy::type_complexity)] pub struct GroupedObjectOutput { pub grouped_results: BTreeMap< Option<( @@ -221,7 +221,6 @@ impl GroupedObjectOutput { } } -#[allow(clippy::format_in_format_args)] impl std::fmt::Display for GroupedObjectOutput { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { writeln!(f, "available stake: {}", self.available_voting_power)?; diff --git a/crates/iota-transactional-test-runner/src/lib.rs b/crates/iota-transactional-test-runner/src/lib.rs index 7e0667e4889..b0527d3b9bf 100644 --- a/crates/iota-transactional-test-runner/src/lib.rs +++ b/crates/iota-transactional-test-runner/src/lib.rs @@ -56,7 +56,6 @@ pub struct ValidatorWithFullnode { pub kv_store: Arc, } -#[allow(unused_variables)] /// TODO: better name? #[async_trait::async_trait] pub trait TransactionalAdapter: Send + Sync + ReadStore { diff --git a/crates/iota-types/src/authenticator_state.rs b/crates/iota-types/src/authenticator_state.rs index c350b756723..054af6d6d9e 100644 --- a/crates/iota-types/src/authenticator_state.rs +++ b/crates/iota-types/src/authenticator_state.rs @@ -94,11 +94,10 @@ fn jwk_ord(a: &ActiveJwk, b: &ActiveJwk) -> std::cmp::Ordering { } } -#[allow(clippy::non_canonical_partial_ord_impl)] impl std::cmp::PartialOrd for ActiveJwk { // This must match the sort order defined by jwk_lt in authenticator_state.move fn partial_cmp(&self, other: &Self) -> Option { - Some(jwk_ord(self, other)) + Some(self.cmp(other)) } } diff --git a/crates/iota-types/src/crypto.rs b/crates/iota-types/src/crypto.rs index a78c50b3ca7..7ea6d2cdece 100644 --- a/crates/iota-types/src/crypto.rs +++ b/crates/iota-types/src/crypto.rs @@ -152,7 +152,7 @@ pub fn verify_proof_of_possession( /// * accounts to interact with Iota. /// * Currently we support eddsa and ecdsa on Iota. -#[allow(clippy::large_enum_variant)] +#[expect(clippy::large_enum_variant)] #[derive(Debug, From, PartialEq, Eq)] pub enum IotaKeyPair { Ed25519(Ed25519KeyPair), diff --git a/crates/iota-types/src/effects/effects_v1.rs b/crates/iota-types/src/effects/effects_v1.rs index 3f3458d42b0..5b7c5848c22 100644 --- a/crates/iota-types/src/effects/effects_v1.rs +++ b/crates/iota-types/src/effects/effects_v1.rs @@ -453,7 +453,6 @@ impl TransactionEffectsV1 { .unwrap() as u32 }); - #[allow(clippy::let_and_return)] let result = Self { status, executed_epoch, diff --git a/crates/iota-types/src/effects/mod.rs b/crates/iota-types/src/effects/mod.rs index 0843ffe0d55..2cab0289a9d 100644 --- a/crates/iota-types/src/effects/mod.rs +++ b/crates/iota-types/src/effects/mod.rs @@ -54,7 +54,6 @@ pub const APPROX_SIZE_OF_OWNER: usize = 48; /// The response from processing a transaction or a certified transaction #[enum_dispatch(TransactionEffectsAPI)] #[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize)] -#[allow(clippy::large_enum_variant)] pub enum TransactionEffects { V1(TransactionEffectsV1), } diff --git a/crates/iota-types/src/error.rs b/crates/iota-types/src/error.rs index bb89bc3444d..1b5eab9e489 100644 --- a/crates/iota-types/src/error.rs +++ b/crates/iota-types/src/error.rs @@ -675,7 +675,7 @@ pub enum IotaError { } #[repr(u64)] -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] /// Sub-status codes for the `UNKNOWN_VERIFICATION_ERROR` VM Status Code which /// provides more context TODO: add more Vm Status errors. We use @@ -686,7 +686,7 @@ pub enum VMMVerifierErrorSubStatusCode { } #[repr(u64)] -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] /// Sub-status codes for the `MEMORY_LIMIT_EXCEEDED` VM Status Code which /// provides more context diff --git a/crates/iota-types/src/gas.rs b/crates/iota-types/src/gas.rs index 5763c16de35..b8996eae528 100644 --- a/crates/iota-types/src/gas.rs +++ b/crates/iota-types/src/gas.rs @@ -201,7 +201,7 @@ pub mod checked { self.gas_used() as i64 - self.storage_rebate as i64 } - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] pub fn new_from_txn_effects<'a>( transactions: impl Iterator, ) -> GasCostSummary { diff --git a/crates/iota-types/src/gas_model/gas_v1.rs b/crates/iota-types/src/gas_model/gas_v1.rs index da872086f33..f173d7f7425 100644 --- a/crates/iota-types/src/gas_model/gas_v1.rs +++ b/crates/iota-types/src/gas_model/gas_v1.rs @@ -26,7 +26,7 @@ mod checked { /// After execution a call to `GasStatus::bucketize` will round the /// computation cost to `cost` for the bucket ([`min`, `max`]) the gas /// used falls into. - #[allow(dead_code)] + #[expect(dead_code)] pub(crate) struct ComputationBucket { min: u64, max: u64, @@ -165,7 +165,6 @@ mod checked { pub new_size: u64, } - #[allow(dead_code)] #[derive(Debug)] pub struct IotaGasStatus { // GasStatus as used by the VM, that is all the VM sees diff --git a/crates/iota-types/src/gas_model/tables.rs b/crates/iota-types/src/gas_model/tables.rs index 5959704e61b..77ad4819e9b 100644 --- a/crates/iota-types/src/gas_model/tables.rs +++ b/crates/iota-types/src/gas_model/tables.rs @@ -49,7 +49,6 @@ pub static INITIAL_COST_SCHEDULE: Lazy = Lazy::new(initial_cost_sched /// Provide all the proper guarantees about gas metering in the Move VM. /// /// Every client must use an instance of this type to interact with the Move VM. -#[allow(dead_code)] #[derive(Debug)] pub struct GasStatus { pub gas_model_version: u64, @@ -151,7 +150,7 @@ impl GasStatus { InternalGas::new(val * Self::INTERNAL_UNIT_MULTIPLIER) } - #[allow(dead_code)] + #[expect(dead_code)] fn to_nanos(&self, val: InternalGas) -> u64 { let gas: Gas = InternalGas::to_unit_round_down(val); u64::from(gas) * self.gas_price diff --git a/crates/iota-types/src/messages_checkpoint.rs b/crates/iota-types/src/messages_checkpoint.rs index 50a9f25d252..78cdffaeba2 100644 --- a/crates/iota-types/src/messages_checkpoint.rs +++ b/crates/iota-types/src/messages_checkpoint.rs @@ -60,7 +60,7 @@ pub struct CheckpointRequest { pub certified: bool, } -#[allow(clippy::large_enum_variant)] +#[expect(clippy::large_enum_variant)] #[derive(Clone, Debug, Serialize, Deserialize)] pub enum CheckpointSummaryResponse { Certified(CertifiedCheckpointSummary), @@ -76,7 +76,6 @@ impl CheckpointSummaryResponse { } } -#[allow(clippy::large_enum_variant)] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct CheckpointResponse { pub checkpoint: Option, diff --git a/crates/iota-types/src/messages_consensus.rs b/crates/iota-types/src/messages_consensus.rs index 77323a54518..a87ede12052 100644 --- a/crates/iota-types/src/messages_consensus.rs +++ b/crates/iota-types/src/messages_consensus.rs @@ -217,7 +217,6 @@ impl ConsensusTransactionKind { } #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] -#[allow(clippy::large_enum_variant)] pub enum VersionedDkgMessage { V1(dkg_v1::Message), } diff --git a/crates/iota-types/src/object.rs b/crates/iota-types/src/object.rs index 4cfe292d222..63ef7c06824 100644 --- a/crates/iota-types/src/object.rs +++ b/crates/iota-types/src/object.rs @@ -375,7 +375,6 @@ impl MoveObject { } #[derive(Eq, PartialEq, Debug, Clone, Deserialize, Serialize, Hash)] -#[allow(clippy::large_enum_variant)] pub enum Data { /// An object whose governing logic lives in a published Move module Move(MoveObject), @@ -1058,7 +1057,6 @@ pub fn generate_test_gas_objects() -> Vec { GAS_OBJECTS.with(|v| v.clone()) } -#[allow(clippy::large_enum_variant)] #[derive(Serialize, Deserialize, Debug)] #[serde(tag = "status", content = "details")] pub enum ObjectRead { @@ -1117,7 +1115,6 @@ impl Display for ObjectRead { } } -#[allow(clippy::large_enum_variant)] #[derive(Serialize, Deserialize, Debug)] #[serde(tag = "status", content = "details")] pub enum PastObjectRead { diff --git a/crates/iota-types/src/timelock/mod.rs b/crates/iota-types/src/timelock/mod.rs index ad30def1808..9fa70613509 100644 --- a/crates/iota-types/src/timelock/mod.rs +++ b/crates/iota-types/src/timelock/mod.rs @@ -3,7 +3,7 @@ pub mod label; pub mod stardust_upgrade_label; -#[allow(clippy::module_inception)] +#[expect(clippy::module_inception)] pub mod timelock; pub mod timelocked_staked_iota; pub mod timelocked_staking; diff --git a/crates/iota-util-mem-derive/lib.rs b/crates/iota-util-mem-derive/lib.rs index d2f308c2e52..83939225beb 100644 --- a/crates/iota-util-mem-derive/lib.rs +++ b/crates/iota-util-mem-derive/lib.rs @@ -76,7 +76,7 @@ fn malloc_size_of_derive(s: synstructure::Structure) -> proc_macro2::TokenStream let tokens = quote! { impl #impl_generics iota_util_mem::MallocSizeOf for #name #ty_generics #where_clause { #[inline] - #[allow(unused_variables, unused_mut, unreachable_code)] + #[expect(unused_variables, unused_mut, unreachable_code)] fn size_of(&self, ops: &mut iota_util_mem::MallocSizeOfOps) -> usize { let mut sum = 0; match *self { diff --git a/crates/iota/src/client_ptb/builder.rs b/crates/iota/src/client_ptb/builder.rs index b8678f11e26..c64514e2f48 100644 --- a/crates/iota/src/client_ptb/builder.rs +++ b/crates/iota/src/client_ptb/builder.rs @@ -1163,7 +1163,7 @@ pub(crate) fn display_did_you_mean + std::fmt::Display>( // This lint is disabled because it's not good and doesn't look at what you're // actually iterating over. This seems to be a common problem with this lint. // See e.g., https://github.com/rust-lang/rust-clippy/issues/6075 -#[allow(clippy::needless_range_loop)] +#[expect(clippy::needless_range_loop)] fn edit_distance(a: &str, b: &str) -> usize { let mut cache = vec![vec![0; b.len() + 1]; a.len() + 1]; diff --git a/crates/iota/src/genesis_inspector.rs b/crates/iota/src/genesis_inspector.rs index 6cba3824f43..5ebfacb50f1 100644 --- a/crates/iota/src/genesis_inspector.rs +++ b/crates/iota/src/genesis_inspector.rs @@ -27,7 +27,6 @@ const STR_IOTA_DISTRIBUTION: &str = "Iota Distribution"; const STR_OBJECTS: &str = "Objects"; const STR_VALIDATORS: &str = "Validators"; -#[allow(clippy::or_fun_call)] pub(crate) fn examine_genesis_checkpoint(genesis: UnsignedGenesis) { let system_object = genesis .iota_system_object() @@ -52,7 +51,7 @@ pub(crate) fn examine_genesis_checkpoint(genesis: UnsignedGenesis) { let mut iota_distribution = BTreeMap::new(); let entry = iota_distribution .entry("Iota System".to_string()) - .or_insert(BTreeMap::new()); + .or_insert_with(BTreeMap::new); entry.insert( "Storage Fund".to_string(), ( @@ -150,7 +149,7 @@ pub(crate) fn examine_genesis_checkpoint(genesis: UnsignedGenesis) { } } -#[allow(clippy::ptr_arg)] +#[expect(clippy::ptr_arg)] fn examine_validators( validator_options: &Vec<&str>, validator_map: &BTreeMap<&str, &IotaValidatorGenesis>, diff --git a/crates/iota/src/iota_commands.rs b/crates/iota/src/iota_commands.rs index 54cad050dae..e607b8dc183 100644 --- a/crates/iota/src/iota_commands.rs +++ b/crates/iota/src/iota_commands.rs @@ -146,7 +146,6 @@ impl IndexerFeatureArgs { } } -#[allow(clippy::large_enum_variant)] #[derive(Parser)] #[clap(rename_all = "kebab-case")] pub enum IotaCommand { diff --git a/crates/iota/src/keytool.rs b/crates/iota/src/keytool.rs index 246848e4c10..95b5c427139 100644 --- a/crates/iota/src/keytool.rs +++ b/crates/iota/src/keytool.rs @@ -59,7 +59,6 @@ use crate::key_identity::{KeyIdentity, get_identity_address_from_keystore}; #[path = "unit_tests/keytool_tests.rs"] mod keytool_tests; -#[allow(clippy::large_enum_variant)] #[derive(Subcommand)] #[clap(rename_all = "kebab-case")] pub enum KeyToolCommand { diff --git a/crates/simulacrum/src/lib.rs b/crates/simulacrum/src/lib.rs index 6a09576cc08..2165600de93 100644 --- a/crates/simulacrum/src/lib.rs +++ b/crates/simulacrum/src/lib.rs @@ -67,7 +67,7 @@ use self::{epoch_state::EpochState, store::in_mem_store::KeyStore}; pub struct Simulacrum { rng: R, keystore: KeyStore, - #[allow(unused)] + #[expect(unused)] genesis: genesis::Genesis, store: Store, checkpoint_builder: MockCheckpointBuilder, @@ -83,7 +83,7 @@ pub struct Simulacrum { impl Simulacrum { /// Create a new, random Simulacrum instance using an `OsRng` as the source /// of randomness. - #[allow(clippy::new_without_default)] + #[expect(clippy::new_without_default)] pub fn new() -> Self { Self::new_with_rng(OsRng) } diff --git a/crates/simulacrum/src/store/in_mem_store.rs b/crates/simulacrum/src/store/in_mem_store.rs index cd05dc3e8a4..9433000e28d 100644 --- a/crates/simulacrum/src/store/in_mem_store.rs +++ b/crates/simulacrum/src/store/in_mem_store.rs @@ -329,7 +329,6 @@ impl ObjectStore for InMemoryStore { #[derive(Debug)] pub struct KeyStore { validator_keys: BTreeMap, - #[allow(unused)] account_keys: BTreeMap, } diff --git a/crates/telemetry-subscribers/src/lib.rs b/crates/telemetry-subscribers/src/lib.rs index acebb2fb213..03ce9b0ba6c 100644 --- a/crates/telemetry-subscribers/src/lib.rs +++ b/crates/telemetry-subscribers/src/lib.rs @@ -69,9 +69,10 @@ pub struct TelemetryConfig { } #[must_use] -#[allow(dead_code)] pub struct TelemetryGuards { + #[expect(unused)] worker_guard: WorkerGuard, + #[expect(unused)] provider: Option, } diff --git a/crates/typed-store-derive/src/lib.rs b/crates/typed-store-derive/src/lib.rs index 9c61652616a..e1997e40824 100644 --- a/crates/typed-store-derive/src/lib.rs +++ b/crates/typed-store-derive/src/lib.rs @@ -380,7 +380,7 @@ pub fn derive_dbmap_utils_general(input: TokenStream) -> TokenStream { /// Only one process is allowed to do this at a time /// `global_db_options_override` apply to the whole DB /// `tables_db_options_override` apply to each table. If `None`, the attributes from `default_options_override_fn` are used if any - #[allow(unused_parens)] + #[expect(unused_parens)] pub fn open_tables_read_write( path: std::path::PathBuf, metric_conf: typed_store::rocks::MetricConf, @@ -395,7 +395,7 @@ pub fn derive_dbmap_utils_general(input: TokenStream) -> TokenStream { } } - #[allow(unused_parens)] + #[expect(unused_parens)] pub fn open_tables_read_write_with_deprecation_option( path: std::path::PathBuf, metric_conf: typed_store::rocks::MetricConf, @@ -415,7 +415,7 @@ pub fn derive_dbmap_utils_general(input: TokenStream) -> TokenStream { /// Only one process is allowed to do this at a time /// `global_db_options_override` apply to the whole DB /// `tables_db_options_override` apply to each table. If `None`, the attributes from `default_options_override_fn` are used if any - #[allow(unused_parens)] + #[expect(unused_parens)] pub fn open_tables_transactional( path: std::path::PathBuf, metric_conf: typed_store::rocks::MetricConf, @@ -794,7 +794,7 @@ pub fn derive_sallydb_general(input: TokenStream) -> TokenStream { /// Only one process is allowed to do this at a time /// `global_db_options_override` apply to the whole DB /// `tables_db_options_override` apply to each table. If `None`, the attributes from `default_options_override_fn` are used if any - #[allow(unused_parens)] + #[expect(unused_parens)] pub fn init( db_options: typed_store::sally::SallyDBOptions ) -> Self { diff --git a/crates/typed-store/src/rocks/mod.rs b/crates/typed-store/src/rocks/mod.rs index d142afddf15..3787e540cfd 100644 --- a/crates/typed-store/src/rocks/mod.rs +++ b/crates/typed-store/src/rocks/mod.rs @@ -351,7 +351,7 @@ impl RocksDB { fail_point!("delete-cf-before"); let ret = delegate_call!(self.delete_cf_opt(cf, key, writeopts)); fail_point!("delete-cf-after"); - #[allow(clippy::let_and_return)] + #[expect(clippy::let_and_return)] ret } @@ -373,7 +373,7 @@ impl RocksDB { fail_point!("put-cf-before"); let ret = delegate_call!(self.put_cf_opt(cf, key, value, writeopts)); fail_point!("put-cf-after"); - #[allow(clippy::let_and_return)] + #[expect(clippy::let_and_return)] ret } @@ -414,7 +414,7 @@ impl RocksDB { )), }; fail_point!("batch-write-after"); - #[allow(clippy::let_and_return)] + #[expect(clippy::let_and_return)] ret } @@ -2837,7 +2837,7 @@ fn is_max(v: &[u8]) -> bool { v.iter().all(|&x| x == u8::MAX) } -#[allow(clippy::assign_op_pattern)] +#[expect(clippy::assign_op_pattern)] #[test] fn test_helpers() { let v = vec![]; diff --git a/examples/tic-tac-toe/cli/src/turn_cap.rs b/examples/tic-tac-toe/cli/src/turn_cap.rs index 73af874cc6e..9ee96ed8435 100644 --- a/examples/tic-tac-toe/cli/src/turn_cap.rs +++ b/examples/tic-tac-toe/cli/src/turn_cap.rs @@ -2,12 +2,11 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use serde::Deserialize; use iota_types::base_types::ObjectID; +use serde::Deserialize; -/// Rust representation of a Move `owned::TurnCap`, suitable for deserializing from their BCS -/// representation. -#[allow(dead_code)] +/// Rust representation of a Move `owned::TurnCap`, suitable for deserializing +/// from their BCS representation. #[derive(Deserialize)] pub(crate) struct TurnCap { pub id: ObjectID, diff --git a/iota-execution/latest/iota-adapter/src/gas_charger.rs b/iota-execution/latest/iota-adapter/src/gas_charger.rs index d83e38ba39b..be082050188 100644 --- a/iota-execution/latest/iota-adapter/src/gas_charger.rs +++ b/iota-execution/latest/iota-adapter/src/gas_charger.rs @@ -28,14 +28,14 @@ pub mod checked { /// All the information about gas is stored in this object. /// The objective here is two-fold: /// 1- Isolate al version info into a single entry point. This file and the - /// other gas related files are the only one that check for gas + /// other gas related files are the only one that check for gas /// version. 2- Isolate all gas accounting into a single implementation. - /// Gas objects are not passed around, and they are retrieved from + /// Gas objects are not passed around, and they are retrieved from /// this instance. - #[allow(dead_code)] #[derive(Debug)] pub struct GasCharger { tx_digest: TransactionDigest, + #[expect(unused)] gas_model_version: u64, gas_coins: Vec, // this is the first gas coin in `gas_coins` and the one that all others will diff --git a/iota-execution/latest/iota-adapter/src/programmable_transactions/execution.rs b/iota-execution/latest/iota-adapter/src/programmable_transactions/execution.rs index b382a447ffc..60dff0ae180 100644 --- a/iota-execution/latest/iota-adapter/src/programmable_transactions/execution.rs +++ b/iota-execution/latest/iota-adapter/src/programmable_transactions/execution.rs @@ -844,7 +844,7 @@ mod checked { /// instances using the protocol's binary configuration. The function /// ensures that the module list is not empty and converts any /// deserialization errors into an `ExecutionError`. - #[allow(clippy::extra_unused_type_parameters)] + #[expect(clippy::extra_unused_type_parameters)] fn deserialize_modules( context: &mut ExecutionContext<'_, '_, '_>, module_bytes: &[Vec], diff --git a/iota-execution/latest/iota-move-natives/src/object_runtime/object_store.rs b/iota-execution/latest/iota-move-natives/src/object_runtime/object_store.rs index 50ef7d78cc3..fcada9506e3 100644 --- a/iota-execution/latest/iota-move-natives/src/object_runtime/object_store.rs +++ b/iota-execution/latest/iota-move-natives/src/object_runtime/object_store.rs @@ -229,7 +229,6 @@ impl Inner<'_> { Ok(obj_opt) } - #[allow(clippy::map_entry)] fn get_or_fetch_object_from_store( &mut self, parent: ObjectID, From 5ede92911bac533489ae3f8387a8755a6b7d6a29 Mon Sep 17 00:00:00 2001 From: Marc Espin Date: Mon, 16 Dec 2024 15:03:33 +0100 Subject: [PATCH 02/14] fix(pnpm): Lock ws to 8.18.0 (#4469) --- package.json | 3 ++- pnpm-lock.yaml | 59 +++++--------------------------------------------- 2 files changed, 8 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index 653580fe2fc..76d65042397 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,8 @@ "eslint": "8.57.1", "mermaid@10.9.1": "10.9.3", "http-proxy-middleware": "2.0.7", - "cross-spawn": "7.0.5" + "cross-spawn": "7.0.5", + "ws": "8.18.0" } }, "engines": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e765a5f6859..6aba893215d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,6 +21,7 @@ overrides: mermaid@10.9.1: 10.9.3 http-proxy-middleware: 2.0.7 cross-spawn: 7.0.5 + ws: 8.18.0 importers: @@ -2019,7 +2020,7 @@ importers: specifier: ^7.2.0 version: 7.2.0 ws: - specifier: ^8.18.0 + specifier: 8.18.0 version: 8.18.0 sdk/wallet-standard: @@ -8201,9 +8202,6 @@ packages: resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} hasBin: true - async-limiter@1.0.1: - resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} - async@3.2.2: resolution: {integrity: sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==} @@ -11593,7 +11591,7 @@ packages: isomorphic-ws@5.0.0: resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} peerDependencies: - ws: '*' + ws: 8.18.0 isstream@0.1.2: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} @@ -16666,41 +16664,6 @@ packages: resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - ws@6.2.3: - resolution: {integrity: sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - ws@7.5.10: - resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} - engines: {node: '>=8.3.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - ws@8.13.0: - resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - ws@8.18.0: resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} @@ -25625,8 +25588,6 @@ snapshots: astring@1.9.0: {} - async-limiter@1.0.1: {} - async@3.2.2: {} asynckit@0.4.0: {} @@ -32813,7 +32774,7 @@ snapshots: progress: 2.0.3 proxy-from-env: 1.1.0 rimraf: 2.7.1 - ws: 6.2.3 + ws: 8.18.0 transitivePeerDependencies: - bufferutil - supports-color @@ -35734,7 +35695,7 @@ snapshots: tmp: 0.2.1 update-notifier: 6.0.2 watchpack: 2.4.0 - ws: 8.13.0 + ws: 8.18.0 yargs: 17.7.1 zip-dir: 2.0.0 transitivePeerDependencies: @@ -36009,7 +35970,7 @@ snapshots: opener: 1.5.2 picocolors: 1.1.0 sirv: 2.0.4 - ws: 7.5.10 + ws: 8.18.0 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -36368,14 +36329,6 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 3.0.7 - ws@6.2.3: - dependencies: - async-limiter: 1.0.1 - - ws@7.5.10: {} - - ws@8.13.0: {} - ws@8.18.0: {} xdg-basedir@5.1.0: {} From 62f51bd23acdbc258d1d8e3729eef21caef41c28 Mon Sep 17 00:00:00 2001 From: JCNoguera <88061365+VmMad@users.noreply.github.com> Date: Mon, 16 Dec 2024 18:52:02 +0100 Subject: [PATCH 03/14] feat(dashboard): add migratable object details (#4424) * feat(dashboard): add migration overview * feat: refine values * fix: update summarizeMigratableObjectValues function * feat(dashboard): add migratable object details * feat: add object details * fix: add missing type * feat: use react query to cache data * refactor: show expiration label correctly * feat: add missing asset fallback * feat: simplify code, add correct timestamps * fix: remove package id * fix: bring back missing logic * fix: remove unnecesary memos and improve skeleton * perf: fetch objects in chunks * fix: remove duplicated export * fix: show correct time in expiration * feat: disable buttons * fix: remove file and improve sorting --- .../migration/createMigrationTransaction.ts | 21 +- apps/core/src/utils/parseObjectDetails.ts | 14 +- apps/ui-kit/src/lib/components/atoms/index.ts | 1 + .../components/atoms/skeleton/Skeleton.tsx | 47 ++++ .../lib/components/atoms/skeleton/index.ts | 4 + .../stories/atoms/Skeleton.stories.tsx | 33 +++ .../app/(protected)/migrations/page.tsx | 231 +++++++++++------ .../components/MigrationOverview.tsx | 2 +- .../components/Popup/Popups/MigratePopup.tsx | 4 +- .../components/VirtualList.tsx | 55 +++-- apps/wallet-dashboard/components/index.ts | 1 + .../migration/MigrationObjectsPanel.tsx | 141 +++++++++++ .../components/migration/index.ts | 4 + .../MigrationObjectDetailsCard.tsx | 155 ++++++++++++ .../migration-object-details-card/index.ts | 4 + apps/wallet-dashboard/hooks/index.ts | 1 + .../hooks/useGetCurrentEpochEndTimestamp.ts | 21 ++ .../hooks/useGetStardustMigratableObjects.ts | 61 +++-- ...GroupedMigrationObjectsByExpirationDate.ts | 59 +++++ apps/wallet-dashboard/lib/constants/index.ts | 1 + .../lib/constants/migration.constants.ts | 15 ++ .../enums/commonMigrationObjectType.enums.ts | 8 + apps/wallet-dashboard/lib/enums/index.ts | 3 + .../enums/stardustOutputDetailsFilter.enum.ts | 10 + .../stardustOutputMigrationStatus.enum.ts | 7 + apps/wallet-dashboard/lib/types/index.ts | 4 + .../lib/types/stardustMigrationObjects.ts | 33 +++ .../migration/filterMigrationObjectDetails.ts | 37 +++ .../utils/migration/groupMigrationObjects.ts | 232 ++++++++++++++++++ .../groupStardustObjectsByMigrationStatus.ts} | 74 ++++-- .../lib/utils/migration/index.ts | 6 + 31 files changed, 1133 insertions(+), 156 deletions(-) create mode 100644 apps/ui-kit/src/lib/components/atoms/skeleton/Skeleton.tsx create mode 100644 apps/ui-kit/src/lib/components/atoms/skeleton/index.ts create mode 100644 apps/ui-kit/src/storybook/stories/atoms/Skeleton.stories.tsx create mode 100644 apps/wallet-dashboard/components/migration/MigrationObjectsPanel.tsx create mode 100644 apps/wallet-dashboard/components/migration/index.ts create mode 100644 apps/wallet-dashboard/components/migration/migration-object-details-card/MigrationObjectDetailsCard.tsx create mode 100644 apps/wallet-dashboard/components/migration/migration-object-details-card/index.ts create mode 100644 apps/wallet-dashboard/hooks/useGetCurrentEpochEndTimestamp.ts create mode 100644 apps/wallet-dashboard/hooks/useGroupedMigrationObjectsByExpirationDate.ts create mode 100644 apps/wallet-dashboard/lib/constants/migration.constants.ts create mode 100644 apps/wallet-dashboard/lib/enums/commonMigrationObjectType.enums.ts create mode 100644 apps/wallet-dashboard/lib/enums/stardustOutputDetailsFilter.enum.ts create mode 100644 apps/wallet-dashboard/lib/enums/stardustOutputMigrationStatus.enum.ts create mode 100644 apps/wallet-dashboard/lib/types/index.ts create mode 100644 apps/wallet-dashboard/lib/types/stardustMigrationObjects.ts create mode 100644 apps/wallet-dashboard/lib/utils/migration/filterMigrationObjectDetails.ts create mode 100644 apps/wallet-dashboard/lib/utils/migration/groupMigrationObjects.ts rename apps/wallet-dashboard/lib/utils/{migration.ts => migration/groupStardustObjectsByMigrationStatus.ts} (53%) create mode 100644 apps/wallet-dashboard/lib/utils/migration/index.ts diff --git a/apps/core/src/utils/migration/createMigrationTransaction.ts b/apps/core/src/utils/migration/createMigrationTransaction.ts index 8519a950831..c5ac17fa556 100644 --- a/apps/core/src/utils/migration/createMigrationTransaction.ts +++ b/apps/core/src/utils/migration/createMigrationTransaction.ts @@ -1,7 +1,7 @@ // Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -import { IotaClient, IotaObjectData } from '@iota/iota-sdk/client'; +import { DynamicFieldInfo, IotaClient, IotaObjectData } from '@iota/iota-sdk/client'; import { Transaction } from '@iota/iota-sdk/transactions'; import { STARDUST_PACKAGE_ID } from '../../constants/migration.constants'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; @@ -17,21 +17,28 @@ type NestedResultType = { NestedResult: [number, number]; }; -export async function getNativeTokenTypesFromBag( - bagId: string, - client: IotaClient, -): Promise { +export async function getNativeTokensFromBag(bagId: string, client: IotaClient) { const nativeTokenDynamicFields = await client.getDynamicFields({ parentId: bagId, }); - const nativeTokenTypes: string[] = []; + const nativeTokenTypes: DynamicFieldInfo[] = []; for (const nativeToken of nativeTokenDynamicFields.data) { - nativeTokenTypes.push(nativeToken?.name?.value as string); + nativeTokenTypes.push(nativeToken); } return nativeTokenTypes; } +export async function getNativeTokenTypesFromBag( + bagId: string, + client: IotaClient, +): Promise { + const nativeTokenDynamicFields = await client.getDynamicFields({ + parentId: bagId, + }); + return nativeTokenDynamicFields.data.map(({ name }) => name.value as string); +} + export function validateBasicOutputObject(outputObject: IotaObjectData): BasicOutputObject { if (outputObject.content?.dataType !== 'moveObject') { throw new Error('Invalid basic output object'); diff --git a/apps/core/src/utils/parseObjectDetails.ts b/apps/core/src/utils/parseObjectDetails.ts index 76a9884c5d8..fefa3c717e1 100644 --- a/apps/core/src/utils/parseObjectDetails.ts +++ b/apps/core/src/utils/parseObjectDetails.ts @@ -9,10 +9,16 @@ type ObjectChangeWithObjectType = Extract< { objectType: string } >; +type PackageId = string; +type ModuleName = string; +type TypeName = string; export function parseObjectChangeDetails( objectChange: ObjectChangeWithObjectType, -): [string, string, string] { - const [packageId, moduleName, typeName] = - objectChange.objectType?.split('<')[0]?.split('::') || []; - return [packageId, moduleName, typeName]; +): [PackageId, ModuleName, TypeName] { + return extractObjectTypeStruct(objectChange.objectType); +} + +export function extractObjectTypeStruct(objectType: string): [PackageId, ModuleName, TypeName] { + const [packageId, moduleName, functionName] = objectType?.split('<')[0]?.split('::') || []; + return [packageId, moduleName, functionName]; } diff --git a/apps/ui-kit/src/lib/components/atoms/index.ts b/apps/ui-kit/src/lib/components/atoms/index.ts index 373f611cd1e..12a58426391 100644 --- a/apps/ui-kit/src/lib/components/atoms/index.ts +++ b/apps/ui-kit/src/lib/components/atoms/index.ts @@ -19,3 +19,4 @@ export * from './snackbar'; export * from './visual-asset-card'; export * from './loading-indicator'; export * from './placeholder'; +export * from './skeleton'; diff --git a/apps/ui-kit/src/lib/components/atoms/skeleton/Skeleton.tsx b/apps/ui-kit/src/lib/components/atoms/skeleton/Skeleton.tsx new file mode 100644 index 00000000000..9504693f036 --- /dev/null +++ b/apps/ui-kit/src/lib/components/atoms/skeleton/Skeleton.tsx @@ -0,0 +1,47 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import cx from 'classnames'; + +interface SkeletonLoaderProps { + /** + * Width class for the skeleton div. + */ + widthClass?: string; + /** + * Height class for the skeleton div. + */ + heightClass?: string; + /** + * If true, the skeleton will use darker neutral colors. + */ + hasSecondaryColors?: boolean; + /** + * Whether the class `rounded-full` should be applied. Defaults to true. + */ + isRounded?: boolean; +} + +export function Skeleton({ + children, + widthClass = 'w-full', + heightClass = 'h-3', + hasSecondaryColors, + isRounded = true, +}: React.PropsWithChildren): React.JSX.Element { + return ( +
+ {children} +
+ ); +} diff --git a/apps/ui-kit/src/lib/components/atoms/skeleton/index.ts b/apps/ui-kit/src/lib/components/atoms/skeleton/index.ts new file mode 100644 index 00000000000..4540f454c5f --- /dev/null +++ b/apps/ui-kit/src/lib/components/atoms/skeleton/index.ts @@ -0,0 +1,4 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export * from './Skeleton'; diff --git a/apps/ui-kit/src/storybook/stories/atoms/Skeleton.stories.tsx b/apps/ui-kit/src/storybook/stories/atoms/Skeleton.stories.tsx new file mode 100644 index 00000000000..cb611c8cf08 --- /dev/null +++ b/apps/ui-kit/src/storybook/stories/atoms/Skeleton.stories.tsx @@ -0,0 +1,33 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import type { Meta, StoryObj } from '@storybook/react'; +import { Card, CardImage, ImageShape, Skeleton } from '@/components'; + +const meta: Meta = { + component: Skeleton, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const SkeletonCard: Story = { + render: () => ( + + +
+ + +
+ + +
+
+ + +
+ + ), +}; diff --git a/apps/wallet-dashboard/app/(protected)/migrations/page.tsx b/apps/wallet-dashboard/app/(protected)/migrations/page.tsx index 544f352e963..acc5dd6f40c 100644 --- a/apps/wallet-dashboard/app/(protected)/migrations/page.tsx +++ b/apps/wallet-dashboard/app/(protected)/migrations/page.tsx @@ -1,10 +1,14 @@ // Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 + 'use client'; +import { useState, useMemo, useCallback } from 'react'; +import { useQueryClient } from '@tanstack/react-query'; +import clsx from 'clsx'; import MigratePopup from '@/components/Popup/Popups/MigratePopup'; -import { usePopups } from '@/hooks'; -import { summarizeMigratableObjectValues } from '@/lib/utils'; +import { useGetStardustMigratableObjects, usePopups } from '@/hooks'; +import { summarizeMigratableObjectValues, summarizeUnmigratableObjectValues } from '@/lib/utils'; import { Button, ButtonSize, @@ -16,18 +20,12 @@ import { Panel, Title, } from '@iota/apps-ui-kit'; +import { Assets, Clock, IotaLogoMark, Tokens } from '@iota/ui-icons'; import { useCurrentAccount, useIotaClient } from '@iota/dapp-kit'; import { STARDUST_BASIC_OUTPUT_TYPE, STARDUST_NFT_OUTPUT_TYPE, useFormatCoin } from '@iota/core'; -import { useGetStardustMigratableObjects } from '@/hooks'; -import { useQueryClient } from '@tanstack/react-query'; -import { Assets, Clock, IotaLogoMark, Tokens } from '@iota/ui-icons'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; - -interface MigrationDisplayCard { - title: string; - subtitle: string; - icon: React.FC; -} +import { StardustOutputMigrationStatus } from '@/lib/enums'; +import { MigrationObjectsPanel } from '@/components'; function MigrationDashboardPage(): JSX.Element { const account = useCurrentAccount(); @@ -36,98 +34,128 @@ function MigrationDashboardPage(): JSX.Element { const queryClient = useQueryClient(); const iotaClient = useIotaClient(); + const [selectedStardustObjectsCategory, setSelectedStardustObjectsCategory] = useState< + StardustOutputMigrationStatus | undefined + >(undefined); + + const { data: stardustMigrationObjects, isPlaceholderData } = + useGetStardustMigratableObjects(address); const { migratableBasicOutputs, - unmigratableBasicOutputs, migratableNftOutputs, + unmigratableBasicOutputs, unmigratableNftOutputs, - } = useGetStardustMigratableObjects(address); + } = stardustMigrationObjects || {}; + + const { + totalIotaAmount, + totalNativeTokens: migratableNativeTokens, + totalVisualAssets: migratableVisualAssets, + } = summarizeMigratableObjectValues({ + basicOutputs: migratableBasicOutputs, + nftOutputs: migratableNftOutputs, + address, + }); + const { totalUnmigratableObjects } = summarizeUnmigratableObjectValues({ + basicOutputs: unmigratableBasicOutputs, + nftOutputs: unmigratableNftOutputs, + }); const hasMigratableObjects = - migratableBasicOutputs.length > 0 || migratableNftOutputs.length > 0; - - function handleOnSuccess(digest: string): void { - iotaClient - .waitForTransaction({ - digest, - }) - .then(() => { + (migratableBasicOutputs?.length || 0) > 0 && (migratableNftOutputs?.length || 0) > 0; + + const [timelockedIotaTokens, symbol] = useFormatCoin(totalIotaAmount, IOTA_TYPE_ARG); + + const handleOnSuccess = useCallback( + (digest: string) => { + iotaClient.waitForTransaction({ digest }).then(() => { queryClient.invalidateQueries({ queryKey: [ 'get-all-owned-objects', address, - { - StructType: STARDUST_BASIC_OUTPUT_TYPE, - }, + { StructType: STARDUST_BASIC_OUTPUT_TYPE }, ], }); queryClient.invalidateQueries({ queryKey: [ 'get-all-owned-objects', address, - { - StructType: STARDUST_NFT_OUTPUT_TYPE, - }, + { StructType: STARDUST_NFT_OUTPUT_TYPE }, ], }); }); - } - function openMigratePopup(): void { - openPopup( - , - ); - } - - const { - accumulatedIotaAmount: accumulatedTimelockedIotaAmount, - totalNativeTokens, - totalVisualAssets, - } = summarizeMigratableObjectValues({ - migratableBasicOutputs, - migratableNftOutputs, - address, - }); - - const [timelockedIotaTokens, symbol] = useFormatCoin( - accumulatedTimelockedIotaAmount, - IOTA_TYPE_ARG, + }, + [iotaClient, queryClient, address], ); - const MIGRATION_CARDS: MigrationDisplayCard[] = [ + const MIGRATION_CARDS: MigrationDisplayCardProps[] = [ { title: `${timelockedIotaTokens} ${symbol}`, subtitle: 'IOTA Tokens', icon: IotaLogoMark, }, { - title: `${totalNativeTokens}`, + title: `${migratableNativeTokens}`, subtitle: 'Native Tokens', icon: Tokens, }, { - title: `${totalVisualAssets}`, + title: `${migratableVisualAssets}`, subtitle: 'Visual Assets', icon: Assets, }, ]; - const timelockedAssetsAmount = unmigratableBasicOutputs.length + unmigratableNftOutputs.length; - const TIMELOCKED_ASSETS_CARDS: MigrationDisplayCard[] = [ + const TIMELOCKED_ASSETS_CARDS: MigrationDisplayCardProps[] = [ { - title: `${timelockedAssetsAmount}`, + title: `${totalUnmigratableObjects}`, subtitle: 'Time-locked', icon: Clock, }, ]; + const selectedObjects = useMemo(() => { + if (stardustMigrationObjects) { + if (selectedStardustObjectsCategory === StardustOutputMigrationStatus.Migratable) { + return [ + ...stardustMigrationObjects.migratableBasicOutputs, + ...stardustMigrationObjects.migratableNftOutputs, + ]; + } else if ( + selectedStardustObjectsCategory === StardustOutputMigrationStatus.TimeLocked + ) { + return [ + ...stardustMigrationObjects.unmigratableBasicOutputs, + ...stardustMigrationObjects.unmigratableNftOutputs, + ]; + } + } + return []; + }, [selectedStardustObjectsCategory, stardustMigrationObjects]); + + function openMigratePopup(): void { + openPopup( + , + ); + } + + function handleCloseDetailsPanel() { + setSelectedStardustObjectsCategory(undefined); + } + return (
-
+
<div className="flex flex-col gap-xs p-md--rs"> {MIGRATION_CARDS.map((card) => ( - <Card key={card.subtitle}> - <CardImage shape={ImageShape.SquareRounded}> - <card.icon /> - </CardImage> - <CardBody title={card.title} subtitle={card.subtitle} /> - </Card> + <MigrationDisplayCard + key={card.subtitle} + isPlaceholder={isPlaceholderData} + {...card} + /> ))} - <Button text="See All" type={ButtonType.Ghost} fullWidth /> + <Button + text="See All" + type={ButtonType.Ghost} + fullWidth + disabled={ + selectedStardustObjectsCategory === + StardustOutputMigrationStatus.Migratable || + !hasMigratableObjects + } + onClick={() => + setSelectedStardustObjectsCategory( + StardustOutputMigrationStatus.Migratable, + ) + } + /> </div> </Panel> @@ -158,20 +199,64 @@ function MigrationDashboardPage(): JSX.Element { <Title title="Time-locked Assets" /> <div className="flex flex-col gap-xs p-md--rs"> {TIMELOCKED_ASSETS_CARDS.map((card) => ( - <Card key={card.subtitle}> - <CardImage shape={ImageShape.SquareRounded}> - <card.icon /> - </CardImage> - <CardBody title={card.title} subtitle={card.subtitle} /> - </Card> + <MigrationDisplayCard + key={card.subtitle} + isPlaceholder={isPlaceholderData} + {...card} + /> ))} - <Button text="See All" type={ButtonType.Ghost} fullWidth /> + <Button + text="See All" + type={ButtonType.Ghost} + fullWidth + disabled={ + selectedStardustObjectsCategory === + StardustOutputMigrationStatus.TimeLocked || + !totalUnmigratableObjects + } + onClick={() => + setSelectedStardustObjectsCategory( + StardustOutputMigrationStatus.TimeLocked, + ) + } + /> </div> </Panel> </div> + + <MigrationObjectsPanel + selectedObjects={selectedObjects} + onClose={handleCloseDetailsPanel} + isTimelocked={ + selectedStardustObjectsCategory === StardustOutputMigrationStatus.TimeLocked + } + /> </div> </div> ); } +interface MigrationDisplayCardProps { + title: string; + subtitle: string; + icon: React.ComponentType; + isPlaceholder?: boolean; +} + +function MigrationDisplayCard({ + title, + subtitle, + icon: Icon, + isPlaceholder, +}: MigrationDisplayCardProps): React.JSX.Element { + return ( + <Card> + <CardImage shape={ImageShape.SquareRounded}> + <Icon /> + </CardImage> + <CardBody title={isPlaceholder ? '--' : title} subtitle={subtitle} /> + </Card> + ); +} + export default MigrationDashboardPage; diff --git a/apps/wallet-dashboard/components/MigrationOverview.tsx b/apps/wallet-dashboard/components/MigrationOverview.tsx index 9b17852f3d5..09faf91737b 100644 --- a/apps/wallet-dashboard/components/MigrationOverview.tsx +++ b/apps/wallet-dashboard/components/MigrationOverview.tsx @@ -12,7 +12,7 @@ export function MigrationOverview() { const router = useRouter(); const account = useCurrentAccount(); const address = account?.address || ''; - const { migratableBasicOutputs, migratableNftOutputs } = + const { data: { migratableBasicOutputs = [], migratableNftOutputs = [] } = {} } = useGetStardustMigratableObjects(address); const needsMigration = migratableBasicOutputs.length > 0 || migratableNftOutputs.length > 0; diff --git a/apps/wallet-dashboard/components/Popup/Popups/MigratePopup.tsx b/apps/wallet-dashboard/components/Popup/Popups/MigratePopup.tsx index 627fb860f3f..e824e41a24d 100644 --- a/apps/wallet-dashboard/components/Popup/Popups/MigratePopup.tsx +++ b/apps/wallet-dashboard/components/Popup/Popups/MigratePopup.tsx @@ -16,8 +16,8 @@ import { NotificationType } from '@/stores/notificationStore'; import { Loader, Warning } from '@iota/ui-icons'; interface MigratePopupProps { - basicOutputObjects: IotaObjectData[]; - nftOutputObjects: IotaObjectData[]; + basicOutputObjects: IotaObjectData[] | undefined; + nftOutputObjects: IotaObjectData[] | undefined; closePopup: () => void; onSuccess?: (digest: string) => void; } diff --git a/apps/wallet-dashboard/components/VirtualList.tsx b/apps/wallet-dashboard/components/VirtualList.tsx index 49178382bfc..54920f7d64c 100644 --- a/apps/wallet-dashboard/components/VirtualList.tsx +++ b/apps/wallet-dashboard/components/VirtualList.tsx @@ -5,6 +5,7 @@ import React, { ReactNode, useEffect } from 'react'; import { useVirtualizer } from '@tanstack/react-virtual'; +import clsx from 'clsx'; interface VirtualListProps<T> { items: T[]; @@ -14,6 +15,8 @@ interface VirtualListProps<T> { estimateSize: (index: number) => number; render: (item: T, index: number) => ReactNode; onClick?: (item: T) => void; + heightClassName?: string; + overflowClassName?: string; } function VirtualList<T>({ @@ -24,6 +27,8 @@ function VirtualList<T>({ estimateSize, render, onClick, + heightClassName = 'h-full', + overflowClassName, }: VirtualListProps<T>): JSX.Element { const containerRef = React.useRef<HTMLDivElement | null>(null); const virtualizer = useVirtualizer({ @@ -61,7 +66,10 @@ function VirtualList<T>({ ]); return ( - <div className="relative h-full w-full" ref={containerRef}> + <div + className={clsx('relative w-full', heightClassName, overflowClassName)} + ref={containerRef} + > <div style={{ height: `${virtualizer.getTotalSize()}px`, @@ -69,27 +77,30 @@ function VirtualList<T>({ position: 'relative', }} > - {virtualItems.map((virtualItem) => ( - <div - key={virtualItem.key} - className={`absolute w-full ${onClick ? 'cursor-pointer' : ''}`} - style={{ - position: 'absolute', - top: 0, - left: 0, - width: '100%', - height: `${virtualItem.size}px`, - transform: `translateY(${virtualItem.start}px)`, - }} - onClick={() => onClick && onClick(items[virtualItem.index])} - > - {virtualItem.index > items.length - 1 - ? hasNextPage - ? 'Loading more...' - : 'Nothing more to load' - : render(items[virtualItem.index], virtualItem.index)} - </div> - ))} + {virtualItems.map((virtualItem) => { + const item = items[virtualItem.index]; + return ( + <div + key={virtualItem.key} + className={`absolute w-full ${onClick ? 'cursor-pointer' : ''}`} + style={{ + position: 'absolute', + top: 0, + left: 0, + width: '100%', + height: `${virtualItem.size}px`, + transform: `translateY(${virtualItem.start}px)`, + }} + onClick={() => onClick && onClick(item)} + > + {virtualItem.index > items.length - 1 + ? hasNextPage + ? 'Loading more...' + : 'Nothing more to load' + : render(item, virtualItem.index)} + </div> + ); + })} </div> </div> ); diff --git a/apps/wallet-dashboard/components/index.ts b/apps/wallet-dashboard/components/index.ts index 37ff834be4f..1e655a49bdc 100644 --- a/apps/wallet-dashboard/components/index.ts +++ b/apps/wallet-dashboard/components/index.ts @@ -23,6 +23,7 @@ export * from './ExplorerLink'; export * from './Dialogs'; export * from './ValidatorStakingData'; export * from './tiles'; +export * from './migration'; export * from './Toaster'; export * from './Banner'; export * from './MigrationOverview'; diff --git a/apps/wallet-dashboard/components/migration/MigrationObjectsPanel.tsx b/apps/wallet-dashboard/components/migration/MigrationObjectsPanel.tsx new file mode 100644 index 00000000000..4d5d80d0af3 --- /dev/null +++ b/apps/wallet-dashboard/components/migration/MigrationObjectsPanel.tsx @@ -0,0 +1,141 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +'use client'; + +import { useGroupedMigrationObjectsByExpirationDate } from '@/hooks'; +import { + STARDUST_MIGRATABLE_OBJECTS_FILTER_LIST, + STARDUST_UNMIGRATABLE_OBJECTS_FILTER_LIST, +} from '@/lib/constants'; +import { StardustOutputDetailsFilter } from '@/lib/enums'; +import { + Button, + ButtonType, + Card, + CardImage, + Chip, + ImageShape, + InfoBox, + InfoBoxStyle, + InfoBoxType, + Panel, + Skeleton, + Title, +} from '@iota/apps-ui-kit'; +import type { IotaObjectData } from '@iota/iota-sdk/client'; +import { Close, Warning } from '@iota/ui-icons'; +import clsx from 'clsx'; +import { useState } from 'react'; +import { MigrationObjectDetailsCard } from './migration-object-details-card'; +import VirtualList from '../VirtualList'; +import { filterMigrationObjects } from '@/lib/utils'; + +const FILTERS = { + migratable: STARDUST_MIGRATABLE_OBJECTS_FILTER_LIST, + unmigratable: STARDUST_UNMIGRATABLE_OBJECTS_FILTER_LIST, +}; + +interface MigrationObjectsPanelProps { + selectedObjects: IotaObjectData[]; + onClose: () => void; + isTimelocked: boolean; +} + +export function MigrationObjectsPanel({ + selectedObjects, + onClose, + isTimelocked, +}: MigrationObjectsPanelProps): React.JSX.Element { + const [stardustOutputDetailsFilter, setStardustOutputDetailsFilter] = + useState<StardustOutputDetailsFilter>(StardustOutputDetailsFilter.All); + + const { + data: resolvedObjects = [], + isLoading, + error: isErrored, + } = useGroupedMigrationObjectsByExpirationDate(selectedObjects, isTimelocked); + + const filteredObjects = filterMigrationObjects(resolvedObjects, stardustOutputDetailsFilter); + + const filters = isTimelocked ? FILTERS.unmigratable : FILTERS.migratable; + const isHidden = selectedObjects.length === 0; + + return ( + <div className={clsx('flex h-full min-h-0 w-2/3 flex-col', isHidden && 'hidden')}> + <Panel> + <Title + title="Details" + trailingElement={ + <Button icon={<Close />} type={ButtonType.Ghost} onClick={onClose} /> + } + /> + <div className="flex min-h-0 flex-1 flex-col px-md--rs"> + <div className="flex flex-row gap-xs py-xs"> + {filters.map((filter) => ( + <Chip + key={filter} + label={filter} + onClick={() => setStardustOutputDetailsFilter(filter)} + selected={stardustOutputDetailsFilter === filter} + /> + ))} + </div> + <div className="flex min-h-0 flex-col py-sm"> + <div className="h-full flex-1 overflow-auto"> + {isLoading && <LoadingPanel />} + {isErrored && !isLoading && ( + <div className="flex h-full max-h-full w-full flex-col items-center"> + <InfoBox + title="Error" + supportingText="Failed to load stardust objects" + style={InfoBoxStyle.Elevated} + type={InfoBoxType.Error} + icon={<Warning />} + /> + </div> + )} + {!isLoading && !isErrored && ( + <VirtualList + heightClassName="h-[600px]" + overflowClassName="overflow-y-auto" + items={filteredObjects} + estimateSize={() => 58} + render={(migrationObject) => ( + <MigrationObjectDetailsCard + migrationObject={migrationObject} + isTimelocked={isTimelocked} + /> + )} + /> + )} + </div> + </div> + </div> + </Panel> + </div> + ); +} + +function LoadingPanel() { + return ( + <div className="flex h-full max-h-full w-full flex-col overflow-hidden"> + {new Array(10).fill(0).map((_, index) => ( + <Card key={index}> + <CardImage shape={ImageShape.SquareRounded}> + <div className="h-10 w-10 animate-pulse bg-neutral-90 dark:bg-neutral-12" /> + <Skeleton widthClass="w-10" heightClass="h-10" isRounded={false} /> + </CardImage> + <div className="flex flex-col gap-y-xs"> + <Skeleton widthClass="w-40" heightClass="h-3.5" /> + <Skeleton widthClass="w-32" heightClass="h-3" hasSecondaryColors /> + </div> + <div className="ml-auto flex flex-col gap-y-xs"> + <Skeleton widthClass="w-20" heightClass="h-3.5" /> + <Skeleton widthClass="w-16" heightClass="h-3" hasSecondaryColors /> + </div> + </Card> + ))} + </div> + ); +} diff --git a/apps/wallet-dashboard/components/migration/index.ts b/apps/wallet-dashboard/components/migration/index.ts new file mode 100644 index 00000000000..cf43709989c --- /dev/null +++ b/apps/wallet-dashboard/components/migration/index.ts @@ -0,0 +1,4 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export * from './MigrationObjectsPanel'; diff --git a/apps/wallet-dashboard/components/migration/migration-object-details-card/MigrationObjectDetailsCard.tsx b/apps/wallet-dashboard/components/migration/migration-object-details-card/MigrationObjectDetailsCard.tsx new file mode 100644 index 00000000000..599e58dbd21 --- /dev/null +++ b/apps/wallet-dashboard/components/migration/migration-object-details-card/MigrationObjectDetailsCard.tsx @@ -0,0 +1,155 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { ExternalImage } from '@/components'; +import { useGetCurrentEpochStartTimestamp } from '@/hooks'; +import { useGetCurrentEpochEndTimestamp } from '@/hooks/useGetCurrentEpochEndTimestamp'; +import { MIGRATION_OBJECT_WITHOUT_UC_KEY } from '@/lib/constants'; +import { CommonMigrationObjectType } from '@/lib/enums'; +import { ResolvedObjectTypes } from '@/lib/types'; +import { Card, CardBody, CardImage, ImageShape, LabelText, LabelTextSize } from '@iota/apps-ui-kit'; +import { MILLISECONDS_PER_SECOND, TimeUnit, useFormatCoin, useTimeAgo } from '@iota/core'; +import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; +import { Assets, DataStack, IotaLogoMark } from '@iota/ui-icons'; +import { useState } from 'react'; + +interface MigrationObjectDetailsCardProps { + migrationObject: ResolvedObjectTypes; + isTimelocked: boolean; +} +export function MigrationObjectDetailsCard({ + migrationObject: { unlockConditionTimestamp, ...migrationObject }, + isTimelocked: isTimelocked, +}: MigrationObjectDetailsCardProps) { + const coinType = 'coinType' in migrationObject ? migrationObject.coinType : IOTA_TYPE_ARG; + const [balance, token] = useFormatCoin(migrationObject.balance, coinType); + + switch (migrationObject.commonObjectType) { + case CommonMigrationObjectType.Basic: + return ( + <MigrationObjectCard + title={`${balance} ${token}`} + subtitle="IOTA Tokens" + unlockConditionTimestamp={unlockConditionTimestamp} + image={<IotaLogoMark />} + isTimelocked={isTimelocked} + /> + ); + case CommonMigrationObjectType.Nft: + return ( + <MigrationObjectCard + title={migrationObject.name} + subtitle="Visual Assets" + unlockConditionTimestamp={unlockConditionTimestamp} + image={ + <ExternalImageWithFallback + src={migrationObject.image_url} + alt={migrationObject.name} + fallback={<Assets />} + /> + } + isTimelocked={isTimelocked} + /> + ); + case CommonMigrationObjectType.NativeToken: + return ( + <MigrationObjectCard + isTimelocked={isTimelocked} + title={`${balance} ${token}`} + subtitle="Native Tokens" + unlockConditionTimestamp={unlockConditionTimestamp} + image={<DataStack />} + /> + ); + default: + return null; + } +} + +interface ExternalImageWithFallbackProps { + src: string; + alt: string; + fallback: React.ReactNode; +} +function ExternalImageWithFallback({ src, alt, fallback }: ExternalImageWithFallbackProps) { + const [errored, setErrored] = useState(false); + function handleError() { + setErrored(true); + } + return !errored ? <ExternalImage src={src} alt={alt} onError={handleError} /> : fallback; +} + +interface MigrationObjectCardProps { + title: string; + subtitle: string; + unlockConditionTimestamp: string; + isTimelocked: boolean; + image?: React.ReactNode; +} + +function MigrationObjectCard({ + title, + subtitle, + unlockConditionTimestamp, + isTimelocked, + image, +}: MigrationObjectCardProps) { + const hasUnlockConditionTimestamp = + unlockConditionTimestamp !== MIGRATION_OBJECT_WITHOUT_UC_KEY; + return ( + <Card> + <CardImage shape={ImageShape.SquareRounded}>{image}</CardImage> + <CardBody title={title} subtitle={subtitle} /> + {hasUnlockConditionTimestamp && ( + <UnlockConditionLabel + groupKey={unlockConditionTimestamp} + isTimelocked={isTimelocked} + /> + )} + </Card> + ); +} + +interface UnlockConditionLabelProps { + groupKey: string; + isTimelocked: boolean; +} +function UnlockConditionLabel({ groupKey, isTimelocked: isTimelocked }: UnlockConditionLabelProps) { + const { data: currentEpochStartTimestampMs, isLoading: isLoadingEpochStart } = + useGetCurrentEpochStartTimestamp(); + const { data: currentEpochEndTimestampMs, isLoading: isLoadingEpochEnd } = + useGetCurrentEpochEndTimestamp(); + + const epochEndMs = currentEpochEndTimestampMs ?? 0; + const epochStartMs = currentEpochStartTimestampMs ?? '0'; + const currentDateMs = Date.now(); + + const unlockConditionTimestampMs = parseInt(groupKey) * MILLISECONDS_PER_SECOND; + const isFromPreviousEpoch = + !isLoadingEpochStart && unlockConditionTimestampMs < parseInt(epochStartMs); + // TODO: https://github.com/iotaledger/iota/issues/4369 + const isInAFutureEpoch = !isLoadingEpochEnd && unlockConditionTimestampMs > epochEndMs; + + const outputTimestampMs = isInAFutureEpoch ? unlockConditionTimestampMs : epochEndMs; + + const timeLabel = useTimeAgo({ + timeFrom: outputTimestampMs, + shortedTimeLabel: true, + shouldEnd: true, + maxTimeUnit: TimeUnit.ONE_DAY, + }); + + const showLabel = !isFromPreviousEpoch && outputTimestampMs > currentDateMs; + + return ( + <div className="ml-auto h-full whitespace-nowrap"> + {showLabel && ( + <LabelText + size={LabelTextSize.Small} + text={timeLabel} + label={isTimelocked ? 'Unlocks in' : 'Expires in'} + /> + )} + </div> + ); +} diff --git a/apps/wallet-dashboard/components/migration/migration-object-details-card/index.ts b/apps/wallet-dashboard/components/migration/migration-object-details-card/index.ts new file mode 100644 index 00000000000..d7097a997c2 --- /dev/null +++ b/apps/wallet-dashboard/components/migration/migration-object-details-card/index.ts @@ -0,0 +1,4 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export * from './MigrationObjectDetailsCard'; diff --git a/apps/wallet-dashboard/hooks/index.ts b/apps/wallet-dashboard/hooks/index.ts index 77ea2304aa4..932b903fdba 100644 --- a/apps/wallet-dashboard/hooks/index.ts +++ b/apps/wallet-dashboard/hooks/index.ts @@ -11,3 +11,4 @@ export * from './useGetCurrentEpochStartTimestamp'; export * from './useTimelockedUnstakeTransaction'; export * from './useExplorerLinkGetter'; export * from './useGetStardustMigratableObjects'; +export * from './useGroupedMigrationObjectsByExpirationDate'; diff --git a/apps/wallet-dashboard/hooks/useGetCurrentEpochEndTimestamp.ts b/apps/wallet-dashboard/hooks/useGetCurrentEpochEndTimestamp.ts new file mode 100644 index 00000000000..69217c4becf --- /dev/null +++ b/apps/wallet-dashboard/hooks/useGetCurrentEpochEndTimestamp.ts @@ -0,0 +1,21 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { useIotaClient } from '@iota/dapp-kit'; +import { useQuery } from '@tanstack/react-query'; + +export function useGetCurrentEpochEndTimestamp() { + const client = useIotaClient(); + return useQuery({ + // eslint-disable-next-line @tanstack/query/exhaustive-deps + queryKey: ['current-epoch-end-timestamp'], + queryFn: async () => { + const iotaSystemState = await client.getLatestIotaSystemState(); + const epochStart = parseInt(iotaSystemState.epochStartTimestampMs); + const epochDuration = parseInt(iotaSystemState.epochDurationMs); + const epochEnd = epochStart + epochDuration; + return epochEnd; + }, + staleTime: 10 * 60 * 1000, // 10 minutes + }); +} diff --git a/apps/wallet-dashboard/hooks/useGetStardustMigratableObjects.ts b/apps/wallet-dashboard/hooks/useGetStardustMigratableObjects.ts index 7a5b40ce140..8480e9d9e2a 100644 --- a/apps/wallet-dashboard/hooks/useGetStardustMigratableObjects.ts +++ b/apps/wallet-dashboard/hooks/useGetStardustMigratableObjects.ts @@ -1,21 +1,17 @@ // Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +import { useQuery } from '@tanstack/react-query'; import { useGetCurrentEpochStartTimestamp } from '@/hooks'; import { groupStardustObjectsByMigrationStatus } from '@/lib/utils'; import { STARDUST_BASIC_OUTPUT_TYPE, STARDUST_NFT_OUTPUT_TYPE, + TimeUnit, useGetAllOwnedObjects, } from '@iota/core'; -import { IotaObjectData } from '@iota/iota-sdk/client'; -export function useGetStardustMigratableObjects(address: string): { - migratableBasicOutputs: IotaObjectData[]; - unmigratableBasicOutputs: IotaObjectData[]; - migratableNftOutputs: IotaObjectData[]; - unmigratableNftOutputs: IotaObjectData[]; -} { +export function useGetStardustMigratableObjects(address: string) { const { data: currentEpochMs } = useGetCurrentEpochStartTimestamp(); const { data: basicOutputObjects } = useGetAllOwnedObjects(address, { StructType: STARDUST_BASIC_OUTPUT_TYPE, @@ -24,24 +20,41 @@ export function useGetStardustMigratableObjects(address: string): { StructType: STARDUST_NFT_OUTPUT_TYPE, }); - const { migratable: migratableBasicOutputs, unmigratable: unmigratableBasicOutputs } = - groupStardustObjectsByMigrationStatus( - basicOutputObjects ?? [], - Number(currentEpochMs), + return useQuery({ + queryKey: [ + 'stardust-migratable-objects', address, - ); + currentEpochMs, + basicOutputObjects, + nftOutputObjects, + ], + queryFn: () => { + const epochMs = Number(currentEpochMs) || 0; - const { migratable: migratableNftOutputs, unmigratable: unmigratableNftOutputs } = - groupStardustObjectsByMigrationStatus( - nftOutputObjects ?? [], - Number(currentEpochMs), - address, - ); + const { migratable: migratableBasicOutputs, unmigratable: unmigratableBasicOutputs } = + groupStardustObjectsByMigrationStatus(basicOutputObjects ?? [], epochMs, address); + + const { migratable: migratableNftOutputs, unmigratable: unmigratableNftOutputs } = + groupStardustObjectsByMigrationStatus(nftOutputObjects ?? [], epochMs, address); - return { - migratableBasicOutputs, - unmigratableBasicOutputs, - migratableNftOutputs, - unmigratableNftOutputs, - }; + return { + migratableBasicOutputs, + unmigratableBasicOutputs, + migratableNftOutputs, + unmigratableNftOutputs, + }; + }, + enabled: + !!address && + currentEpochMs !== undefined && + basicOutputObjects !== undefined && + nftOutputObjects !== undefined, + staleTime: TimeUnit.ONE_SECOND * TimeUnit.ONE_MINUTE * 5, + placeholderData: { + migratableBasicOutputs: [], + unmigratableBasicOutputs: [], + migratableNftOutputs: [], + unmigratableNftOutputs: [], + }, + }); } diff --git a/apps/wallet-dashboard/hooks/useGroupedMigrationObjectsByExpirationDate.ts b/apps/wallet-dashboard/hooks/useGroupedMigrationObjectsByExpirationDate.ts new file mode 100644 index 00000000000..d9d96816fd2 --- /dev/null +++ b/apps/wallet-dashboard/hooks/useGroupedMigrationObjectsByExpirationDate.ts @@ -0,0 +1,59 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { ResolvedObjectTypes } from '@/lib/types'; +import { + groupMigrationObjectsByUnlockCondition, + sortStardustResolvedObjectsByExpiration, +} from '@/lib/utils'; +import { TimeUnit } from '@iota/core'; +import { useCurrentAccount, useIotaClient } from '@iota/dapp-kit'; +import { IotaObjectData } from '@iota/iota-sdk/client'; +import { useQuery } from '@tanstack/react-query'; +import { useGetCurrentEpochStartTimestamp } from './useGetCurrentEpochStartTimestamp'; +import { useGetCurrentEpochEndTimestamp } from './useGetCurrentEpochEndTimestamp'; + +export function useGroupedMigrationObjectsByExpirationDate( + objects: IotaObjectData[], + isTimelockUnlockCondition: boolean = false, +) { + const client = useIotaClient(); + const address = useCurrentAccount()?.address; + + const { data: currentEpochStartTimestampMs } = useGetCurrentEpochStartTimestamp(); + const { data: currentEpochEndTimestampMs } = useGetCurrentEpochEndTimestamp(); + + const epochStartMs = currentEpochStartTimestampMs ? parseInt(currentEpochStartTimestampMs) : 0; + const epochEndMs = currentEpochEndTimestampMs ? currentEpochEndTimestampMs : 0; + + return useQuery({ + // eslint-disable-next-line @tanstack/query/exhaustive-deps + queryKey: [ + 'grouped-migration-objects', + objects, + address, + isTimelockUnlockCondition, + epochStartMs, + epochEndMs, + ], + queryFn: async (): Promise<ResolvedObjectTypes[]> => { + if (!client || objects.length === 0) { + return []; + } + const resolvedObjects = await groupMigrationObjectsByUnlockCondition( + objects, + client, + address, + isTimelockUnlockCondition, + ); + + return sortStardustResolvedObjectsByExpiration( + resolvedObjects, + epochStartMs, + epochEndMs, + ); + }, + enabled: !!client && objects.length > 0, + staleTime: TimeUnit.ONE_SECOND * TimeUnit.ONE_MINUTE * 5, + }); +} diff --git a/apps/wallet-dashboard/lib/constants/index.ts b/apps/wallet-dashboard/lib/constants/index.ts index b2c6ab5f6cd..30680459cef 100644 --- a/apps/wallet-dashboard/lib/constants/index.ts +++ b/apps/wallet-dashboard/lib/constants/index.ts @@ -2,3 +2,4 @@ // SPDX-License-Identifier: Apache-2.0 export * from './vesting.constants'; +export * from './migration.constants'; diff --git a/apps/wallet-dashboard/lib/constants/migration.constants.ts b/apps/wallet-dashboard/lib/constants/migration.constants.ts new file mode 100644 index 00000000000..5aa2c5a5c0f --- /dev/null +++ b/apps/wallet-dashboard/lib/constants/migration.constants.ts @@ -0,0 +1,15 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { StardustOutputDetailsFilter } from '../enums'; + +export const STARDUST_MIGRATABLE_OBJECTS_FILTER_LIST: StardustOutputDetailsFilter[] = Object.values( + StardustOutputDetailsFilter, +); + +export const STARDUST_UNMIGRATABLE_OBJECTS_FILTER_LIST: StardustOutputDetailsFilter[] = + Object.values(StardustOutputDetailsFilter).filter( + (element) => element !== StardustOutputDetailsFilter.WithExpiration, + ); + +export const MIGRATION_OBJECT_WITHOUT_UC_KEY = 'no-unlock-condition-timestamp'; diff --git a/apps/wallet-dashboard/lib/enums/commonMigrationObjectType.enums.ts b/apps/wallet-dashboard/lib/enums/commonMigrationObjectType.enums.ts new file mode 100644 index 00000000000..9395fca36b8 --- /dev/null +++ b/apps/wallet-dashboard/lib/enums/commonMigrationObjectType.enums.ts @@ -0,0 +1,8 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export enum CommonMigrationObjectType { + NativeToken = 'nativeToken', + Nft = 'nft', + Basic = 'basic', +} diff --git a/apps/wallet-dashboard/lib/enums/index.ts b/apps/wallet-dashboard/lib/enums/index.ts index 87f3b0e2f22..6d936d1ec45 100644 --- a/apps/wallet-dashboard/lib/enums/index.ts +++ b/apps/wallet-dashboard/lib/enums/index.ts @@ -3,3 +3,6 @@ export * from './protectedRouteTitle.enum'; export * from './assetCategory.enum'; +export * from './commonMigrationObjectType.enums'; +export * from './stardustOutputDetailsFilter.enum'; +export * from './stardustOutputMigrationStatus.enum'; diff --git a/apps/wallet-dashboard/lib/enums/stardustOutputDetailsFilter.enum.ts b/apps/wallet-dashboard/lib/enums/stardustOutputDetailsFilter.enum.ts new file mode 100644 index 00000000000..f1ff813072c --- /dev/null +++ b/apps/wallet-dashboard/lib/enums/stardustOutputDetailsFilter.enum.ts @@ -0,0 +1,10 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export enum StardustOutputDetailsFilter { + All = 'All', + IOTA = 'IOTA', + NativeTokens = 'Native Tokens', + VisualAssets = 'Visual Assets', + WithExpiration = 'With Expiration', +} diff --git a/apps/wallet-dashboard/lib/enums/stardustOutputMigrationStatus.enum.ts b/apps/wallet-dashboard/lib/enums/stardustOutputMigrationStatus.enum.ts new file mode 100644 index 00000000000..29df88def12 --- /dev/null +++ b/apps/wallet-dashboard/lib/enums/stardustOutputMigrationStatus.enum.ts @@ -0,0 +1,7 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export enum StardustOutputMigrationStatus { + Migratable = 'Migratable', + TimeLocked = 'TimeLocked', +} diff --git a/apps/wallet-dashboard/lib/types/index.ts b/apps/wallet-dashboard/lib/types/index.ts new file mode 100644 index 00000000000..cdec0f4219f --- /dev/null +++ b/apps/wallet-dashboard/lib/types/index.ts @@ -0,0 +1,4 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export * from './stardustMigrationObjects'; diff --git a/apps/wallet-dashboard/lib/types/stardustMigrationObjects.ts b/apps/wallet-dashboard/lib/types/stardustMigrationObjects.ts new file mode 100644 index 00000000000..516cc7e2908 --- /dev/null +++ b/apps/wallet-dashboard/lib/types/stardustMigrationObjects.ts @@ -0,0 +1,33 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { IotaObjectData } from '@iota/iota-sdk/client'; +import { CommonMigrationObjectType } from '../enums'; + +export type UnlockConditionTimestamp = string; + +interface CommonExpirationTypeObject { + unlockConditionTimestamp: UnlockConditionTimestamp; + output: IotaObjectData; + uniqueId: string; + balance: bigint; +} + +export interface ResolvedNativeToken extends CommonExpirationTypeObject { + name: string; + commonObjectType: CommonMigrationObjectType.NativeToken; + coinType: string; +} + +export interface ResolvedBasicObject extends CommonExpirationTypeObject { + type: string; + commonObjectType: CommonMigrationObjectType.Basic; +} + +export interface ResolvedNftObject extends CommonExpirationTypeObject { + name: string; + image_url: string; + commonObjectType: CommonMigrationObjectType.Nft; +} + +export type ResolvedObjectTypes = ResolvedBasicObject | ResolvedNftObject | ResolvedNativeToken; diff --git a/apps/wallet-dashboard/lib/utils/migration/filterMigrationObjectDetails.ts b/apps/wallet-dashboard/lib/utils/migration/filterMigrationObjectDetails.ts new file mode 100644 index 00000000000..3f9d54de6c8 --- /dev/null +++ b/apps/wallet-dashboard/lib/utils/migration/filterMigrationObjectDetails.ts @@ -0,0 +1,37 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { MIGRATION_OBJECT_WITHOUT_UC_KEY } from '@/lib/constants'; +import { CommonMigrationObjectType, StardustOutputDetailsFilter } from '@/lib/enums'; +import { ResolvedObjectTypes } from '@/lib/types'; + +export function filterMigrationObjects( + objects: ResolvedObjectTypes[], + filter: StardustOutputDetailsFilter, +) { + switch (filter) { + case StardustOutputDetailsFilter.All: + return objects; + case StardustOutputDetailsFilter.IOTA: + return filterObjectByCommonOutputType(objects, CommonMigrationObjectType.Basic); + case StardustOutputDetailsFilter.VisualAssets: + return filterObjectByCommonOutputType(objects, CommonMigrationObjectType.Nft); + case StardustOutputDetailsFilter.NativeTokens: + return filterObjectByCommonOutputType(objects, CommonMigrationObjectType.NativeToken); + case StardustOutputDetailsFilter.WithExpiration: + return filterObjectsByExpiration(objects); + } +} + +function filterObjectByCommonOutputType( + objects: ResolvedObjectTypes[], + type: CommonMigrationObjectType, +) { + return objects.filter((object) => object.commonObjectType === type); +} + +function filterObjectsByExpiration(objects: ResolvedObjectTypes[]): ResolvedObjectTypes[] { + return objects.filter( + (object) => object.unlockConditionTimestamp !== MIGRATION_OBJECT_WITHOUT_UC_KEY, + ); +} diff --git a/apps/wallet-dashboard/lib/utils/migration/groupMigrationObjects.ts b/apps/wallet-dashboard/lib/utils/migration/groupMigrationObjects.ts new file mode 100644 index 00000000000..98badabacdd --- /dev/null +++ b/apps/wallet-dashboard/lib/utils/migration/groupMigrationObjects.ts @@ -0,0 +1,232 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { CommonMigrationObjectType } from '@/lib/enums'; +import { + ResolvedBasicObject, + ResolvedNativeToken, + ResolvedNftObject, + ResolvedObjectTypes, + UnlockConditionTimestamp, +} from '@/lib/types'; +import { + extractObjectTypeStruct, + getNativeTokensFromBag, + MILLISECONDS_PER_SECOND, + STARDUST_BASIC_OUTPUT_TYPE, + STARDUST_NFT_OUTPUT_TYPE, +} from '@iota/core'; +import { extractMigrationOutputFields, extractStorageDepositReturnAmount } from '.'; +import { IotaClient, IotaObjectData } from '@iota/iota-sdk/client'; +import { MIGRATION_OBJECT_WITHOUT_UC_KEY } from '@/lib/constants'; + +export async function groupMigrationObjectsByUnlockCondition( + objectsData: IotaObjectData[], + client: IotaClient, + currentAddress: string = '', + isTimelockUnlockCondition: boolean = false, +): Promise<ResolvedObjectTypes[]> { + const flatObjects: ResolvedObjectTypes[] = []; + const basicObjectMap: Map<string, ResolvedBasicObject> = new Map(); + const nativeTokenMap: Map<string, Map<string, ResolvedNativeToken>> = new Map(); + + const PROMISE_CHUNK_SIZE = 100; + + // Get output data in chunks of 100 + for (let i = 0; i < objectsData.length; i += PROMISE_CHUNK_SIZE) { + const chunk = objectsData.slice(i, i + PROMISE_CHUNK_SIZE); + + const promises = chunk.map(async (object) => { + const objectFields = extractMigrationOutputFields(object); + + let groupKey: string | undefined; + if (isTimelockUnlockCondition) { + const timestamp = objectFields.timelock_uc?.fields.unix_time.toString(); + groupKey = timestamp; + } else { + const timestamp = objectFields.expiration_uc?.fields.unix_time.toString(); + // Timestamp can be undefined if the object was timelocked and is now unlocked + // and it doesn't have an expiration unlock condition + groupKey = timestamp ?? MIGRATION_OBJECT_WITHOUT_UC_KEY; + } + + if (!groupKey) { + return; + } + + if (object.type === STARDUST_BASIC_OUTPUT_TYPE) { + const existing = basicObjectMap.get(groupKey); + const gasReturn = extractStorageDepositReturnAmount(objectFields, currentAddress); + const newBalance = + (existing ? existing.balance : 0n) + + BigInt(objectFields.balance) + + (gasReturn ?? 0n); + + if (existing) { + existing.balance = newBalance; + } else { + const newBasicObject: ResolvedBasicObject = { + balance: newBalance, + unlockConditionTimestamp: groupKey, + type: object.type, + commonObjectType: CommonMigrationObjectType.Basic, + output: object, + uniqueId: objectFields.id.id, + }; + basicObjectMap.set(groupKey, newBasicObject); + flatObjects.push(newBasicObject); + } + } else if (object.type === STARDUST_NFT_OUTPUT_TYPE) { + const nftDetails = await getNftDetails(object, groupKey, client); + flatObjects.push(...nftDetails); + } + + if (!nativeTokenMap.has(groupKey)) { + nativeTokenMap.set(groupKey, new Map()); + } + + const tokenGroup = nativeTokenMap.get(groupKey)!; + const objectNativeTokens = await extractNativeTokensFromObject( + object, + client, + groupKey, + ); + + for (const token of objectNativeTokens) { + const existing = tokenGroup.get(token.name); + + if (existing) { + existing.balance += token.balance; + } else { + tokenGroup.set(token.name, token); + flatObjects.push(token); + } + } + }); + + // Wait for all promises in the chunk to resolve + await Promise.all(promises); + } + + return flatObjects; +} + +export function sortStardustResolvedObjectsByExpiration( + objects: ResolvedObjectTypes[], + currentEpochStartMs: number, + currentEpochEndMs: number, +): ResolvedObjectTypes[] { + const currentTimestampMs = Date.now(); + + return objects.sort((a, b) => { + const aIsNoExpiration = a.unlockConditionTimestamp === MIGRATION_OBJECT_WITHOUT_UC_KEY; + const bIsNoExpiration = b.unlockConditionTimestamp === MIGRATION_OBJECT_WITHOUT_UC_KEY; + + // No-expiration objects should be last + if (aIsNoExpiration && bIsNoExpiration) return 0; + if (aIsNoExpiration) return 1; + if (bIsNoExpiration) return -1; + + const aTimestampMs = parseInt(a.unlockConditionTimestamp) * MILLISECONDS_PER_SECOND; + const bTimestampMs = parseInt(b.unlockConditionTimestamp) * MILLISECONDS_PER_SECOND; + + const aIsFromPreviousEpoch = aTimestampMs < currentEpochStartMs; + const bIsFromPreviousEpoch = bTimestampMs < currentEpochStartMs; + + // Objects from a past epoch should be last (but before no-expiration objects) + if (aIsFromPreviousEpoch && bIsFromPreviousEpoch) return 0; + if (aIsFromPreviousEpoch) return 1; + if (bIsFromPreviousEpoch) return -1; + + const aIsInFutureEpoch = aTimestampMs > currentEpochEndMs; + const bIsInFutureEpoch = bTimestampMs > currentEpochEndMs; + + const aOutputTimestampMs = aIsInFutureEpoch ? aTimestampMs : currentEpochEndMs; + const bOutputTimestampMs = bIsInFutureEpoch ? bTimestampMs : currentEpochEndMs; + + // Objects closer to the calculated `outputTimestampMs` should be first + const aProximity = Math.abs(aOutputTimestampMs - currentTimestampMs); + const bProximity = Math.abs(bOutputTimestampMs - currentTimestampMs); + + return aProximity - bProximity; + }); +} + +async function getNftDetails( + object: IotaObjectData, + expirationKey: UnlockConditionTimestamp, + client: IotaClient, +): Promise<ResolvedNftObject[]> { + const objectFields = extractMigrationOutputFields(object); + const nftOutputDynamicFields = await client.getDynamicFields({ + parentId: objectFields.id.id, + }); + + const nftDetails: ResolvedNftObject[] = []; + for (const nft of nftOutputDynamicFields.data) { + const nftObject = await client.getObject({ + id: nft.objectId, + options: { showDisplay: true }, + }); + + if (!nftObject?.data?.display?.data) { + continue; + } + + nftDetails.push({ + balance: BigInt(objectFields.balance), + name: nftObject.data.display.data.name ?? '', + image_url: nftObject.data.display.data.image_url ?? '', + commonObjectType: CommonMigrationObjectType.Nft, + unlockConditionTimestamp: expirationKey, + output: object, + uniqueId: nftObject.data.objectId, + }); + } + + return nftDetails; +} + +async function extractNativeTokensFromObject( + object: IotaObjectData, + client: IotaClient, + expirationKey: UnlockConditionTimestamp, +): Promise<ResolvedNativeToken[]> { + const fields = extractMigrationOutputFields(object); + const bagId = fields.native_tokens.fields.id.id; + const bagSize = Number(fields.native_tokens.fields.size); + + const nativeTokens = bagSize > 0 ? await getNativeTokensFromBag(bagId, client) : []; + const result: ResolvedNativeToken[] = []; + + for (const nativeToken of nativeTokens) { + const nativeTokenParentId = fields.native_tokens.fields.id.id; + const objectDynamic = await client.getDynamicFieldObject({ + parentId: nativeTokenParentId, + name: nativeToken.name, + }); + + if (objectDynamic?.data?.content && 'fields' in objectDynamic.data.content) { + const nativeTokenFields = objectDynamic.data.content.fields as { + name: string; + value: string; + id: { id: string }; + }; + const tokenStruct = extractObjectTypeStruct(nativeTokenFields.name); + const tokenName = tokenStruct[2]; + const balance = BigInt(nativeTokenFields.value); + + result.push({ + name: tokenName, + balance, + coinType: nativeTokenFields.name, + unlockConditionTimestamp: expirationKey, + commonObjectType: CommonMigrationObjectType.NativeToken, + output: object, + uniqueId: nativeTokenFields.id.id, + }); + } + } + + return result; +} diff --git a/apps/wallet-dashboard/lib/utils/migration.ts b/apps/wallet-dashboard/lib/utils/migration/groupStardustObjectsByMigrationStatus.ts similarity index 53% rename from apps/wallet-dashboard/lib/utils/migration.ts rename to apps/wallet-dashboard/lib/utils/migration/groupStardustObjectsByMigrationStatus.ts index ee129d4d211..c7aa8f0e784 100644 --- a/apps/wallet-dashboard/lib/utils/migration.ts +++ b/apps/wallet-dashboard/lib/utils/migration/groupStardustObjectsByMigrationStatus.ts @@ -1,7 +1,7 @@ // Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -import { CommonOutputObjectWithUc } from '@iota/core'; +import { CommonOutputObjectWithUc, MILLISECONDS_PER_SECOND } from '@iota/core'; import { IotaObjectData } from '@iota/iota-sdk/client'; export type StardustMigrationGroupedObjects = { @@ -11,16 +11,16 @@ export type StardustMigrationGroupedObjects = { export function groupStardustObjectsByMigrationStatus( stardustOutputObjects: IotaObjectData[], - epochTimestamp: number, + epochTimestampMs: number, address: string, ): StardustMigrationGroupedObjects { const migratable: IotaObjectData[] = []; const unmigratable: IotaObjectData[] = []; - const epochUnix = epochTimestamp / 1000; + const epochUnix = epochTimestampMs / MILLISECONDS_PER_SECOND; for (const outputObject of stardustOutputObjects) { - const outputObjectFields = extractOutputFields(outputObject); + const outputObjectFields = extractMigrationOutputFields(outputObject); if (outputObjectFields.expiration_uc) { const unlockableAddress = @@ -33,6 +33,7 @@ export function groupStardustObjectsByMigrationStatus( continue; } } + if ( outputObjectFields.timelock_uc && outputObjectFields.timelock_uc.fields.unix_time > epochUnix @@ -50,49 +51,76 @@ export function groupStardustObjectsByMigrationStatus( interface MigratableObjectsData { totalNativeTokens: number; totalVisualAssets: number; - accumulatedIotaAmount: number; + totalIotaAmount: bigint; +} + +interface SummarizeMigrationObjectParams { + basicOutputs: IotaObjectData[] | undefined; + nftOutputs: IotaObjectData[] | undefined; + address: string; } export function summarizeMigratableObjectValues({ - migratableBasicOutputs, - migratableNftOutputs, + basicOutputs = [], + nftOutputs = [], address, -}: { - migratableBasicOutputs: IotaObjectData[]; - migratableNftOutputs: IotaObjectData[]; - address: string; -}): MigratableObjectsData { +}: SummarizeMigrationObjectParams): MigratableObjectsData { let totalNativeTokens = 0; - let totalIotaAmount = 0; + let totalIotaAmount: bigint = 0n; - const totalVisualAssets = migratableNftOutputs.length; - const outputObjects = [...migratableBasicOutputs, ...migratableNftOutputs]; + const totalVisualAssets = nftOutputs.length; + const outputObjects = [...basicOutputs, ...nftOutputs]; for (const output of outputObjects) { - const outputObjectFields = extractOutputFields(output); + const outputObjectFields = extractMigrationOutputFields(output); - totalIotaAmount += parseInt(outputObjectFields.balance); + totalIotaAmount += BigInt(outputObjectFields.balance); totalNativeTokens += parseInt(outputObjectFields.native_tokens.fields.size); - totalIotaAmount += extractStorageDepositReturnAmount(outputObjectFields, address) || 0; + totalIotaAmount += extractStorageDepositReturnAmount(outputObjectFields, address) || 0n; + } + + return { totalNativeTokens, totalVisualAssets, totalIotaAmount }; +} + +interface UnmmigratableObjectsData { + totalUnmigratableObjects: number; +} + +export function summarizeUnmigratableObjectValues({ + basicOutputs = [], + nftOutputs = [], +}: Omit<SummarizeMigrationObjectParams, 'address'>): UnmmigratableObjectsData { + const basicObjects = basicOutputs.length; + const nftObjects = nftOutputs.length; + let nativeTokens = 0; + + for (const output of [...basicOutputs, ...nftOutputs]) { + const outputObjectFields = extractMigrationOutputFields(output); + + nativeTokens += parseInt(outputObjectFields.native_tokens.fields.size); } - return { totalNativeTokens, totalVisualAssets, accumulatedIotaAmount: totalIotaAmount }; + const totalUnmigratableObjects = basicObjects + nativeTokens + nftObjects; + + return { totalUnmigratableObjects }; } -function extractStorageDepositReturnAmount( +export function extractStorageDepositReturnAmount( { storage_deposit_return_uc }: CommonOutputObjectWithUc, address: string, -): number | null { +): bigint | null { if ( storage_deposit_return_uc?.fields && storage_deposit_return_uc?.fields.return_address === address ) { - return parseInt(storage_deposit_return_uc?.fields.return_amount); + return BigInt(storage_deposit_return_uc?.fields.return_amount); } return null; } -function extractOutputFields(outputObject: IotaObjectData): CommonOutputObjectWithUc { +export function extractMigrationOutputFields( + outputObject: IotaObjectData, +): CommonOutputObjectWithUc { return ( outputObject.content as unknown as { fields: CommonOutputObjectWithUc; diff --git a/apps/wallet-dashboard/lib/utils/migration/index.ts b/apps/wallet-dashboard/lib/utils/migration/index.ts new file mode 100644 index 00000000000..8dbde02f32c --- /dev/null +++ b/apps/wallet-dashboard/lib/utils/migration/index.ts @@ -0,0 +1,6 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export * from './filterMigrationObjectDetails'; +export * from './groupMigrationObjects'; +export * from './groupStardustObjectsByMigrationStatus'; From 73868d85c63a985daf2c51580a9841f2b419e4c7 Mon Sep 17 00:00:00 2001 From: vivekjain23 <165671934+vivekjain23@users.noreply.github.com> Date: Tue, 17 Dec 2024 12:13:49 +0530 Subject: [PATCH 04/14] fix sidebar highlights (#4467) * fix sidebar highlights --- docs/site/src/components/API/api-ref/refnav.js | 1 - docs/site/src/css/custom.css | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/site/src/components/API/api-ref/refnav.js b/docs/site/src/components/API/api-ref/refnav.js index e88b41d0233..f594067ece1 100644 --- a/docs/site/src/components/API/api-ref/refnav.js +++ b/docs/site/src/components/API/api-ref/refnav.js @@ -44,7 +44,6 @@ const RefNav = (props) => { className={`menu__link font-medium block hover:no-underline text-base ${page === method.name && 'menu__link--active'}`} key={`link-${method.name.toLowerCase()}`} href={`#${method.name.toLowerCase()}`} - data-theme="dark" onClick={() => setPage(method.name)} > {method.name} diff --git a/docs/site/src/css/custom.css b/docs/site/src/css/custom.css index 85816995775..eac62e74432 100644 --- a/docs/site/src/css/custom.css +++ b/docs/site/src/css/custom.css @@ -135,14 +135,14 @@ html[data-theme="dark"] { [data-theme="dark"] .menu__link--active { font-weight: bold; - color: white; + color: #3b82f6; } @media (min-width: 997px) { [data-theme="light"] .menu__link:hover, [data-theme="light"] .menu__link--active{ font-weight: bold; - color: var(--ifm-menu-color) + color: #3b82f6 } } @media (max-width: 996px) { @@ -154,7 +154,7 @@ html[data-theme="dark"] { [data-theme="light"] .menu__list-item-collapsible--active, [data-theme="light"] .menu__link--active { font-weight: bold; - color: white; + color: #3b82f6; } [data-theme="light"] .menu__list-item-collapsible:hover, From 2d61a5545a209a6623503ac21640bee068a4064a Mon Sep 17 00:00:00 2001 From: DaughterOfMars <chloedaughterofmars@gmail.com> Date: Tue, 17 Dec 2024 03:51:58 -0500 Subject: [PATCH 05/14] chore(CI): Refactor and re-enable simulator nightly (#4430) * chore(CI): Refactor and re-enable simulator nightly * change default ref * Combine nightly workflows --------- Co-authored-by: Thibault Martinez <thibault@iota.org> --- .github/workflows/_rust_tests.yml | 4 + .github/workflows/nightly.yml | 30 ++++ .github/workflows/simulator_nightly.yml | 178 ------------------------ 3 files changed, 34 insertions(+), 178 deletions(-) delete mode 100644 .github/workflows/simulator_nightly.yml diff --git a/.github/workflows/_rust_tests.yml b/.github/workflows/_rust_tests.yml index 75a96614c06..9aeccdffe2d 100644 --- a/.github/workflows/_rust_tests.yml +++ b/.github/workflows/_rust_tests.yml @@ -6,6 +6,9 @@ on: changedCrates: type: string required: false + runSimtest: + type: boolean + default: true concurrency: group: rust-tests-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -118,6 +121,7 @@ jobs: simtest: name: Simtest rust + if: inputs.runSimtest timeout-minutes: 45 runs-on: [self-hosted] env: diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 27268340ad9..3e02cfc233f 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -4,6 +4,17 @@ on: schedule: - cron: "0 0 * * *" # every day at midnight workflow_dispatch: + inputs: + iota_ref: + description: "Branch / commit to simtest" + type: string + required: true + default: develop + test_num: + description: "MSIM_TEST_NUM (test iterations)" + type: string + required: false + default: "30" env: BINARY_LIST_FILE: "./binary-build-list.json" @@ -27,6 +38,8 @@ env: RUSTUP_MAX_RETRIES: 10 # Don't emit giant backtraces in the CI logs. RUST_BACKTRACE: short + IOTA_REF: "${{ github.event.inputs.iota_ref || 'develop' }}" + TEST_NUM: "${{ github.event.inputs.test_num || '30' }}" jobs: release: @@ -61,6 +74,9 @@ jobs: tests: uses: ./.github/workflows/_rust_tests.yml + with: + # simtest job below runs a superset of these tests + runSimtest: false external-tests: uses: ./.github/workflows/_external_rust_tests.yml @@ -84,3 +100,17 @@ jobs: split-cluster: uses: ./.github/workflows/split_cluster.yml + + simtest: + timeout-minutes: 240 + runs-on: [self-hosted] + + steps: + - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + with: + ref: ${{ env.IOTA_REF }} + - uses: taiki-e/install-action@375e0c7f08a66b8c2ba7e7eef31a6f91043a81b0 # v2.44.38 + with: + tool: nextest + - name: Run simtest + run: scripts/simtest/simtest-run.sh diff --git a/.github/workflows/simulator_nightly.yml b/.github/workflows/simulator_nightly.yml deleted file mode 100644 index 234a9013788..00000000000 --- a/.github/workflows/simulator_nightly.yml +++ /dev/null @@ -1,178 +0,0 @@ -name: Simulator Tests - -on: - schedule: - - cron: "0 9 * * *" # UTC timing is every day at 1am PST - workflow_dispatch: - inputs: - iota_ref: - description: "Branch / commit to test" - type: string - required: true - default: main - test_num: - description: "MSIM_TEST_NUM (test iterations)" - type: string - required: false - default: "30" - -concurrency: - group: ${{ github.workflow }} - -env: - IOTA_REF: "${{ github.event.inputs.iota_ref || 'main' }}" - TEST_NUM: "${{ github.event.inputs.test_num || '30' }}" - -jobs: - simtest: - timeout-minutes: 240 - permissions: - # The "id-token: write" permission is required or Machine ID will not be - # able to authenticate with the cluster. - id-token: write - contents: read - runs-on: self-hosted - - steps: - - name: Install Teleport - uses: teleport-actions/setup@176c25dfcd19cd31a252f275d579822b243e7b9c # v1.0.6 - with: - version: 11.3.1 - - name: Authorize against Teleport - id: auth - uses: teleport-actions/auth@685adaf480dc79262a99220eb158a92136d5abd9 # v2.0.3 - with: - # Specify the publically accessible address of your Teleport proxy. - proxy: proxy.iota-int.com:443 - # Specify the name of the join token for your bot. - token: iota-simtest-token - # Specify the length of time that the generated credentials should be - # valid for. This is optional and defaults to "1h" - certificate-ttl: 2h - - # Cargo clean and git restore on any left over files from git checkout, and deletes all remote tracking branches - - name: Environment clean - run: | - tsh -i ${{ steps.auth.outputs.identity-file }} --ttl 5 ssh ubuntu@simtest-01 "source ~/.bashrc && source ~/.cargo/env && rm -rf ~/iota" - tsh -i ${{ steps.auth.outputs.identity-file }} --ttl 5 ssh ubuntu@simtest-01 "source ~/.bashrc && source ~/.cargo/env && cd ~/ && git clone git@github.com:iotaledger/iota.git" - - # Deleting files in tmpfs that usually fill up pretty quickly after each run. Cargo clean to free up space as well. - - name: Tmpfs and cargo clean - run: | - tsh -i ${{ steps.auth.outputs.identity-file }} --ttl 5 ssh ubuntu@simtest-01 "sudo rm -rf /tmp/*" - tsh -i ${{ steps.auth.outputs.identity-file }} --ttl 5 ssh ubuntu@simtest-01 "source ~/.bashrc && source ~/.cargo/env && cd ~/iota && cargo clean" - - # Checkout out the latest iota repo - - name: Checkout iota repo - run: | - tsh -i ${{ steps.auth.outputs.identity-file }} --ttl 10 ssh ubuntu@simtest-01 "source ~/.bashrc && source ~/.cargo/env && cd ~/iota && git fetch origin && git checkout ${{ env.IOTA_REF }}" - - # Setting up cargo and simtest - - name: Install simtest - run: | - tsh -i ${{ steps.auth.outputs.identity-file }} --ttl 10 ssh ubuntu@simtest-01 "source ~/.bashrc && source ~/.cargo/env && cd ~/iota && ./scripts/simtest/install.sh" - - # Run simulator tests - - name: Run simtest - run: | - tsh -i ${{ steps.auth.outputs.identity-file }} --ttl 120 ssh ubuntu@simtest-01 "source ~/.bashrc && source ~/.cargo/env && cd ~/iota && RUSTUP_MAX_RETRIES=10 CARGO_TERM_COLOR=always CARGO_INCREMENTAL=0 CARGO_NET_RETRY=10 RUST_BACKTRACE=short RUST_LOG=off NUM_CPUS=24 TEST_NUM=${{ env.TEST_NUM }} ./scripts/simtest/simtest-run.sh" - - notify: - name: Notify - needs: [simtest] - runs-on: self-hosted - if: github.event_name == 'schedule' && failure() - - steps: - - uses: technote-space/workflow-conclusion-action@45ce8e0eb155657ab8ccf346ade734257fd196a5 # v3.0.3 - - - name: Checkout iota repo develop branch - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 - - - name: Get iota commit - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - export iota_sha=$(git rev-parse HEAD) - echo "iota_sha=${iota_sha}" >> $GITHUB_ENV - - - name: Get link to logs - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh_job_link=$(gh api -X GET 'repos/iotaledger/iota/actions/runs/${{ github.run_id }}/jobs' --jq '.jobs.[0].html_url') - echo "gh_job_link=${gh_job_link}" >> $GITHUB_ENV - - - name: Get current oncall - run: | - export current_oncall=$(curl -s --request GET \ - --url 'https://api.pagerduty.com/oncalls?schedule_ids[]=PGCQ3YS' \ - --header 'Accept: application/json' \ - --header 'Authorization: Token token=${{ secrets.PAGERDUTY_ACCESS_KEY }}' \ - --header 'Content-Type: application/json' \ - | jq '.oncalls[].user.summary' | tr -d '"') - echo "current_oncall=$(echo ${current_oncall})" >> $GITHUB_ENV - - export oncall_name=$(curl -s --request GET \ - --url 'https://api.pagerduty.com/oncalls?schedule_ids[]=PGCQ3YS' \ - --header 'Accept: application/json' \ - --header 'Authorization: Token token=${{ secrets.PAGERDUTY_ACCESS_KEY }}' \ - --header 'Content-Type: application/json' \ - | jq '.oncalls[].escalation_policy.summary' | tr -d '"') - echo "oncall_name=$(echo ${oncall_name})" >> $GITHUB_ENV - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: us-west-2 - - - name: Get slack id for the oncall - run: | - export slack_id=$(aws s3 cp s3://iota-employees-dir/employees.json - | jq --arg ONCALL "${{ env.current_oncall }}" '.[] | if .name == $ONCALL then .slack_id else empty end') - echo "slack_id=$(echo ${slack_id} | tr -d '"')" >> $GITHUB_ENV - - - name: Post to slack - uses: slackapi/slack-github-action@37ebaef184d7626c5f204ab8d3baff4262dd30f0 # v1.27.0 - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - IOTA_SHA: ${{ env.iota_sha }} - GH_JOB_LINK: ${{ env.gh_job_link }} - SLACK_ID: ${{ env.slack_id }} - ONCALL_NAME: ${{ env.oncall_name }} - with: - channel-id: "simtest-nightly" - payload: | - { - "text": "*${{ github.workflow }}* workflow status: `${{ env.WORKFLOW_CONCLUSION }}`", - "blocks": [ - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "*${{ github.workflow }}* workflow status: `${{ env.WORKFLOW_CONCLUSION }}`" - } - }, - { - "type": "divider" - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "IOTA commit: <https://github.com/iotaledger/iota/commit/${{ env.IOTA_SHA }}|${{ env.IOTA_SHA }}> \nRun: <${{ env.GH_JOB_LINK }}|${{ github.run_id }}>" - } - }, - { - "type": "divider" - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "<@${{ env.SLACK_ID }}>, current `${{ env.ONCALL_NAME }}` oncall, please debug failures: `tsh ssh ubuntu@simtest-01` and look in the `/home/ubuntu/simtest_logs/{date}` folder for test results" - } - } - ] - } From 3ab420c0afe2bc6ef96a0bad3a2b22a86a10cffd Mon Sep 17 00:00:00 2001 From: Panteleymonchuk <panteleymonchuk@gmail.com> Date: Tue, 17 Dec 2024 11:29:52 +0200 Subject: [PATCH 06/14] feat(wallet-dashboard): Add tx details state to the end of send coin flow (#4422) * feat(wallet-dashboard): implement SentSuccess view and update SendTokenDialog flow * feat(dashboard): enhance SendTokenDialog flow and improve transaction handling * feat(dashboard): rename SentSuccessView to TransactionDetailsView and update flow * fix(dashboard): improve error message for transaction info retrieval * feat(dashboard): add loading state with spinner during transaction fetching * feat(dashboard): implement transfer transaction mutation and refactor handling logic * refactor(explorer, core): move useRecognizedPackages from explorer to core. * feat(dashboard): integrate useRecognizedPackages for transaction details * fix(dashboard): correct import path for useTransferTransaction * remove with dialog content * refactor: format --------- Co-authored-by: marc2332 <mespinsanz@gmail.com> --- apps/core/src/hooks/index.ts | 1 + .../src/hooks/useRecognizedPackages.ts | 11 +- .../src/components/owned-coins/OwnedCoins.tsx | 9 +- apps/explorer/src/hooks/index.ts | 1 - apps/explorer/src/hooks/useResolveVideo.ts | 8 +- .../transaction-result/TransactionData.tsx | 8 +- .../transaction-result/TransactionView.tsx | 9 +- .../transaction-summary/index.tsx | 10 +- .../Dialogs/SendToken/SendTokenDialog.tsx | 105 ++++----- .../SendToken/views/EnterValuesFormView.tsx | 203 ++++++++++-------- .../SendToken/views/ReviewValuesFormView.tsx | 129 +++++------ .../views/TransactionDetailsView.tsx | 47 ++++ .../Dialogs/SendToken/views/index.ts | 1 + .../transaction/TransactionDetailsLayout.tsx | 58 +++++ .../components/Dialogs/transaction/index.ts | 4 + .../transactions/TransactionTile.tsx | 71 +----- apps/wallet-dashboard/hooks/index.ts | 1 + .../hooks/useTransferTransaction.ts | 24 +++ 18 files changed, 402 insertions(+), 298 deletions(-) rename apps/{explorer => core}/src/hooks/useRecognizedPackages.ts (61%) create mode 100644 apps/wallet-dashboard/components/Dialogs/SendToken/views/TransactionDetailsView.tsx create mode 100644 apps/wallet-dashboard/components/Dialogs/transaction/TransactionDetailsLayout.tsx create mode 100644 apps/wallet-dashboard/components/Dialogs/transaction/index.ts create mode 100644 apps/wallet-dashboard/hooks/useTransferTransaction.ts diff --git a/apps/core/src/hooks/index.ts b/apps/core/src/hooks/index.ts index 89aced3f57f..1602541e57b 100644 --- a/apps/core/src/hooks/index.ts +++ b/apps/core/src/hooks/index.ts @@ -47,5 +47,6 @@ export * from './useOwnedNFT'; export * from './useNftDetails'; export * from './useCountdownByTimestamp'; export * from './useStakeRewardStatus'; +export * from './useRecognizedPackages'; export * from './stake'; diff --git a/apps/explorer/src/hooks/useRecognizedPackages.ts b/apps/core/src/hooks/useRecognizedPackages.ts similarity index 61% rename from apps/explorer/src/hooks/useRecognizedPackages.ts rename to apps/core/src/hooks/useRecognizedPackages.ts index 811c2abfdf4..15a62c80447 100644 --- a/apps/explorer/src/hooks/useRecognizedPackages.ts +++ b/apps/core/src/hooks/useRecognizedPackages.ts @@ -2,18 +2,11 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -import { Feature } from '@iota/core'; import { useFeatureValue } from '@growthbook/growthbook-react'; -import { IOTA_FRAMEWORK_ADDRESS, IOTA_SYSTEM_ADDRESS } from '@iota/iota-sdk/utils'; import { Network } from '@iota/iota-sdk/client'; +import { Feature, DEFAULT_RECOGNIZED_PACKAGES } from '../../'; -import { useNetwork } from './'; - -const DEFAULT_RECOGNIZED_PACKAGES = [IOTA_FRAMEWORK_ADDRESS, IOTA_SYSTEM_ADDRESS]; - -export function useRecognizedPackages(): string[] { - const [network] = useNetwork(); - +export function useRecognizedPackages(network: Network): string[] { const recognizedPackages = useFeatureValue( Feature.RecognizedPackages, DEFAULT_RECOGNIZED_PACKAGES, diff --git a/apps/explorer/src/components/owned-coins/OwnedCoins.tsx b/apps/explorer/src/components/owned-coins/OwnedCoins.tsx index 8df810f8f0c..619fd8e9864 100644 --- a/apps/explorer/src/components/owned-coins/OwnedCoins.tsx +++ b/apps/explorer/src/components/owned-coins/OwnedCoins.tsx @@ -2,14 +2,14 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -import { getCoinSymbol } from '@iota/core'; +import { getCoinSymbol, useRecognizedPackages } from '@iota/core'; import { useIotaClientQuery } from '@iota/dapp-kit'; -import { type CoinBalance } from '@iota/iota-sdk/client'; +import { type CoinBalance, type Network } from '@iota/iota-sdk/client'; +import { useNetwork } from '~/hooks'; import { normalizeIotaAddress } from '@iota/iota-sdk/utils'; import { FilterList, Warning } from '@iota/ui-icons'; import { useMemo, useState } from 'react'; import OwnedCoinView from './OwnedCoinView'; -import { useRecognizedPackages } from '~/hooks/useRecognizedPackages'; import { Button, ButtonType, @@ -47,7 +47,8 @@ export function OwnedCoins({ id }: OwnerCoinsProps): JSX.Element { const { isPending, data, isError } = useIotaClientQuery('getAllBalances', { owner: normalizeIotaAddress(id), }); - const recognizedPackages = useRecognizedPackages(); + const [network] = useNetwork(); + const recognizedPackages = useRecognizedPackages(network as Network); const balances: Record<CoinFilter, CoinBalanceVerified[]> = useMemo(() => { const balanceData = data?.reduce( diff --git a/apps/explorer/src/hooks/index.ts b/apps/explorer/src/hooks/index.ts index 9fbe82e3302..a52c31b12d6 100644 --- a/apps/explorer/src/hooks/index.ts +++ b/apps/explorer/src/hooks/index.ts @@ -17,7 +17,6 @@ export * from './useInitialPageView'; export * from './useMediaQuery'; export * from './useNetwork'; export * from './useNormalizedMoveModule'; -export * from './useRecognizedPackages'; export * from './useResolveVideo'; export * from './useSearch'; export * from './useVerifiedSourceCode'; diff --git a/apps/explorer/src/hooks/useResolveVideo.ts b/apps/explorer/src/hooks/useResolveVideo.ts index 19d7c871d23..a40622340a3 100644 --- a/apps/explorer/src/hooks/useResolveVideo.ts +++ b/apps/explorer/src/hooks/useResolveVideo.ts @@ -2,12 +2,14 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -import { type IotaObjectResponse } from '@iota/iota-sdk/client'; +import { type IotaObjectResponse, type Network } from '@iota/iota-sdk/client'; -import { useRecognizedPackages } from './useRecognizedPackages'; +import { useRecognizedPackages } from '@iota/core'; +import { useNetwork } from '~/hooks'; export function useResolveVideo(object: IotaObjectResponse): string | undefined | null { - const recognizedPackages = useRecognizedPackages(); + const [network] = useNetwork(); + const recognizedPackages = useRecognizedPackages(network as Network); const objectType = (object.data?.type ?? object?.data?.content?.dataType === 'package') ? 'package' diff --git a/apps/explorer/src/pages/transaction-result/TransactionData.tsx b/apps/explorer/src/pages/transaction-result/TransactionData.tsx index de3d78e5890..17617d7363a 100644 --- a/apps/explorer/src/pages/transaction-result/TransactionData.tsx +++ b/apps/explorer/src/pages/transaction-result/TransactionData.tsx @@ -2,13 +2,14 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -import { useTransactionSummary } from '@iota/core'; +import { useTransactionSummary, useRecognizedPackages } from '@iota/core'; import { type ProgrammableTransaction, type IotaTransactionBlockResponse, + type Network, } from '@iota/iota-sdk/client'; import { GasBreakdown } from '~/components'; -import { useRecognizedPackages } from '~/hooks/useRecognizedPackages'; +import { useNetwork } from '~/hooks/useNetwork'; import { InputsCard } from '~/pages/transaction-result/programmable-transaction-view/InputsCard'; import { TransactionsCard } from '~/pages/transaction-result/programmable-transaction-view/TransactionsCard'; @@ -17,7 +18,8 @@ interface TransactionDataProps { } export function TransactionData({ transaction }: TransactionDataProps): JSX.Element { - const recognizedPackagesList = useRecognizedPackages(); + const [network] = useNetwork(); + const recognizedPackagesList = useRecognizedPackages(network as Network); const summary = useTransactionSummary({ transaction, recognizedPackagesList, diff --git a/apps/explorer/src/pages/transaction-result/TransactionView.tsx b/apps/explorer/src/pages/transaction-result/TransactionView.tsx index 06b5f3d6c15..73af5407edf 100644 --- a/apps/explorer/src/pages/transaction-result/TransactionView.tsx +++ b/apps/explorer/src/pages/transaction-result/TransactionView.tsx @@ -2,7 +2,7 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -import { type IotaTransactionBlockResponse } from '@iota/iota-sdk/client'; +import { type Network, type IotaTransactionBlockResponse } from '@iota/iota-sdk/client'; import clsx from 'clsx'; import { useState } from 'react'; import { ErrorBoundary, SplitPanes } from '~/components'; @@ -11,8 +11,8 @@ import { TransactionData } from '~/pages/transaction-result/TransactionData'; import { TransactionSummary } from '~/pages/transaction-result/transaction-summary'; import { Signatures } from './Signatures'; import { TransactionDetails } from './transaction-summary/TransactionDetails'; -import { useTransactionSummary } from '@iota/core'; -import { useBreakpoint, useRecognizedPackages } from '~/hooks'; +import { useTransactionSummary, useRecognizedPackages } from '@iota/core'; +import { useBreakpoint, useNetwork } from '~/hooks'; import { ButtonSegment, ButtonSegmentType, @@ -42,7 +42,8 @@ export function TransactionView({ transaction }: TransactionViewProps): JSX.Elem const transactionKindName = transaction.transaction?.data.transaction?.kind; const isProgrammableTransaction = transactionKindName === 'ProgrammableTransaction'; - const recognizedPackagesList = useRecognizedPackages(); + const [network] = useNetwork(); + const recognizedPackagesList = useRecognizedPackages(network as Network); const summary = useTransactionSummary({ transaction, recognizedPackagesList, diff --git a/apps/explorer/src/pages/transaction-result/transaction-summary/index.tsx b/apps/explorer/src/pages/transaction-result/transaction-summary/index.tsx index 7ea356fbcb2..ea5d48cbab6 100644 --- a/apps/explorer/src/pages/transaction-result/transaction-summary/index.tsx +++ b/apps/explorer/src/pages/transaction-result/transaction-summary/index.tsx @@ -2,20 +2,20 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -import { useTransactionSummary } from '@iota/core'; -import { type IotaTransactionBlockResponse } from '@iota/iota-sdk/client'; - +import { useTransactionSummary, useRecognizedPackages } from '@iota/core'; +import { type IotaTransactionBlockResponse, type Network } from '@iota/iota-sdk/client'; import { BalanceChanges } from './BalanceChanges'; import { ObjectChanges } from './ObjectChanges'; import { UpgradedSystemPackages } from './UpgradedSystemPackages'; -import { useRecognizedPackages } from '~/hooks/useRecognizedPackages'; +import { useNetwork } from '~/hooks'; interface TransactionSummaryProps { transaction: IotaTransactionBlockResponse; } export function TransactionSummary({ transaction }: TransactionSummaryProps): JSX.Element { - const recognizedPackagesList = useRecognizedPackages(); + const [network] = useNetwork(); + const recognizedPackagesList = useRecognizedPackages(network as Network); const summary = useTransactionSummary({ transaction, recognizedPackagesList, diff --git a/apps/wallet-dashboard/components/Dialogs/SendToken/SendTokenDialog.tsx b/apps/wallet-dashboard/components/Dialogs/SendToken/SendTokenDialog.tsx index da417f66147..913e362e27d 100644 --- a/apps/wallet-dashboard/components/Dialogs/SendToken/SendTokenDialog.tsx +++ b/apps/wallet-dashboard/components/Dialogs/SendToken/SendTokenDialog.tsx @@ -2,16 +2,16 @@ // SPDX-License-Identifier: Apache-2.0 import React, { useState } from 'react'; -import { EnterValuesFormView, ReviewValuesFormView } from './views'; +import { EnterValuesFormView, ReviewValuesFormView, TransactionDetailsView } from './views'; import { CoinBalance } from '@iota/iota-sdk/client'; import { useSendCoinTransaction, useNotifications } from '@/hooks'; -import { useSignAndExecuteTransaction } from '@iota/dapp-kit'; import { NotificationType } from '@/stores/notificationStore'; import { CoinFormat, useFormatCoin, useGetAllCoins } from '@iota/core'; -import { Dialog, DialogBody, DialogContent, DialogPosition, Header } from '@iota/apps-ui-kit'; +import { Dialog, DialogContent, DialogPosition } from '@iota/apps-ui-kit'; import { FormDataValues } from './interfaces'; import { INITIAL_VALUES } from './constants'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; +import { useTransferTransactionMutation } from '@/hooks'; interface SendCoinPopupProps { coin: CoinBalance; @@ -23,6 +23,7 @@ interface SendCoinPopupProps { enum FormStep { EnterValues, ReviewValues, + TransactionDetails, } function SendTokenDialogBody({ @@ -34,11 +35,9 @@ function SendTokenDialogBody({ const [selectedCoin, setSelectedCoin] = useState<CoinBalance>(coin); const [formData, setFormData] = useState<FormDataValues>(INITIAL_VALUES); const [fullAmount] = useFormatCoin(formData.amount, selectedCoin.coinType, CoinFormat.FULL); - const { addNotification } = useNotifications(); - const { data: coinsData } = useGetAllCoins(selectedCoin.coinType, activeAddress); - const { mutateAsync: signAndExecuteTransaction, isPending } = useSignAndExecuteTransaction(); + const { addNotification } = useNotifications(); const isPayAllIota = selectedCoin.totalBalance === formData.amount && selectedCoin.coinType === IOTA_TYPE_ARG; @@ -51,25 +50,28 @@ function SendTokenDialogBody({ isPayAllIota, ); - function handleTransfer() { + const { + mutate: transfer, + data, + isPending: isLoadingTransfer, + } = useTransferTransactionMutation(); + + async function handleTransfer() { if (!transaction) { addNotification('There was an error with the transaction', NotificationType.Error); return; - } else { - signAndExecuteTransaction({ - transaction, - }) - .then(() => { - setOpen(false); - addNotification('Transfer transaction has been sent'); - }) - .catch(handleTransactionError); } - } - function handleTransactionError() { - setOpen(false); - addNotification('There was an error with the transaction', NotificationType.Error); + transfer(transaction, { + onSuccess: () => { + setStep(FormStep.TransactionDetails); + addNotification('Transfer transaction has been sent', NotificationType.Success); + }, + onError: () => { + setOpen(false); + addNotification('Transfer transaction failed', NotificationType.Error); + }, + }); } function onNext(): void { @@ -87,40 +89,43 @@ function SendTokenDialogBody({ return ( <> - <Header - title={step === FormStep.EnterValues ? 'Send' : 'Review & Send'} - onClose={() => setOpen(false)} - onBack={step === FormStep.ReviewValues ? onBack : undefined} - /> - <div className="h-full [&>div]:h-full"> - <DialogBody> - {step === FormStep.EnterValues && ( - <EnterValuesFormView - coin={selectedCoin} - activeAddress={activeAddress} - setSelectedCoin={setSelectedCoin} - onNext={onNext} - setFormData={setFormData} - initialFormValues={formData} - /> - )} - {step === FormStep.ReviewValues && ( - <ReviewValuesFormView - formData={formData} - executeTransfer={handleTransfer} - senderAddress={activeAddress} - isPending={isPending} - coinType={selectedCoin.coinType} - isPayAllIota={isPayAllIota} - /> - )} - </DialogBody> - </div> + {step === FormStep.EnterValues && ( + <EnterValuesFormView + coin={selectedCoin} + activeAddress={activeAddress} + setSelectedCoin={setSelectedCoin} + onNext={onNext} + onClose={() => setOpen(false)} + setFormData={setFormData} + initialFormValues={formData} + /> + )} + {step === FormStep.ReviewValues && ( + <ReviewValuesFormView + formData={formData} + executeTransfer={handleTransfer} + senderAddress={activeAddress} + isPending={isLoadingTransfer} + coinType={selectedCoin.coinType} + isPayAllIota={isPayAllIota} + onClose={() => setOpen(false)} + onBack={onBack} + /> + )} + {step === FormStep.TransactionDetails && data?.digest && ( + <TransactionDetailsView + digest={data.digest} + onClose={() => { + setOpen(false); + setStep(FormStep.EnterValues); + }} + /> + )} </> ); } -export function SendTokenDialog(props: SendCoinPopupProps): React.JSX.Element { +export function SendTokenDialog(props: SendCoinPopupProps) { return ( <Dialog open={props.open} onOpenChange={props.setOpen}> <DialogContent containerId="overlay-portal-container" position={DialogPosition.Right}> diff --git a/apps/wallet-dashboard/components/Dialogs/SendToken/views/EnterValuesFormView.tsx b/apps/wallet-dashboard/components/Dialogs/SendToken/views/EnterValuesFormView.tsx index f38c0d95cfa..f33ddbc8fef 100644 --- a/apps/wallet-dashboard/components/Dialogs/SendToken/views/EnterValuesFormView.tsx +++ b/apps/wallet-dashboard/components/Dialogs/SendToken/views/EnterValuesFormView.tsx @@ -24,14 +24,16 @@ import { Button, InfoBoxStyle, LoadingIndicator, + Header, } from '@iota/apps-ui-kit'; import { useIotaClientQuery } from '@iota/dapp-kit'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; -import { Form, Formik, FormikProps } from 'formik'; +import { Form, FormikProvider, useFormik, useFormikContext } from 'formik'; import { Exclamation } from '@iota/ui-icons'; import { UseQueryResult } from '@tanstack/react-query'; import { FormDataValues } from '../interfaces'; import { INITIAL_VALUES } from '../constants'; +import { DialogLayoutBody, DialogLayoutFooter } from '../../layout'; interface EnterValuesFormProps { coin: CoinBalance; @@ -40,9 +42,10 @@ interface EnterValuesFormProps { setFormData: React.Dispatch<React.SetStateAction<FormDataValues>>; setSelectedCoin: React.Dispatch<React.SetStateAction<CoinBalance>>; onNext: () => void; + onClose: () => void; } -interface FormInputsProps extends FormikProps<FormDataValues> { +interface FormInputsProps { coinType: string; coinDecimals: number; coinBalance: bigint; @@ -52,6 +55,9 @@ interface FormInputsProps extends FormikProps<FormDataValues> { activeAddress: string; coins: CoinStruct[]; queryResult: UseQueryResult<CoinMetadata | null>; + formattedAmount: bigint; + hasEnoughBalance: boolean; + isPayAllIota: boolean; } function totalBalance(coins: CoinStruct[]): bigint { @@ -62,29 +68,18 @@ function getBalanceFromCoinStruct(coin: CoinStruct): bigint { } function FormInputs({ - isValid, - isSubmitting, - setFieldValue, - values, - submitForm, - coinType, coinDecimals, coinBalance, - iotaBalance, formattedTokenBalance, symbol, activeAddress, coins, queryResult, + formattedAmount, + hasEnoughBalance, + isPayAllIota, }: FormInputsProps): React.JSX.Element { - const formattedAmount = parseAmount(values.amount, coinDecimals); - const isPayAllIota = formattedAmount === coinBalance && coinType === IOTA_TYPE_ARG; - - const hasEnoughBalance = - isPayAllIota || - iotaBalance > - BigInt(values.gasBudgetEst ?? '0') + - (coinType === IOTA_TYPE_ARG ? formattedAmount : 0n); + const { setFieldValue, values } = useFormikContext<FormDataValues>(); async function onMaxTokenButtonClick() { await setFieldValue('amount', formattedTokenBalance); @@ -94,46 +89,31 @@ function FormInputs({ formattedAmount === coinBalance || queryResult.isPending || !coinBalance; return ( - <div className="flex h-full w-full flex-col"> - <Form autoComplete="off" noValidate className="flex-1"> - <div className="flex h-full w-full flex-col gap-md"> - {!hasEnoughBalance && ( - <InfoBox - type={InfoBoxType.Error} - supportingText="Insufficient IOTA to cover transaction" - style={InfoBoxStyle.Elevated} - icon={<Exclamation />} - /> - )} - - <SendTokenFormInput - name="amount" - to={values.to} - symbol={symbol} - coins={coins} - coinDecimals={coinDecimals} - activeAddress={activeAddress} - onActionClick={onMaxTokenButtonClick} - isMaxActionDisabled={isMaxActionDisabled} - isPayAllIota={isPayAllIota} + <Form autoComplete="off" noValidate className="flex-1"> + <div className="flex h-full w-full flex-col gap-md"> + {!hasEnoughBalance && ( + <InfoBox + type={InfoBoxType.Error} + supportingText="Insufficient IOTA to cover transaction" + style={InfoBoxStyle.Elevated} + icon={<Exclamation />} /> - <AddressInput name="to" placeholder="Enter Address" /> - </div> - </Form> + )} - <div className="pt-xs"> - <Button - onClick={submitForm} - htmlType={ButtonHtmlType.Submit} - type={ButtonType.Primary} - disabled={ - !isValid || isSubmitting || !hasEnoughBalance || values.gasBudgetEst === '' - } - text="Review" - fullWidth + <SendTokenFormInput + name="amount" + to={values.to} + symbol={symbol} + coins={coins} + coinDecimals={coinDecimals} + activeAddress={activeAddress} + onActionClick={onMaxTokenButtonClick} + isMaxActionDisabled={isMaxActionDisabled} + isPayAllIota={isPayAllIota} /> + <AddressInput name="to" placeholder="Enter Address" /> </div> - </div> + </Form> ); } @@ -144,6 +124,7 @@ export function EnterValuesFormView({ setSelectedCoin, onNext, initialFormValues, + onClose, }: EnterValuesFormProps): JSX.Element { // Get all coins of the type const { data: coinsData, isPending: coinsIsPending } = useGetAllCoins( @@ -188,13 +169,14 @@ export function EnterValuesFormView({ const formattedTokenBalance = tokenBalance.replace(/,/g, ''); - if (coinsBalanceIsPending || coinsIsPending || iotaCoinsIsPending) { - return ( - <div className="flex h-full w-full items-center justify-center"> - <LoadingIndicator /> - </div> - ); - } + const formik = useFormik({ + initialValues: initialFormValues, + validationSchema: validationSchemaStepOne, + enableReinitialize: true, + validateOnChange: false, + validateOnBlur: false, + onSubmit: handleFormSubmit, + }); async function handleFormSubmit({ to, amount, gasBudgetEst }: FormDataValues) { const formattedAmount = parseAmount(amount, coinDecimals).toString(); @@ -207,41 +189,72 @@ export function EnterValuesFormView({ onNext(); } + const coinType = coin.coinType; + const formattedAmount = parseAmount(formik.values.amount, coinDecimals); + const isPayAllIota = formattedAmount === coinBalance && coinType === IOTA_TYPE_ARG; + + const hasEnoughBalance = + isPayAllIota || + iotaBalance > + BigInt(formik.values.gasBudgetEst ?? '0') + + (coinType === IOTA_TYPE_ARG ? formattedAmount : 0n); + + if (coinsBalanceIsPending || coinsIsPending || iotaCoinsIsPending) { + return ( + <div className="flex h-full w-full items-center justify-center"> + <LoadingIndicator /> + </div> + ); + } + return ( - <div className="flex h-full w-full flex-col gap-md"> - <CoinSelector - activeCoinType={coin.coinType} - coins={coinsBalance ?? []} - onClick={(coinType) => { - setFormData(INITIAL_VALUES); - const coin = coinsBalance?.find((coin) => coin.coinType === coinType); - setSelectedCoin(coin!); - }} - /> - - <Formik - initialValues={initialFormValues} - validationSchema={validationSchemaStepOne} - enableReinitialize - validateOnChange={false} - validateOnBlur={false} - onSubmit={handleFormSubmit} - > - {(props: FormikProps<FormDataValues>) => ( - <FormInputs - {...props} - coinType={coin.coinType} - coinDecimals={coinDecimals} - coinBalance={coinBalance} - iotaBalance={iotaBalance} - formattedTokenBalance={formattedTokenBalance} - symbol={symbol} - activeAddress={activeAddress} - coins={coins ?? []} - queryResult={queryResult} - /> - )} - </Formik> - </div> + <FormikProvider value={formik}> + <Header title={'Send'} onClose={onClose} /> + <DialogLayoutBody> + <CoinSelector + activeCoinType={coin.coinType} + coins={coinsBalance ?? []} + onClick={(coinType) => { + setFormData(INITIAL_VALUES); + const selectedCoin = coinsBalance?.find( + (coinBalance) => coinBalance.coinType === coinType, + ); + if (selectedCoin) { + setSelectedCoin(selectedCoin); + } + }} + /> + + <FormInputs + hasEnoughBalance={hasEnoughBalance} + formattedAmount={formattedAmount} + isPayAllIota={isPayAllIota} + coinType={coin.coinType} + coinDecimals={coinDecimals} + coinBalance={coinBalance} + iotaBalance={iotaBalance} + formattedTokenBalance={formattedTokenBalance} + symbol={symbol} + activeAddress={activeAddress} + coins={coins ?? []} + queryResult={queryResult} + /> + </DialogLayoutBody> + <DialogLayoutFooter> + <Button + onClick={formik.submitForm} + htmlType={ButtonHtmlType.Submit} + type={ButtonType.Primary} + disabled={ + !formik.isValid || + formik.isSubmitting || + !hasEnoughBalance || + formik.values.gasBudgetEst === '' + } + text="Review" + fullWidth + /> + </DialogLayoutFooter> + </FormikProvider> ); } diff --git a/apps/wallet-dashboard/components/Dialogs/SendToken/views/ReviewValuesFormView.tsx b/apps/wallet-dashboard/components/Dialogs/SendToken/views/ReviewValuesFormView.tsx index 58d6e21e10b..d4d82d1ccad 100644 --- a/apps/wallet-dashboard/components/Dialogs/SendToken/views/ReviewValuesFormView.tsx +++ b/apps/wallet-dashboard/components/Dialogs/SendToken/views/ReviewValuesFormView.tsx @@ -16,11 +16,13 @@ import { KeyValueInfo, Divider, ButtonType, + Header, } from '@iota/apps-ui-kit'; import { formatAddress, IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; import { CoinIcon, ImageIconSize, useFormatCoin, ExplorerLinkType, CoinFormat } from '@iota/core'; import { Loader } from '@iota/ui-icons'; import { ExplorerLink } from '@/components'; +import { DialogLayoutBody, DialogLayoutFooter } from '../../layout'; interface ReviewValuesFormProps { formData: FormDataValues; @@ -29,6 +31,8 @@ interface ReviewValuesFormProps { executeTransfer: () => void; coinType: string; isPayAllIota?: boolean; + onClose: () => void; + onBack: () => void; } export function ReviewValuesFormView({ @@ -38,78 +42,75 @@ export function ReviewValuesFormView({ executeTransfer, coinType, isPayAllIota, + onClose, + onBack, }: ReviewValuesFormProps): JSX.Element { const [roundedAmount, symbol] = useFormatCoin(amount, coinType, CoinFormat.ROUNDED); const [gasEstimated, gasSymbol] = useFormatCoin(gasBudgetEst, IOTA_TYPE_ARG); return ( - <div className="flex h-full flex-col"> - <div className="flex h-full w-full flex-col gap-md"> - <div className="flex h-full flex-col justify-between"> - <div className="h-full flex-1"> - <div className="flex w-full flex-col gap-md"> - {Number(amount) !== 0 ? ( - <Card type={CardType.Filled}> - <CardImage type={ImageType.BgSolid}> - <CoinIcon - coinType={coinType} - rounded - size={ImageIconSize.Small} - /> - </CardImage> - <CardBody - title={`${isPayAllIota ? '~' : ''}${roundedAmount} ${symbol}`} - subtitle="Amount" - /> - <CardAction type={CardActionType.SupportingText} /> - </Card> - ) : null} - <div className="flex flex-col gap-md--rs p-sm--rs"> - <KeyValueInfo - keyText={'From'} - value={ - <ExplorerLink - type={ExplorerLinkType.Address} - address={senderAddress} - > - {formatAddress(senderAddress)} - </ExplorerLink> - } - fullwidth - /> + <> + <Header title="Review & Send" onClose={onClose} onBack={onBack} /> + <DialogLayoutBody> + <div className="flex w-full flex-col gap-md"> + {Number(amount) !== 0 ? ( + <Card type={CardType.Filled}> + <CardImage type={ImageType.BgSolid}> + <CoinIcon coinType={coinType} rounded size={ImageIconSize.Small} /> + </CardImage> + <CardBody + title={`${isPayAllIota ? '~' : ''}${roundedAmount} ${symbol}`} + subtitle="Amount" + /> + <CardAction type={CardActionType.SupportingText} /> + </Card> + ) : null} + <div className="flex flex-col gap-md--rs p-sm--rs"> + <KeyValueInfo + keyText={'From'} + value={ + <ExplorerLink + type={ExplorerLinkType.Address} + address={senderAddress} + > + {formatAddress(senderAddress)} + </ExplorerLink> + } + fullwidth + /> - <Divider /> - <KeyValueInfo - keyText={'To'} - value={ - <ExplorerLink type={ExplorerLinkType.Address} address={to}> - {formatAddress(to || '')} - </ExplorerLink> - } - fullwidth - /> + <Divider /> + <KeyValueInfo + keyText={'To'} + value={ + <ExplorerLink type={ExplorerLinkType.Address} address={to}> + {formatAddress(to || '')} + </ExplorerLink> + } + fullwidth + /> - <Divider /> - <KeyValueInfo - keyText={'Est. Gas Fees'} - value={gasEstimated} - supportingLabel={gasSymbol} - fullwidth - /> - </div> - </div> + <Divider /> + <KeyValueInfo + keyText={'Est. Gas Fees'} + value={gasEstimated} + supportingLabel={gasSymbol} + fullwidth + /> </div> - <Button - type={ButtonType.Primary} - onClick={executeTransfer} - text="Send Now" - disabled={coinType === null || isPending} - fullWidth - icon={isPending ? <Loader className="animate-spin" /> : undefined} - iconAfterText - /> </div> - </div> - </div> + </DialogLayoutBody> + <DialogLayoutFooter> + <Button + type={ButtonType.Primary} + onClick={executeTransfer} + text="Send Now" + disabled={coinType === null || isPending} + fullWidth + icon={isPending ? <Loader className="animate-spin" /> : undefined} + iconAfterText + /> + </DialogLayoutFooter> + </> ); } diff --git a/apps/wallet-dashboard/components/Dialogs/SendToken/views/TransactionDetailsView.tsx b/apps/wallet-dashboard/components/Dialogs/SendToken/views/TransactionDetailsView.tsx new file mode 100644 index 00000000000..f534f72e387 --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/SendToken/views/TransactionDetailsView.tsx @@ -0,0 +1,47 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { useGetTransaction } from '@iota/core'; +import { InfoBoxType, InfoBox, InfoBoxStyle } from '@iota/apps-ui-kit'; +import { Warning, Loader } from '@iota/ui-icons'; +import { getExtendedTransaction } from '@/lib/utils'; +import { useCurrentAccount } from '@iota/dapp-kit'; +import { TransactionDetailsLayout } from '../../transaction'; + +interface TransactionDetailsViewProps { + digest?: string; + onClose: () => void; +} + +export function TransactionDetailsView({ digest, onClose }: TransactionDetailsViewProps) { + const currentAccount = useCurrentAccount(); + const { data, isError, error, isFetching } = useGetTransaction(digest || ''); + + if (isError) { + return ( + <InfoBox + type={InfoBoxType.Error} + title="Error getting transaction info" + supportingText={ + error?.message ?? 'An error occurred when getting the transaction info' + } + icon={<Warning />} + style={InfoBoxStyle.Default} + /> + ); + } + + if (isFetching) { + return ( + <div className="flex h-full w-full items-center justify-center"> + <Loader className="h-6 w-6 animate-spin" /> + </div> + ); + } + + const transaction = data && getExtendedTransaction(data, currentAccount?.address || ''); + + return transaction ? ( + <TransactionDetailsLayout transaction={transaction} onClose={onClose} /> + ) : null; +} diff --git a/apps/wallet-dashboard/components/Dialogs/SendToken/views/index.ts b/apps/wallet-dashboard/components/Dialogs/SendToken/views/index.ts index bc7f7fd90e7..4938ff14337 100644 --- a/apps/wallet-dashboard/components/Dialogs/SendToken/views/index.ts +++ b/apps/wallet-dashboard/components/Dialogs/SendToken/views/index.ts @@ -3,3 +3,4 @@ export * from './EnterValuesFormView'; export * from './ReviewValuesFormView'; +export * from './TransactionDetailsView'; diff --git a/apps/wallet-dashboard/components/Dialogs/transaction/TransactionDetailsLayout.tsx b/apps/wallet-dashboard/components/Dialogs/transaction/TransactionDetailsLayout.tsx new file mode 100644 index 00000000000..44bc9474a6a --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/transaction/TransactionDetailsLayout.tsx @@ -0,0 +1,58 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 +import React from 'react'; +import { ExplorerLink } from '@/components'; +import { ExtendedTransaction } from '@/lib/interfaces'; +import { Header, LoadingIndicator } from '@iota/apps-ui-kit'; +import { + useTransactionSummary, + ViewTxnOnExplorerButton, + ExplorerLinkType, + TransactionReceipt, + useRecognizedPackages, +} from '@iota/core'; +import { useCurrentAccount, useIotaClientContext } from '@iota/dapp-kit'; +import { DialogLayoutBody, DialogLayoutFooter } from '../layout'; +import { Validator } from '../Staking/views/Validator'; +import { Network } from '@iota/iota-sdk/client'; + +interface TransactionDialogDetailsProps { + transaction: ExtendedTransaction; + onClose: () => void; +} +export function TransactionDetailsLayout({ transaction, onClose }: TransactionDialogDetailsProps) { + const address = useCurrentAccount()?.address ?? ''; + + const { network } = useIotaClientContext(); + const recognizedPackagesList = useRecognizedPackages(network as Network); + const summary = useTransactionSummary({ + transaction: transaction.raw, + currentAddress: address, + recognizedPackagesList, + }); + + if (!summary) return <LoadingIndicator />; + + return ( + <> + <Header title="Transaction" onClose={onClose} /> + <DialogLayoutBody> + <TransactionReceipt + txn={transaction.raw} + activeAddress={address} + summary={summary} + renderExplorerLink={ExplorerLink} + renderValidatorLogo={Validator} + /> + </DialogLayoutBody> + <DialogLayoutFooter> + <ExplorerLink + type={ExplorerLinkType.Transaction} + transactionID={transaction.raw.digest} + > + <ViewTxnOnExplorerButton digest={transaction.raw.digest} /> + </ExplorerLink> + </DialogLayoutFooter> + </> + ); +} diff --git a/apps/wallet-dashboard/components/Dialogs/transaction/index.ts b/apps/wallet-dashboard/components/Dialogs/transaction/index.ts new file mode 100644 index 00000000000..55a1e09a752 --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/transaction/index.ts @@ -0,0 +1,4 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export * from './TransactionDetailsLayout'; diff --git a/apps/wallet-dashboard/components/transactions/TransactionTile.tsx b/apps/wallet-dashboard/components/transactions/TransactionTile.tsx index 405a02e76c6..0c76c27ceb1 100644 --- a/apps/wallet-dashboard/components/transactions/TransactionTile.tsx +++ b/apps/wallet-dashboard/components/transactions/TransactionTile.tsx @@ -6,7 +6,6 @@ import React, { useState } from 'react'; import TransactionIcon from './TransactionIcon'; import formatTimestamp from '@/lib/utils/time'; -import { ExplorerLink } from '@/components'; import { ExtendedTransaction, TransactionState } from '@/lib/interfaces'; import { Card, @@ -18,21 +17,12 @@ import { CardAction, CardActionType, Dialog, - Header, - LoadingIndicator, } from '@iota/apps-ui-kit'; -import { - useFormatCoin, - getLabel, - useTransactionSummary, - ViewTxnOnExplorerButton, - ExplorerLinkType, - TransactionReceipt, -} from '@iota/core'; +import { useFormatCoin, getLabel, useTransactionSummary } from '@iota/core'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; import { useCurrentAccount } from '@iota/dapp-kit'; -import { DialogLayout, DialogLayoutBody, DialogLayoutFooter } from '../Dialogs/layout'; -import { Validator } from '../Dialogs/Staking/views/Validator'; +import { TransactionDetailsLayout } from '../Dialogs/transaction/TransactionDetailsLayout'; +import { DialogLayout } from '../Dialogs/layout'; interface TransactionTileProps { transaction: ExtendedTransaction; @@ -85,53 +75,14 @@ export function TransactionTile({ transaction }: TransactionTileProps): JSX.Elem } /> </Card> - <ActivityDetailsDialog transaction={transaction} open={open} setOpen={setOpen} /> - </> - ); -} - -interface ActivityDetailsDialogProps { - transaction: ExtendedTransaction; - open: boolean; - setOpen: (open: boolean) => void; -} -function ActivityDetailsDialog({ - transaction, - open, - setOpen, -}: ActivityDetailsDialogProps): React.JSX.Element { - const address = useCurrentAccount()?.address ?? ''; - - const summary = useTransactionSummary({ - transaction: transaction.raw, - currentAddress: address, - recognizedPackagesList: [], - }); - - if (!summary) return <LoadingIndicator />; - - return ( - <Dialog open={open} onOpenChange={setOpen}> - <DialogLayout> - <Header title="Transaction" onClose={() => setOpen(false)} /> - <DialogLayoutBody> - <TransactionReceipt - txn={transaction.raw} - activeAddress={address} - summary={summary} - renderExplorerLink={ExplorerLink} - renderValidatorLogo={Validator} + <Dialog open={open} onOpenChange={setOpen}> + <DialogLayout> + <TransactionDetailsLayout + transaction={transaction} + onClose={() => setOpen(false)} /> - </DialogLayoutBody> - <DialogLayoutFooter> - <ExplorerLink - type={ExplorerLinkType.Transaction} - transactionID={transaction.raw.digest} - > - <ViewTxnOnExplorerButton digest={transaction.raw.digest} /> - </ExplorerLink> - </DialogLayoutFooter> - </DialogLayout> - </Dialog> + </DialogLayout> + </Dialog> + </> ); } diff --git a/apps/wallet-dashboard/hooks/index.ts b/apps/wallet-dashboard/hooks/index.ts index 932b903fdba..f33eda9c3fc 100644 --- a/apps/wallet-dashboard/hooks/index.ts +++ b/apps/wallet-dashboard/hooks/index.ts @@ -12,3 +12,4 @@ export * from './useTimelockedUnstakeTransaction'; export * from './useExplorerLinkGetter'; export * from './useGetStardustMigratableObjects'; export * from './useGroupedMigrationObjectsByExpirationDate'; +export * from './useTransferTransaction'; diff --git a/apps/wallet-dashboard/hooks/useTransferTransaction.ts b/apps/wallet-dashboard/hooks/useTransferTransaction.ts new file mode 100644 index 00000000000..ee673368ac0 --- /dev/null +++ b/apps/wallet-dashboard/hooks/useTransferTransaction.ts @@ -0,0 +1,24 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 +import { useMutation } from '@tanstack/react-query'; +import { useIotaClient, useSignAndExecuteTransaction } from '@iota/dapp-kit'; +import { Transaction } from '@iota/iota-sdk/transactions'; + +export function useTransferTransactionMutation() { + const iotaClient = useIotaClient(); + const { mutateAsync: signAndExecuteTransaction } = useSignAndExecuteTransaction(); + + return useMutation({ + mutationFn: async (transaction: Transaction) => { + const executed = await signAndExecuteTransaction({ + transaction, + }); + + const tx = await iotaClient.waitForTransaction({ + digest: executed.digest, + }); + + return tx; + }, + }); +} From c0f46683365e52dfc106e429092afd37e86ea74b Mon Sep 17 00:00:00 2001 From: Marc Espin <mespinsanz@gmail.com> Date: Tue, 17 Dec 2024 11:27:12 +0100 Subject: [PATCH 07/14] refactor(apps-backend): Enable vesting and migration in production (#4514) --- apps/apps-backend/src/features/features.controller.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/apps-backend/src/features/features.controller.ts b/apps/apps-backend/src/features/features.controller.ts index c3947236ec5..a3f3dbbdd3f 100644 --- a/apps/apps-backend/src/features/features.controller.ts +++ b/apps/apps-backend/src/features/features.controller.ts @@ -134,10 +134,10 @@ export class FeaturesController { defaultValue: false, }, [Feature.StardustMigration]: { - defaultValue: false, + defaultValue: true, }, [Feature.SupplyIncreaseVesting]: { - defaultValue: false, + defaultValue: true, }, }, dateUpdated: new Date().toISOString(), From a3c1e5faf27ca7ff65ad1a594487c07df92e817d Mon Sep 17 00:00:00 2001 From: evavirseda <evirseda@boxfish.studio> Date: Tue, 17 Dec 2024 11:36:24 +0100 Subject: [PATCH 08/14] feat(wallet-dashboard): improve dark/light mode switcher (#4503) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: improve dark/light mode * feat: cleanup * enhancement: swap theme setting buttons positions --------- Co-authored-by: Begoña Alvarez <balvarez@boxfish.studio> --- .../src/components/buttons}/ThemeSwitcher.tsx | 3 ++- apps/core/src/components/buttons/index.ts | 1 + .../explorer/src/components/header/Header.tsx | 3 ++- apps/explorer/src/components/header/index.ts | 1 - .../(protected)/components/top-nav/TopNav.tsx | 2 ++ .../app/(protected)/layout.tsx | 20 ------------------- apps/wallet-dashboard/app/page.tsx | 7 +++++-- 7 files changed, 12 insertions(+), 25 deletions(-) rename apps/{explorer/src/components/header => core/src/components/buttons}/ThemeSwitcher.tsx (89%) diff --git a/apps/explorer/src/components/header/ThemeSwitcher.tsx b/apps/core/src/components/buttons/ThemeSwitcher.tsx similarity index 89% rename from apps/explorer/src/components/header/ThemeSwitcher.tsx rename to apps/core/src/components/buttons/ThemeSwitcher.tsx index b947cafe76c..922deb78957 100644 --- a/apps/explorer/src/components/header/ThemeSwitcher.tsx +++ b/apps/core/src/components/buttons/ThemeSwitcher.tsx @@ -3,7 +3,8 @@ import { Button, ButtonType } from '@iota/apps-ui-kit'; import { DarkMode, LightMode } from '@iota/ui-icons'; -import { useTheme, Theme, ThemePreference } from '@iota/core'; +import { Theme, ThemePreference } from '../../enums'; +import { useTheme } from '../../hooks'; export function ThemeSwitcher(): React.JSX.Element { const { theme, themePreference, setThemePreference } = useTheme(); diff --git a/apps/core/src/components/buttons/index.ts b/apps/core/src/components/buttons/index.ts index b7638e371ce..95938f61610 100644 --- a/apps/core/src/components/buttons/index.ts +++ b/apps/core/src/components/buttons/index.ts @@ -2,3 +2,4 @@ // SPDX-License-Identifier: Apache-2.0 export * from './ViewTxnOnExplorerButton'; +export * from './ThemeSwitcher'; diff --git a/apps/explorer/src/components/header/Header.tsx b/apps/explorer/src/components/header/Header.tsx index a3b0cbcb00b..a2f95b165d5 100644 --- a/apps/explorer/src/components/header/Header.tsx +++ b/apps/explorer/src/components/header/Header.tsx @@ -5,7 +5,8 @@ import { NetworkSelector } from '../network'; import Search from '../search/Search'; import { LinkWithQuery } from '~/components/ui'; -import { ThemeSwitcher, ThemedIotaLogo } from '~/components'; +import { ThemedIotaLogo } from '~/components'; +import { ThemeSwitcher } from '@iota/core'; function Header(): JSX.Element { return ( diff --git a/apps/explorer/src/components/header/index.ts b/apps/explorer/src/components/header/index.ts index b23c1fae65a..8a717a10a0b 100644 --- a/apps/explorer/src/components/header/index.ts +++ b/apps/explorer/src/components/header/index.ts @@ -2,4 +2,3 @@ // SPDX-License-Identifier: Apache-2.0 export * from './Header'; -export * from './ThemeSwitcher'; diff --git a/apps/wallet-dashboard/app/(protected)/components/top-nav/TopNav.tsx b/apps/wallet-dashboard/app/(protected)/components/top-nav/TopNav.tsx index 8dd5f01ca2b..2fe8eba32f3 100644 --- a/apps/wallet-dashboard/app/(protected)/components/top-nav/TopNav.tsx +++ b/apps/wallet-dashboard/app/(protected)/components/top-nav/TopNav.tsx @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { Badge, BadgeType, Button, ButtonType } from '@iota/apps-ui-kit'; +import { ThemeSwitcher } from '@iota/core'; import { ConnectButton } from '@iota/dapp-kit'; import { Settings } from '@iota/ui-icons'; @@ -10,6 +11,7 @@ export function TopNav() { <div className="flex w-full flex-row items-center justify-end gap-md py-xs--rs"> <Badge label="Mainnet" type={BadgeType.PrimarySoft} /> <ConnectButton size="md" /> + <ThemeSwitcher /> <Button icon={<Settings />} type={ButtonType.Ghost} /> </div> ); diff --git a/apps/wallet-dashboard/app/(protected)/layout.tsx b/apps/wallet-dashboard/app/(protected)/layout.tsx index a77c8922ab9..72fa80c67cc 100644 --- a/apps/wallet-dashboard/app/(protected)/layout.tsx +++ b/apps/wallet-dashboard/app/(protected)/layout.tsx @@ -4,21 +4,9 @@ import { Notifications } from '@/components/index'; import React, { type PropsWithChildren } from 'react'; -import { Button } from '@iota/apps-ui-kit'; import { Sidebar, TopNav } from './components'; -import { ThemePreference, useTheme } from '@iota/core'; function DashboardLayout({ children }: PropsWithChildren): JSX.Element { - const { theme, themePreference, setThemePreference } = useTheme(); - - const toggleTheme = () => { - const newTheme = - themePreference === ThemePreference.Light - ? ThemePreference.Dark - : ThemePreference.Light; - setThemePreference(newTheme); - }; - return ( <div className="min-h-full"> <div className="fixed left-0 top-0 z-50 h-full"> @@ -34,14 +22,6 @@ function DashboardLayout({ children }: PropsWithChildren): JSX.Element { <div className="flex-1 py-md--rs">{children}</div> </div> </div> - - <div className="fixed bottom-5 right-5"> - <Button - onClick={toggleTheme} - text={`${theme === 'dark' ? 'Light' : 'Dark'} mode`} - /> - </div> - <Notifications /> </div> ); diff --git a/apps/wallet-dashboard/app/page.tsx b/apps/wallet-dashboard/app/page.tsx index 8901eec400a..e3036bf38c2 100644 --- a/apps/wallet-dashboard/app/page.tsx +++ b/apps/wallet-dashboard/app/page.tsx @@ -7,7 +7,7 @@ import { ConnectButton, useCurrentWallet, useAutoConnectWallet } from '@iota/dap import { redirect } from 'next/navigation'; import { IotaLogoWeb } from '@iota/ui-icons'; import { HOMEPAGE_ROUTE } from '@/lib/constants/routes.constants'; -import { Theme, useTheme } from '@iota/core'; +import { Theme, ThemeSwitcher, useTheme } from '@iota/core'; import { LoadingIndicator } from '@iota/apps-ui-kit'; function HomeDashboardPage(): JSX.Element { @@ -44,7 +44,10 @@ function HomeDashboardPage(): JSX.Element { disableRemotePlayback ></video> </div> - <div className="flex h-full w-full flex-col items-center justify-between p-md sm:p-2xl"> + <div className="relative flex h-full w-full flex-col items-center justify-between p-md sm:p-2xl"> + <div className="absolute right-2 top-2 sm:right-8 sm:top-8"> + <ThemeSwitcher /> + </div> <IotaLogoWeb width={130} height={32} /> <div className="flex max-w-sm flex-col items-center gap-8 text-center"> <div className="flex flex-col items-center gap-4"> From d5a8e4de853fbf2dee4ff83279b974bcde5b59ea Mon Sep 17 00:00:00 2001 From: cpl121 <100352899+cpl121@users.noreply.github.com> Date: Tue, 17 Dec 2024 11:52:55 +0100 Subject: [PATCH 09/14] feat(wallet-dashboard): show tx details to unstaking flow (#4433) * feat(wallet-dashboard): implement SentSuccess view and update SendTokenDialog flow * feat: add tx details state to the end of unstaking flow * feat(dashboard): enhance SendTokenDialog flow and improve transaction handling * feat(dashboard): rename SentSuccessView to TransactionDetailsView and update flow * fix(dashboard): improve error message for transaction info retrieval * fix(dashboard): rename props interface * fix(dashboard): clean merge debris --------- Co-authored-by: Panteleymonchuk <panteleymonchuk@gmail.com> --- .../Dialogs/Staking/StakeDialog.tsx | 29 +++++++++++++++++-- .../Dialogs/Staking/views/UnstakeView.tsx | 23 +++++++-------- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/StakeDialog.tsx b/apps/wallet-dashboard/components/Dialogs/Staking/StakeDialog.tsx index 2c9f72a2911..29f832afdf6 100644 --- a/apps/wallet-dashboard/components/Dialogs/Staking/StakeDialog.tsx +++ b/apps/wallet-dashboard/components/Dialogs/Staking/StakeDialog.tsx @@ -31,6 +31,7 @@ import { DetailsView, UnstakeView } from './views'; import { FormValues } from './views/EnterAmountView'; import { TransactionDialogView } from '../TransactionDialog'; import { StakeDialogView } from './enums/view.enums'; +import { Transaction } from '@iota/iota-sdk/transactions'; const INITIAL_VALUES = { amount: '', @@ -114,7 +115,7 @@ export function StakeDialog({ groupedTimelockObjects, ); - const { mutateAsync: signAndExecuteTransaction } = useSignAndExecuteTransaction(); + const { mutateAsync: signAndExecuteTransaction, isPending } = useSignAndExecuteTransaction(); const { addNotification } = useNotifications(); const { data: rollingAverageApys } = useGetValidatorsApy(); @@ -173,6 +174,29 @@ export function StakeDialog({ ); } + function handleUnstake(transaction: Transaction): void { + if (!transaction) { + addNotification('Unstake transaction was not created', NotificationType.Error); + return; + } + signAndExecuteTransaction( + { + transaction: transaction, + }, + { + onSuccess: (tx) => { + onSuccess?.(tx.digest); + addNotification('Unstake transaction has been sent'); + setTxDigest(tx.digest); + setView?.(StakeDialogView.TransactionDetails); + }, + onError: () => { + addNotification('Unstake transaction was not sent', NotificationType.Error); + }, + }, + ); + } + function onSubmit(_: FormValues, { resetForm }: FormikHelpers<FormValues>) { handleStake(); resetForm(); @@ -225,7 +249,8 @@ export function StakeDialog({ <UnstakeView extendedStake={stakedDetails} handleClose={handleClose} - showActiveStatus + onUnstake={handleUnstake} + isPending={isPending} /> )} {view === StakeDialogView.TransactionDetails && ( diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/views/UnstakeView.tsx b/apps/wallet-dashboard/components/Dialogs/Staking/views/UnstakeView.tsx index 671184c9cea..302d1de5514 100644 --- a/apps/wallet-dashboard/components/Dialogs/Staking/views/UnstakeView.tsx +++ b/apps/wallet-dashboard/components/Dialogs/Staking/views/UnstakeView.tsx @@ -26,23 +26,26 @@ import { } from '@iota/core'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; import { useMemo } from 'react'; -import { useCurrentAccount, useSignAndExecuteTransaction } from '@iota/dapp-kit'; +import { useCurrentAccount } from '@iota/dapp-kit'; import { Loader, Warning } from '@iota/ui-icons'; import { useUnstakeTransaction } from '@/hooks'; import { ValidatorStakingData } from '@/components'; import { DialogLayout, DialogLayoutFooter, DialogLayoutBody } from '../../layout'; +import { Transaction } from '@iota/iota-sdk/transactions'; -interface UnstakeDialogProps { +interface UnstakeViewProps { extendedStake: ExtendedDelegatedStake; handleClose: () => void; - showActiveStatus?: boolean; + onUnstake: (unstakeTransaction: Transaction) => void; + isPending: boolean; } export function UnstakeView({ extendedStake, handleClose, - showActiveStatus, -}: UnstakeDialogProps): JSX.Element { + onUnstake, + isPending, +}: UnstakeViewProps): JSX.Element { const stakingReward = BigInt(extendedStake.estimatedReward ?? '').toString(); const [rewards, rewardSymbol] = useFormatCoin(stakingReward, IOTA_TYPE_ARG); const activeAddress = useCurrentAccount()?.address ?? null; @@ -67,7 +70,7 @@ export function UnstakeView({ error: delegatedStakeDataError, } = delegatedStakeDataResult; - const delegationId = extendedStake?.status === 'Active' && extendedStake?.stakedIotaId; + const delegationId = extendedStake?.stakedIotaId; const [totalIota] = useFormatCoin( BigInt(stakingReward || 0) + totalStakeOriginal, @@ -93,14 +96,10 @@ export function UnstakeView({ extendedStake.stakedIotaId, activeAddress || '', ); - const { mutateAsync: signAndExecuteTransaction, isPending } = useSignAndExecuteTransaction(); - async function handleUnstake(): Promise<void> { + function handleUnstake(): void { if (!unstakeData) return; - await signAndExecuteTransaction({ - transaction: unstakeData.transaction, - }); - handleClose(); + onUnstake(unstakeData.transaction); } const currentEpochEndTimeFormatted = From 3b6bcdcecef82f88029ca969015683726d9419a1 Mon Sep 17 00:00:00 2001 From: Lucas Tortora <85233773+lucas-tortora@users.noreply.github.com> Date: Tue, 17 Dec 2024 09:06:00 -0300 Subject: [PATCH 10/14] fix(devx): Fix links and feedback (#4453) * fix(devx): Added 2f+1 clarification * fix(devx): added link to docker-compose.yml * fix(devx) removed gas price updates * fix(devx) improve snippet * Update docs/content/_snippets/info-BST-2f1.mdx Co-authored-by: vivekjain23 <165671934+vivekjain23@users.noreply.github.com> --------- Co-authored-by: vivekjain23 <165671934+vivekjain23@users.noreply.github.com> --- docs/content/_snippets/info-BST-2f1.mdx | 10 ++++++++++ .../about-iota/iota-architecture/epochs.mdx | 3 +++ .../content/operator/iota-full-node/overview.mdx | 3 +++ nre/docker/README.md | 4 ++-- nre/validator_tasks.md | 11 ----------- nre/validator_tool.md | 16 ---------------- 6 files changed, 18 insertions(+), 29 deletions(-) create mode 100644 docs/content/_snippets/info-BST-2f1.mdx diff --git a/docs/content/_snippets/info-BST-2f1.mdx b/docs/content/_snippets/info-BST-2f1.mdx new file mode 100644 index 00000000000..7c6161c2ad8 --- /dev/null +++ b/docs/content/_snippets/info-BST-2f1.mdx @@ -0,0 +1,10 @@ +:::info + +In Byzantine Fault Tolerant (BFT) `f` represents the number of faulty validators. `2f+1` represents the minimum number of validators +needed to agree on a transaction to ensure integrity and finality, even if up to `f` validators are faulty. + +For example, if `f = 1`, this means 3 validators must confirm a transaction (a supermajority) to guarantee its +integrity, +ensuring that even if one validator is faulty, the correct decision still stands. + +::: \ No newline at end of file diff --git a/docs/content/about-iota/iota-architecture/epochs.mdx b/docs/content/about-iota/iota-architecture/epochs.mdx index e543edcc4d6..bfbbb3ade6d 100644 --- a/docs/content/about-iota/iota-architecture/epochs.mdx +++ b/docs/content/about-iota/iota-architecture/epochs.mdx @@ -1,3 +1,4 @@ +import BSTInfo from '../../_snippets/info-BST-2f1.mdx'; import Quiz from '@site/src/components/Quiz'; import {questions} from '../../../site/static/json/about-iota/iota-architecture/epochs.json'; @@ -37,6 +38,8 @@ validator set and stake distribution can be altered. ### 4. Protocol Upgrade +<BSTInfo/> + If 2f+1 validators agree, the network may upgrade to a new protocol version, which includes new features, bug fixes, and updates to the Move framework libraries. diff --git a/docs/content/operator/iota-full-node/overview.mdx b/docs/content/operator/iota-full-node/overview.mdx index cfb80e6b4f8..cdd63215d70 100644 --- a/docs/content/operator/iota-full-node/overview.mdx +++ b/docs/content/operator/iota-full-node/overview.mdx @@ -3,6 +3,7 @@ title: Overview description: Operate an IOTA Full Node to validate blockchain activities, like transactions, checkpoints, and epoch changes. --- import Quiz from '@site/src/components/Quiz'; +import BSTInfo from '../../_snippets/info-BST-2f1.mdx'; import questions from '/json/node-operators/iota-full-node/overview.json'; import WarningAdvanced from './../../_snippets/warning-advanced-instructions-node-setup.mdx' @@ -28,6 +29,8 @@ A transaction requires a few round trips to 2f+1 validators to form a transactio This synchronization process includes: +<BSTInfo/> + 1. Following 2f+1 validators and listening for newly committed transactions. 1. Making sure that 2f+1 validators recognize the transaction and that it reaches finality. 1. Executing the transaction locally and updating the local DB. diff --git a/nre/docker/README.md b/nre/docker/README.md index 640e94dabd3..bc80d87cca3 100644 --- a/nre/docker/README.md +++ b/nre/docker/README.md @@ -9,7 +9,7 @@ Tested using: 1. Confirm you have either [Docker Engine](https://docs.docker.com/engine/install/) or [Docker Desktop](https://docs.docker.com/desktop/install/linux-install/) installed, as well as [Docker Compose](https://github.com/docker/compose#linux). -2. Update [validator.yaml](../config/validator.yaml) and place it in the same directory as `docker-compose.yaml`. +2. Update [validator.yaml](../config/validator.yaml) and place it in the same directory as [`docker-compose.yaml`](https://github.com/iotaledger/iota/blob/testnet/nre/docker/docker-compose.yaml). Add the paths to your private keys to validator.yaml. If you chose to put them in `/opt/iota/key-pairs`, you can use the following example: @@ -22,7 +22,7 @@ network-key-pair: path: /opt/iota/key-pairs/network.key ``` -3. Place `genesis.blob` in the same directory as `docker-compose.yaml`. (available post genesis ceremony) +3. Place `genesis.blob` in the same directory as [`docker-compose.yaml`](https://github.com/iotaledger/iota/blob/testnet/nre/docker/docker-compose.yaml). (available post genesis ceremony) ## Connectivity diff --git a/nre/validator_tasks.md b/nre/validator_tasks.md index 06d741d4131..ce7c4c1ee43 100644 --- a/nre/validator_tasks.md +++ b/nre/validator_tasks.md @@ -27,7 +27,6 @@ This document focuses on running the Iota Node software as a Validator. - [Chain Operations](#chain-operations) - [Updating On-chain Metadata](#updating-on-chain-metadata) - [Operation Cap](#operation-cap) - - [Updating the Gas Price Survey Quote](#updating-the-gas-price-survey-quote) - [Reporting/Un-reporting Validators](#reportingun-reporting-validators) - [Joining the Validator Set](#joining-the-validator-set) - [Leaving the Validator Set](#leaving-the-validator-set) @@ -364,16 +363,6 @@ setting the holder as the active address. <!-- Will be fixed by issue 1867. --> <!-- Or go to the [explorer](https://explorer.rebased.iota.org/object/0x0000000000000000000000000000000000000005) and look for `operation_cap_id` of that validator in the `validators` module. --> -### Updating the Gas Price Survey Quote - -To update the Gas Price Survey Quote of a validator, which is used to calculate the Reference Gas Price at the end of -the epoch, the sender needs to hold a valid [`UnverifiedValidatorOperationCap`](#operation-cap). The sender could be the -validator itself, or a trusted delegatee. To do so, call `iota_system::request_set_gas_price`: - -```shell -iota client call --package 0x3 --module iota_system --function request_set_gas_price --args 0x5 {cap_object_id} {new_gas_price} --gas-budget 10000 -``` - ### Reporting/Un-reporting Validators To report a validator or undo an existing report, the sender needs to hold a valid [`UnverifiedValidatorOperationCap`](#operation-cap). The sender could be the validator itself, or a trusted delegatee. To diff --git a/nre/validator_tool.md b/nre/validator_tool.md index 3c6c3291463..2dd32ef695c 100644 --- a/nre/validator_tool.md +++ b/nre/validator_tool.md @@ -106,22 +106,6 @@ Operation Cap allows a validator to authorizer another account to perform certai The Operation Cap holder (either the validator itself or the delegatee) updates its Gas Price and reports validator peers with the Operation Cap. -#### Update Gas Price - -To update Gas Price, run - -```bash -$IOTA_BINARY validator update-gas-price <gas-price> -``` - -if the account itself is a validator and holds the Operation Cap. Or - -```bash -$IOTA_BINARY validator update-gas-price --operation-cap-id <operation-cap-id> <gas-price> -``` - -if the account is a delegatee. - #### Report Validators To report validators peers, run From f975dc719805cbd3bbb9a35400fe37badd5f18cd Mon Sep 17 00:00:00 2001 From: Lucas Tortora <85233773+lucas-tortora@users.noreply.github.com> Date: Tue, 17 Dec 2024 11:06:59 -0300 Subject: [PATCH 11/14] feat(devx): Update event docs (#4465) * fix(devx): Move access time and using events to move overview section * feat(devx) update using events guide * fix(devx) Add tabs, remove headers * fix(devx) make link absolute * fix links * Update docs/content/developer/iota-101/using-events.mdx Co-authored-by: vivekjain23 <165671934+vivekjain23@users.noreply.github.com> --------- Co-authored-by: vivekjain23 <165671934+vivekjain23@users.noreply.github.com> --- .../developer/iota-101/using-events.mdx | 156 ++++++++++++------ docs/content/sidebars/developer.js | 4 +- 2 files changed, 110 insertions(+), 50 deletions(-) diff --git a/docs/content/developer/iota-101/using-events.mdx b/docs/content/developer/iota-101/using-events.mdx index f808f9e1e07..5e6182ddc78 100644 --- a/docs/content/developer/iota-101/using-events.mdx +++ b/docs/content/developer/iota-101/using-events.mdx @@ -28,13 +28,13 @@ An event object in IOTA consists of the following attributes: - `bcs`: Binary canonical serialization value. - `timestampMs`: Unix epoch timestamp in milliseconds. -## Exploring Available Events +### Exploring Available Events -To subscribe to on-chain events, you first need to identify which events are available. While you can easily track events emitted by your own code, discovering events from external packages can be more challenging. The IOTA RPC provides the [`queryEvents`](/iota-api-ref#iotax_queryevents) method, which allows you to query on-chain packages and obtain a list of events you can subscribe to. +To [subscribe to on-chain events](#subscribing-to-events), you first need to identify which events are available. While you can easily track events emitted by your own code, discovering events from external packages can be more challenging. The IOTA RPC provides the [`queryEvents`](/iota-api-ref#iotax_queryevents) method, which allows you to query on-chain packages and obtain a list of events you can subscribe to. -## Applying Event Filters +### Applying Event Filters -When targeting specific events for querying or subscribing, you can use filters to refine your results. Although the filtering options for querying and subscribing are similar, there are notable differences to be aware of. +When targeting specific events for [querying](#querying-events) or [subscribing](#subscribing-to-events), you can use [filters](#filtering-events) to refine your results. Although the filtering options for querying and subscribing are similar, there are notable differences to be aware of. ## Emitting Events in Move @@ -49,65 +49,117 @@ use iota::event; Then, within your function, you can emit an event using the [`emit`](../../references/framework/iota-framework/event.mdx#function-emit) function. For example: -```move -/// Take coin from `DonutShop` and transfer it to tx sender. -/// Requires authorization with `ShopOwnerCap`. -public fun collect_profits( _: &ShopOwnerCap, shop: &mut DonutShop, ctx: &mut TxContext ) { - let amount = balance::value(&shop.balance); - let profits = coin::take(&mut shop.balance, amount, ctx); - // simply create new type instance and emit it. - event::emit(ProfitsCollected { amount }); - transfer::public_transfer(profits, tx_context::sender(ctx)); -} +```move file=<rootDir>/examples/trading/contracts/escrow/sources/lock.move#L42-L63 ``` -## Subscribing to Events +## Querying Events + +<Tabs> + +<TabItem value="RPC" label="IOTA RPC"> +The IOTA RPC provides a [`queryEvents`](/iota-api-ref#iotax_queryevents) method to query on-chain packages and return available events. As an example, the following `curl` command queries the Deepbook package on Mainnet for a specific type of event: + +```sh +curl -X POST https://api.testnet.iota.cafe:443 \ +-H "Content-Type: application/json" \ +-d '{ + "jsonrpc": "2.0", + "id": 1, + "method": "iotax_queryEvents", + "params": [ + { + "MoveModule": { + "package": "0x0000000000000000000000000000000000000000000000000000000000000002", + "module": "display", + "type": "0x0000…0002::display::Display<0xba68…286b::testnet_nft::TestnetNFT>" + } + }, + null, + 3, + false + ] +}' +``` + +The TypeScript SDK provides a wrapper for the `iotax_queryEvents` method: +[`client.queryEvents`](../../references/ts-sdk/api/client/classes/IotaClient#queryevents). -To react to events emitted by Move modules, you need to subscribe to them. -IOTA full nodes support event subscriptions via JSON-RPC notifications over WebSocket. You can interact with the [RPC directly][iotax_subscribeEvent](/iota-api-ref#iotax_subscribeevent), [iotax_subscribeTransaction](/iota-api-ref#iotax_subscribetransaction) or use an SDK like the [IOTA TypeScript SDK](../../references/ts-sdk/typescript/index.mdx). +</TabItem> +<TabItem value="rs" label="Rust"> -The following excerpt from one of the examples uses the TypeScript SDK to create an asynchronous subscription to the filter identified in the filter. +You can use the following as an example on how to query for events using the `query_events` function. You should update +the `PACKAGE_ID_CONST` with a package of your choice. -```move -let unsubscribe = await provider.subscribeEvent({ - filter: { <PACKAGE_ID> }, - onMessage: (event) => { - console.log("subscribeEvent", JSON.stringify(event, null, 2)) +```rust +use iota_sdk::{rpc_types::EventFilter, types::Identifier, IotaClientBuilder}; + +const PACKAGE_ID_CONST: &str = ""; + +#[tokio::main] +async fn main() -> Result<(), anyhow::Error> { + let iota_testnet = IotaClientBuilder::default() + .build("https://api.testnet.iota.cafe:443") + .await?; + + let events = iota_testnet + .event_api() + .query_events( + EventFilter::MoveModule { + package: PACKAGE_ID_CONST.parse()?, + module: Identifier::new("dev_trophy")?, + }, + None, + None, + false, + ) + .await?; + + for event in events.data { + println!("Event: {:?}", event.parsed_json); } -}); + + Ok(()) +} ``` +</TabItem> +<TabItem value="graphql" label="GraphQL"> -Move smart contracts can call other smart contracts that emit events. For example, `0x107a::nft` calls the `0x2::display::new_with_fields` smart contract and emits a `0x2::display::DisplayCreated` event. Note that using package and transaction module to query for `0x2::display` misses the following event even though it is actually an event the `0x2` package emits. The current workaround for this issue is to know all the `packageId`s you care about and search those in the `queryEvent` call. +You can use GraphQL to query events instead of JSON RPC. The following example queries are in the +[`iota-graphql-rpc` crate](https://github.com/iotaledger/iota/tree/develop/crates/iota-graphql-rpc/examples/event_connection) in the IOTA repo. -```json -{ - "id": { - "txDigest": "DrZmtQDDCUKooLzFCi29VhUB4w6AT8phCsT9d62BAf8g", - "eventSeq": "0" - }, - "packageId": "0x000000000000000000000000000000000000000000000000000000000000107a", - "transactionModule": "nft", - "sender": "0x0000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2::display::DisplayCreated<0x107a::nft::Nft>", - "parsedJson": { - "id": "0xa12d72c159d57d4c7f540b2b9e985327628d856b20c1d6cdfd3028a2a605abfe" - }, - "bcs": "CFbAeqXAwwkyTxUD36FtzTGEcMGrVj4zgcTR1G7AaRjb", - "timestampMs": "1521456213521" -} +#### Event Connection + +```graphql file=<rootDir>/crates/iota-graphql-rpc/examples/event_connection/event_connection.graphql +``` + +#### Filter Events By Sender + +```graphql file=<rootDir>/crates/iota-graphql-rpc/examples/event_connection/filter_by_sender.graphql ``` -## Examples +#### Filter Events By Emitting Package and Type -### Subscribe to Event +```graphql file=<rootDir>/crates/iota-graphql-rpc/examples/event_connection/filter_by_sender.graphql +``` + +:::tip + +The [TypeScript SDK](../../references/ts-sdk/api/graphql/classes/IotaGraphQLClient) provides functionality to +interact with the IOTA GraphQL service. + +::: + +</TabItem> +</Tabs> + + +## Subscribing to Events This example leverages the IOTA TypeScript SDK to subscribe to events the package with ID `<PACKAGE_ID>` emits. Each time the event fires, the code displays the response to the console. <Tabs> <TabItem value="rs" label="Rust"> -### Rust - See [Rust SDK](../../references/rust-sdk.mdx). ```rust @@ -132,8 +184,6 @@ async fn main() -> Result<()> { </TabItem> <TabItem value="ts" label="TypeScript"> -### TypeScript - To create the event subscription, you can use a basic Node.js app. You need the [IOTA TypeScript SDK](../../references/ts-sdk/typescript/index.mdx), so install the module using `npm install @iota/iota-sdk` at the root of your project. In your TypeScript code, import `JsonRpcProvider` and a connection from the library. ```ts @@ -199,9 +249,19 @@ subscribeEvent { </TabItem> </Tabs> +## Monitoring Events + +Firing events is not very useful in a vacuum. You also need the ability to respond to those events. +There are two methods from which to choose when you need to monitor on-chain events: +- Incorporate a [custom indexer](../advanced/custom-indexer.mdx) to take advantage of IOTA's micro-data ingestion framework. +- Poll the IOTA network on a schedule to query events. + +Using a custom indexer provides a near-real time monitoring of events, so is most useful when your project requires immediate reaction to the firing of events. Polling the network is most useful when the events you're monitoring don't fire often or the need to act on those events are not immediate. The following section provides a polling example. + + ## Filtering Events -You can filter events when querying or subscribing to receive only the events you are interested in. +You can filter events when [querying](#querying-events) or [subscribing](#subscribing-to-events) to receive only the events you are interested in. :::info diff --git a/docs/content/sidebars/developer.js b/docs/content/sidebars/developer.js index e8ac1eb1bb5..d1500f346fc 100644 --- a/docs/content/sidebars/developer.js +++ b/docs/content/sidebars/developer.js @@ -57,7 +57,6 @@ const developer = [ label: 'Typescript SDK', href: '/references/ts-sdk/typescript', }, - 'developer/iota-101/using-events', ], }, { @@ -70,6 +69,8 @@ const developer = [ 'developer/iota-101/move-overview/init', 'developer/iota-101/move-overview/visibility', 'developer/iota-101/move-overview/entry-functions', + 'developer/iota-101/using-events', + 'developer/iota-101/access-time', { type: 'category', label: 'Structs and Abilities', @@ -107,7 +108,6 @@ const developer = [ 'developer/iota-101/move-overview/patterns/id-pointer', ], }, - 'developer/iota-101/access-time', 'developer/iota-101/move-overview/conventions', ], }, From 619115c4472eabb4ce9762cfc8a025d6c4d7d5f4 Mon Sep 17 00:00:00 2001 From: JCNoguera <88061365+VmMad@users.noreply.github.com> Date: Tue, 17 Dec 2024 16:09:52 +0100 Subject: [PATCH 12/14] feat(wallet-dashboard): add unstake timelocked objects flow (#4300) * feat(dashboard): add unstake timelocked objects view * refactor: improve function * feat: add more unstaking information and rename constant * refactor: imports * fix: imports * fix: remove duplication collapsible * refactor: include both single stake and grouped in a unstake hook * refactor: unify usntake panel * fix: go back correctly to previous screen in staking * refactor: cleanup * refactor: remove popups * refactor: remove popups * revert "refactor: remove popups" * refactor: remove only unnecessary popups * refactor: divide hooks and move deeper inside components * fix: resolve re rendering issue * feat: remove redundant code * fix: update conditionally showing the stake dialog * fix(tooling-dashboard): improve stake wizard (#4454) * fix: improve stake wizzard * fix: add set view helper function * fix: add check for stake details --------- Co-authored-by: evavirseda <evirseda@boxfish.studio> * refactor: imports / exports * feat: add wait for transaction and refresh * feat: improve dialogs * feat(dashboard): minor fixes * fix: query key for timelocked staking * fix: revert constants changes * fix: disable stake button if no available amount for staking * fix: query key for timelocked staking transaction * fix: bigint serialization * fix: remove or check in the useNewStakeTimelockedTransaction --------- Co-authored-by: Bran <52735957+brancoder@users.noreply.github.com> Co-authored-by: evavirseda <evirseda@boxfish.studio> Co-authored-by: cpl121 <100352899+cpl121@users.noreply.github.com> Co-authored-by: cpl121 <cpeon@boxfish.studio> Co-authored-by: Branko <brankobosnic1@gmail.com> --- .../atoms/key-value-info/KeyValueInfo.tsx | 6 + .../loading-indicator/LoadingIndicator.tsx | 7 +- .../app/(protected)/staking/page.tsx | 80 +- .../app/(protected)/vesting/page.tsx | 387 ++++---- .../Dialogs/Staking/StakeDialog.tsx | 154 +--- .../Dialogs/Staking/enums/view.enums.ts | 1 - .../components/Dialogs/Staking/index.ts | 3 +- .../Dialogs/Staking/views/DetailsView.tsx | 6 +- .../Dialogs/Staking/views/EnterAmountView.tsx | 60 +- .../views/EnterTimelockedAmountView.tsx | 104 ++- .../Dialogs/Staking/views/UnstakeView.tsx | 201 ----- .../components/Dialogs/Staking/views/index.ts | 1 - .../components/Dialogs/TransactionDialog.tsx | 4 +- .../components/Dialogs/index.ts | 1 + .../Dialogs/unstake/UnstakeDialog.tsx | 56 ++ .../components/Dialogs/unstake/enums/index.ts | 4 + .../Dialogs/unstake/enums/views.enums.ts | 8 + .../components/Dialogs/unstake/hooks/index.ts | 4 + .../Dialogs/unstake/hooks/useUnstakeDialog.ts | 41 + .../components/Dialogs/unstake/index.ts | 8 + .../views/UnstakeTimelockedObjectsView.tsx | 213 +++++ .../Dialogs/unstake/views/UnstakeView.tsx | 167 ++++ .../components/Dialogs/unstake/views/index.ts | 5 + .../Popup/Popups/SendAssetPopup.tsx | 85 -- .../components/Popup/Popups/UnstakePopup.tsx | 49 - .../VestingPopup/TimelockedUnstakePopup.tsx | 84 -- .../Popup/Popups/VestingPopup/index.ts | 4 - .../components/Popup/Popups/index.ts | 7 - .../components/Popup/index.ts | 2 - .../components/StakeRewardsPanel.tsx | 70 ++ apps/wallet-dashboard/components/index.ts | 1 + .../staking-overview/StartStaking.tsx | 1 - .../components/staking-overview/index.ts | 1 + apps/wallet-dashboard/hooks/index.ts | 2 +- .../hooks/useNewStakeTransaction.ts | 46 +- .../hooks/useNewUnstakeTransaction.ts | 55 ++ .../hooks/useUnstakeTransaction.ts | 28 - apps/wallet-dashboard/package.json | 1 + pnpm-lock.yaml | 842 ++++++++---------- 39 files changed, 1511 insertions(+), 1288 deletions(-) delete mode 100644 apps/wallet-dashboard/components/Dialogs/Staking/views/UnstakeView.tsx create mode 100644 apps/wallet-dashboard/components/Dialogs/unstake/UnstakeDialog.tsx create mode 100644 apps/wallet-dashboard/components/Dialogs/unstake/enums/index.ts create mode 100644 apps/wallet-dashboard/components/Dialogs/unstake/enums/views.enums.ts create mode 100644 apps/wallet-dashboard/components/Dialogs/unstake/hooks/index.ts create mode 100644 apps/wallet-dashboard/components/Dialogs/unstake/hooks/useUnstakeDialog.ts create mode 100644 apps/wallet-dashboard/components/Dialogs/unstake/index.ts create mode 100644 apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeTimelockedObjectsView.tsx create mode 100644 apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeView.tsx create mode 100644 apps/wallet-dashboard/components/Dialogs/unstake/views/index.ts delete mode 100644 apps/wallet-dashboard/components/Popup/Popups/SendAssetPopup.tsx delete mode 100644 apps/wallet-dashboard/components/Popup/Popups/UnstakePopup.tsx delete mode 100644 apps/wallet-dashboard/components/Popup/Popups/VestingPopup/TimelockedUnstakePopup.tsx delete mode 100644 apps/wallet-dashboard/components/Popup/Popups/VestingPopup/index.ts delete mode 100644 apps/wallet-dashboard/components/Popup/Popups/index.ts create mode 100644 apps/wallet-dashboard/components/StakeRewardsPanel.tsx create mode 100644 apps/wallet-dashboard/hooks/useNewUnstakeTransaction.ts delete mode 100644 apps/wallet-dashboard/hooks/useUnstakeTransaction.ts diff --git a/apps/ui-kit/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx b/apps/ui-kit/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx index 569054372f2..d15da2af5de 100644 --- a/apps/ui-kit/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx +++ b/apps/ui-kit/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx @@ -57,6 +57,10 @@ interface KeyValueProps { * Reverse the KeyValue (optional). */ isReverse?: boolean; + /** + * Text shown on value hover. + */ + valueHoverTitle?: string; } export function KeyValueInfo({ @@ -72,6 +76,7 @@ export function KeyValueInfo({ onCopyError, fullwidth, isReverse = false, + valueHoverTitle, }: KeyValueProps): React.JSX.Element { const flexDirectionClass = isReverse ? 'flex-row-reverse' : 'flex-row'; async function handleCopyClick(event: React.MouseEvent<HTMLButtonElement>) { @@ -119,6 +124,7 @@ export function KeyValueInfo({ })} > <span + title={valueHoverTitle} className={cx( 'text-neutral-10 dark:text-neutral-92', size === ValueSize.Medium ? 'text-body-lg' : 'text-body-md', diff --git a/apps/ui-kit/src/lib/components/atoms/loading-indicator/LoadingIndicator.tsx b/apps/ui-kit/src/lib/components/atoms/loading-indicator/LoadingIndicator.tsx index 6a0c8d5df45..86160c55771 100644 --- a/apps/ui-kit/src/lib/components/atoms/loading-indicator/LoadingIndicator.tsx +++ b/apps/ui-kit/src/lib/components/atoms/loading-indicator/LoadingIndicator.tsx @@ -18,16 +18,21 @@ export interface LoadingIndicatorProps { * The text to display next to the loading indicator. */ text?: string; + /** + * The 'data-testid' attribute value (used in e2e tests) + */ + testId?: string; } export function LoadingIndicator({ color = 'text-primary-30 dark:text-primary-80', size = 'w-5 h-5', text, + testId, }: LoadingIndicatorProps): React.JSX.Element { return ( <div className="flex items-center justify-center gap-xs"> - <Loader className={cx('animate-spin', color, size)} /> + <Loader className={cx('animate-spin', color, size)} data-testid={testId} /> {text && <span className={cx('text-body-sm', color)}>{text}</span>} </div> ); diff --git a/apps/wallet-dashboard/app/(protected)/staking/page.tsx b/apps/wallet-dashboard/app/(protected)/staking/page.tsx index e33b1253b95..87f69eccffa 100644 --- a/apps/wallet-dashboard/app/(protected)/staking/page.tsx +++ b/apps/wallet-dashboard/app/(protected)/staking/page.tsx @@ -3,7 +3,6 @@ 'use client'; -import { StartStaking } from '@/components/staking-overview/StartStaking'; import { Button, ButtonSize, @@ -16,7 +15,15 @@ import { Title, TitleSize, } from '@iota/apps-ui-kit'; -import { StakeDialog, StakeDialogView } from '@/components'; +import { + StakeDialog, + StakeDialogView, + UnstakeDialog, + useUnstakeDialog, + UnstakeDialogView, + useStakeDialog, + StartStaking, +} from '@/components'; import { ExtendedDelegatedStake, formatDelegatedStake, @@ -32,8 +39,8 @@ import { useCurrentAccount, useIotaClient, useIotaClientQuery } from '@iota/dapp import { IotaSystemStateSummary } from '@iota/iota-sdk/client'; import { Info } from '@iota/ui-icons'; import { useMemo } from 'react'; -import { useStakeDialog } from '@/components/Dialogs/Staking/hooks/useStakeDialog'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; +import { IotaSignAndExecuteTransactionOutput } from '@iota/wallet-standard'; function StakingDashboardPage(): React.JSX.Element { const account = useCurrentAccount(); @@ -52,6 +59,14 @@ function StakingDashboardPage(): React.JSX.Element { handleCloseStakeDialog, handleNewStake, } = useStakeDialog(); + const { + isOpen: isUnstakeDialogOpen, + openUnstakeDialog, + defaultDialogProps, + handleClose: handleCloseUnstakeDialog, + setView: setUnstakeDialogView, + setTxDigest, + } = useUnstakeDialog(); const { data: delegatedStakeData, refetch: refetchDelegatedStakes } = useGetDelegatedStake({ address: account?.address || '', @@ -100,6 +115,34 @@ function StakingDashboardPage(): React.JSX.Element { .then(() => refetchDelegatedStakes()); } + function handleUnstakeClick() { + setStakeDialogView(undefined); + openUnstakeDialog(); + } + + function handleUnstakeDialogBack() { + setStakeDialogView(StakeDialogView.Details); + handleCloseUnstakeDialog(); + } + + function handleOnUnstakeBack(view: UnstakeDialogView): (() => void) | undefined { + if (view === UnstakeDialogView.Unstake) { + return handleUnstakeDialogBack; + } + } + + function handleOnUnstakeSuccess(tx: IotaSignAndExecuteTransactionOutput): void { + setUnstakeDialogView(UnstakeDialogView.TransactionDetails); + iotaClient + .waitForTransaction({ + digest: tx.digest, + }) + .then((tx) => { + refetchDelegatedStakes(); + setTxDigest(tx.digest); + }); + } + return ( <div className="flex justify-center"> <div className="w-3/4"> @@ -171,16 +214,27 @@ function StakingDashboardPage(): React.JSX.Element { </div> </div> </div> - <StakeDialog - stakedDetails={selectedStake} - onSuccess={handleOnStakeSuccess} - isOpen={isDialogStakeOpen} - handleClose={handleCloseStakeDialog} - view={stakeDialogView} - setView={setStakeDialogView} - selectedValidator={selectedValidator} - setSelectedValidator={setSelectedValidator} - /> + {isDialogStakeOpen && ( + <StakeDialog + stakedDetails={selectedStake} + onSuccess={handleOnStakeSuccess} + handleClose={handleCloseStakeDialog} + view={stakeDialogView} + setView={setStakeDialogView} + selectedValidator={selectedValidator} + setSelectedValidator={setSelectedValidator} + onUnstakeClick={handleUnstakeClick} + /> + )} + + {isUnstakeDialogOpen && selectedStake && ( + <UnstakeDialog + extendedStake={selectedStake} + onBack={handleOnUnstakeBack} + onSuccess={handleOnUnstakeSuccess} + {...defaultDialogProps} + /> + )} </Panel> ) : ( <div className="flex h-[270px] p-lg"> diff --git a/apps/wallet-dashboard/app/(protected)/vesting/page.tsx b/apps/wallet-dashboard/app/(protected)/vesting/page.tsx index b925d57e97c..2b95cf643b9 100644 --- a/apps/wallet-dashboard/app/(protected)/vesting/page.tsx +++ b/apps/wallet-dashboard/app/(protected)/vesting/page.tsx @@ -6,12 +6,14 @@ import { Banner, StakeDialog, - StakeDialogView, - TimelockedUnstakePopup, useStakeDialog, VestingScheduleDialog, + UnstakeDialog, + StakeDialogView, } from '@/components'; -import { useGetCurrentEpochStartTimestamp, useNotifications, usePopups } from '@/hooks'; +import { UnstakeDialogView } from '@/components/Dialogs/unstake/enums'; +import { useUnstakeDialog } from '@/components/Dialogs/unstake/hooks'; +import { useGetCurrentEpochStartTimestamp, useNotifications } from '@/hooks'; import { buildSupplyIncreaseVestingSchedule, formatDelegatedTimelockedStake, @@ -63,29 +65,33 @@ import { import { IotaValidatorSummary } from '@iota/iota-sdk/client'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; import { Calendar, StarHex } from '@iota/ui-icons'; -import { useQueryClient } from '@tanstack/react-query'; import { useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; import { StakedTimelockObject } from '@/components'; +import { IotaSignAndExecuteTransactionOutput } from '@iota/wallet-standard'; -function VestingDashboardPage(): JSX.Element { +export default function VestingDashboardPage(): JSX.Element { + const [timelockedObjectsToUnstake, setTimelockedObjectsToUnstake] = + useState<TimelockedStakedObjectsGrouped | null>(null); const account = useCurrentAccount(); - const queryClient = useQueryClient(); const iotaClient = useIotaClient(); const router = useRouter(); const { data: system } = useIotaClientQuery('getLatestIotaSystemState'); const [isVestingScheduleDialogOpen, setIsVestingScheduleDialogOpen] = useState(false); const { addNotification } = useNotifications(); - const { openPopup, closePopup } = usePopups(); const { data: currentEpochMs } = useGetCurrentEpochStartTimestamp(); const { data: activeValidators } = useGetActiveValidatorsInfo(); - const { data: timelockedObjects } = useGetAllOwnedObjects(account?.address || '', { - StructType: TIMELOCK_IOTA_TYPE, - }); - - const { data: timelockedStakedObjects, isLoading: istimelockedStakedObjectsLoading } = - useGetTimelockedStakedObjects(account?.address || ''); - + const { data: timelockedObjects, refetch: refetchGetAllOwnedObjects } = useGetAllOwnedObjects( + account?.address || '', + { + StructType: TIMELOCK_IOTA_TYPE, + }, + ); + const { + data: timelockedStakedObjects, + isLoading: istimelockedStakedObjectsLoading, + refetch: refetchTimelockedStakedObjects, + } = useGetTimelockedStakedObjects(account?.address || ''); const { mutateAsync: signAndExecuteTransaction } = useSignAndExecuteTransaction(); const { theme } = useTheme(); @@ -118,6 +124,14 @@ function VestingDashboardPage(): JSX.Element { handleNewStake, } = useStakeDialog(); + const { + isOpen: isUnstakeDialogOpen, + openUnstakeDialog, + defaultDialogProps, + setTxDigest, + setView: setUnstakeDialogView, + } = useUnstakeDialog(); + const nextPayout = getLatestOrEarliestSupplyIncreaseVestingPayout( [...timelockedMapped, ...timelockedstakedMapped], Number(currentEpochMs), @@ -183,25 +197,19 @@ function VestingDashboardPage(): JSX.Element { unlockedTimelockedObjectIds, ); + function refreshStakeList() { + refetchTimelockedStakedObjects(); + refetchGetAllOwnedObjects(); + } + function handleOnSuccess(digest: string): void { + setTimelockedObjectsToUnstake(null); + iotaClient .waitForTransaction({ digest, }) - .then(() => { - queryClient.invalidateQueries({ - queryKey: ['get-timelocked-staked-objects', account?.address], - }); - queryClient.invalidateQueries({ - queryKey: [ - 'get-all-owned-objects', - account?.address, - { - StructType: TIMELOCK_IOTA_TYPE, - }, - ], - }); - }); + .then(refreshStakeList); } const handleCollect = () => { @@ -228,27 +236,22 @@ function VestingDashboardPage(): JSX.Element { }; function handleUnstake(delegatedTimelockedStake: TimelockedStakedObjectsGrouped): void { - const validatorInfo = getValidatorByAddress(delegatedTimelockedStake.validatorAddress); - if (!account || !validatorInfo) { - addNotification('Cannot create transaction', NotificationType.Error); - return; - } - - openPopup( - <TimelockedUnstakePopup - accountAddress={account.address} - delegatedStake={delegatedTimelockedStake} - validatorInfo={validatorInfo} - closePopup={closePopup} - onSuccess={handleOnSuccess} - />, - ); + setTimelockedObjectsToUnstake(delegatedTimelockedStake); + openUnstakeDialog(UnstakeDialogView.TimelockedUnstake); } function openReceiveTokenPopup(): void { setIsVestingScheduleDialogOpen(true); } + function handleOnSuccessUnstake(tx: IotaSignAndExecuteTransactionOutput): void { + setUnstakeDialogView(UnstakeDialogView.TransactionDetails); + iotaClient.waitForTransaction({ digest: tx.digest }).then((tx) => { + refreshStakeList(); + setTxDigest(tx.digest); + }); + } + useEffect(() => { if (!supplyIncreaseVestingEnabled) { router.push('/'); @@ -264,152 +267,174 @@ function VestingDashboardPage(): JSX.Element { } return ( - <div className="flex w-full max-w-4xl flex-col items-stretch justify-center gap-lg justify-self-center md:flex-row"> - <div className="flex w-full flex-col gap-lg md:w-1/2"> - <Panel> - <Title title="Vesting" size={TitleSize.Medium} /> - <div className="flex flex-col gap-md p-lg pt-sm"> - <div className="flex h-24 flex-row gap-4"> - <DisplayStats - label="Total Vested" - value={formattedTotalVested} - supportingLabel={vestedSymbol} - /> - <DisplayStats - label="Total Locked" - value={formattedTotalLocked} - supportingLabel={lockedSymbol} - tooltipText="Total amount of IOTA that is still locked in your account." - tooltipPosition={TooltipPosition.Right} - /> - </div> - <Card type={CardType.Outlined}> - <CardImage type={ImageType.BgSolid} shape={ImageShape.SquareRounded}> - <StarHex className="h-5 w-5 text-primary-30 dark:text-primary-80" /> - </CardImage> - <CardBody - title={`${formattedAvailableClaiming} ${availableClaimingSymbol}`} - subtitle="Available Rewards" - /> - <CardAction - type={CardActionType.Button} - onClick={handleCollect} - title="Collect" - buttonType={ButtonType.Primary} - buttonDisabled={ - !vestingSchedule.availableClaiming || - vestingSchedule.availableClaiming === 0n - } - /> - </Card> - <Card type={CardType.Outlined}> - <CardImage type={ImageType.BgSolid} shape={ImageShape.SquareRounded}> - <Calendar className="h-5 w-5 text-primary-30 dark:text-primary-80" /> - </CardImage> - <CardBody - title={`${formattedNextPayout} ${nextPayoutSymbol}`} - subtitle={`Next payout ${ - nextPayout?.expirationTimestampMs - ? formattedLastPayoutExpirationTime - : '' - }`} - /> - <CardAction - type={CardActionType.Button} - onClick={openReceiveTokenPopup} - title="See All" - buttonType={ButtonType.Secondary} - buttonDisabled={!vestingPortfolio} - /> - </Card> - {vestingPortfolio && ( - <VestingScheduleDialog - open={isVestingScheduleDialogOpen} - setOpen={setIsVestingScheduleDialogOpen} - vestingPortfolio={vestingPortfolio} - /> - )} - </div> - </Panel> - - {timelockedstakedMapped.length === 0 ? ( - <Banner - videoSrc={videoSrc} - title="Stake Vested Tokens" - subtitle="Earn Rewards" - onButtonClick={() => handleNewStake()} - buttonText="Stake" - /> - ) : null} - </div> - - {timelockedstakedMapped.length !== 0 ? ( - <div className="flex w-full md:w-1/2"> + <> + <div className="flex w-full max-w-4xl flex-col items-stretch justify-center gap-lg justify-self-center md:flex-row"> + <div className="flex w-full flex-col gap-lg md:w-1/2"> <Panel> - <Title - title="Staked Vesting" - trailingElement={ - <Button - type={ButtonType.Primary} - text="Stake" - onClick={() => { - setStakeDialogView(StakeDialogView.SelectValidator); - }} - /> - } - /> - - <div className="flex flex-col px-lg py-sm"> - <div className="flex flex-row gap-md"> + <Title title="Vesting" size={TitleSize.Medium} /> + <div className="flex flex-col gap-md p-lg pt-sm"> + <div className="flex h-24 flex-row gap-4"> <DisplayStats - label="Your stake" - value={`${totalStakedFormatted} ${totalStakedSymbol}`} + label="Total Vested" + value={formattedTotalVested} + supportingLabel={vestedSymbol} /> <DisplayStats - label="Earned" - value={`${totalEarnedFormatted} ${totalEarnedSymbol}`} + label="Total Locked" + value={formattedTotalLocked} + supportingLabel={lockedSymbol} + tooltipText="Total amount of IOTA that is still locked in your account." + tooltipPosition={TooltipPosition.Right} /> </div> - </div> - <div className="flex flex-col px-lg py-sm"> - <div className="flex w-full flex-col items-center justify-center space-y-4 pt-4"> - {system && - timelockedStakedObjectsGrouped?.map( - (timelockedStakedObject) => { - return ( - <StakedTimelockObject - key={ - timelockedStakedObject.validatorAddress + - timelockedStakedObject.stakeRequestEpoch + - timelockedStakedObject.label - } - getValidatorByAddress={getValidatorByAddress} - timelockedStakedObject={timelockedStakedObject} - handleUnstake={handleUnstake} - currentEpoch={Number(system.epoch)} - /> - ); - }, - )} - </div> + <Card type={CardType.Outlined}> + <CardImage + type={ImageType.BgSolid} + shape={ImageShape.SquareRounded} + > + <StarHex className="h-5 w-5 text-primary-30 dark:text-primary-80" /> + </CardImage> + <CardBody + title={`${formattedAvailableClaiming} ${availableClaimingSymbol}`} + subtitle="Available Rewards" + /> + <CardAction + type={CardActionType.Button} + onClick={handleCollect} + title="Collect" + buttonType={ButtonType.Primary} + buttonDisabled={ + !vestingSchedule.availableClaiming || + vestingSchedule.availableClaiming === 0n + } + /> + </Card> + <Card type={CardType.Outlined}> + <CardImage + type={ImageType.BgSolid} + shape={ImageShape.SquareRounded} + > + <Calendar className="h-5 w-5 text-primary-30 dark:text-primary-80" /> + </CardImage> + <CardBody + title={`${formattedNextPayout} ${nextPayoutSymbol}`} + subtitle={`Next payout ${ + nextPayout?.expirationTimestampMs + ? formattedLastPayoutExpirationTime + : '' + }`} + /> + <CardAction + type={CardActionType.Button} + onClick={openReceiveTokenPopup} + title="See All" + buttonType={ButtonType.Secondary} + buttonDisabled={!vestingPortfolio} + /> + </Card> + {vestingPortfolio && ( + <VestingScheduleDialog + open={isVestingScheduleDialogOpen} + setOpen={setIsVestingScheduleDialogOpen} + vestingPortfolio={vestingPortfolio} + /> + )} </div> </Panel> + + {timelockedstakedMapped.length === 0 ? ( + <Banner + videoSrc={videoSrc} + title="Stake Vested Tokens" + subtitle="Earn Rewards" + onButtonClick={() => handleNewStake()} + buttonText="Stake" + /> + ) : null} </div> - ) : null} - <StakeDialog - isTimelockedStaking - stakedDetails={selectedStake} - onSuccess={handleOnSuccess} - isOpen={isDialogStakeOpen} - handleClose={handleCloseStakeDialog} - view={stakeDialogView} - setView={setStakeDialogView} - selectedValidator={selectedValidator} - setSelectedValidator={setSelectedValidator} - maxStakableTimelockedAmount={BigInt(vestingSchedule.availableStaking)} - /> - </div> + + {timelockedstakedMapped.length !== 0 ? ( + <div className="flex w-full md:w-1/2"> + <Panel> + <Title + title="Staked Vesting" + trailingElement={ + <Button + type={ButtonType.Primary} + text="Stake" + disabled={vestingSchedule.availableStaking === 0n} + onClick={() => { + setStakeDialogView(StakeDialogView.SelectValidator); + }} + /> + } + /> + + <div className="flex flex-col px-lg py-sm"> + <div className="flex flex-row gap-md"> + <DisplayStats + label="Your stake" + value={`${totalStakedFormatted} ${totalStakedSymbol}`} + /> + <DisplayStats + label="Earned" + value={`${totalEarnedFormatted} ${totalEarnedSymbol}`} + /> + </div> + </div> + <div className="flex flex-col px-lg py-sm"> + <div className="flex w-full flex-col items-center justify-center space-y-4 pt-4"> + {system && + timelockedStakedObjectsGrouped?.map( + (timelockedStakedObject) => { + return ( + <StakedTimelockObject + key={ + timelockedStakedObject.validatorAddress + + timelockedStakedObject.stakeRequestEpoch + + timelockedStakedObject.label + } + getValidatorByAddress={ + getValidatorByAddress + } + timelockedStakedObject={ + timelockedStakedObject + } + handleUnstake={handleUnstake} + currentEpoch={Number(system.epoch)} + /> + ); + }, + )} + </div> + </div> + </Panel> + </div> + ) : null} + + {isDialogStakeOpen && ( + <StakeDialog + isTimelockedStaking + stakedDetails={selectedStake} + onSuccess={handleOnSuccess} + handleClose={handleCloseStakeDialog} + view={stakeDialogView} + setView={setStakeDialogView} + selectedValidator={selectedValidator} + setSelectedValidator={setSelectedValidator} + maxStakableTimelockedAmount={BigInt(vestingSchedule.availableStaking)} + onUnstakeClick={openUnstakeDialog} + /> + )} + + {isUnstakeDialogOpen && timelockedObjectsToUnstake && ( + <UnstakeDialog + groupedTimelockedObjects={timelockedObjectsToUnstake} + onSuccess={handleOnSuccessUnstake} + {...defaultDialogProps} + /> + )} + </div> + </> ); } - -export default VestingDashboardPage; diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/StakeDialog.tsx b/apps/wallet-dashboard/components/Dialogs/Staking/StakeDialog.tsx index 29f832afdf6..6829097f6c3 100644 --- a/apps/wallet-dashboard/components/Dialogs/Staking/StakeDialog.tsx +++ b/apps/wallet-dashboard/components/Dialogs/Staking/StakeDialog.tsx @@ -3,42 +3,28 @@ import React, { useMemo, useState } from 'react'; import { EnterAmountView, EnterTimelockedAmountView, SelectValidatorView } from './views'; -import { - useNotifications, - useNewStakeTransaction, - useGetCurrentEpochStartTimestamp, -} from '@/hooks'; import { ExtendedDelegatedStake, - GroupedTimelockObject, parseAmount, - TIMELOCK_IOTA_TYPE, useCoinMetadata, - useGetAllOwnedObjects, useGetValidatorsApy, useBalance, createValidationSchema, MIN_NUMBER_IOTA_TO_STAKE, } from '@iota/core'; import { FormikProvider, useFormik } from 'formik'; -import type { FormikHelpers } from 'formik'; -import { useCurrentAccount, useSignAndExecuteTransaction } from '@iota/dapp-kit'; +import { useCurrentAccount } from '@iota/dapp-kit'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; -import { NotificationType } from '@/stores/notificationStore'; -import { prepareObjectsForTimelockedStakingTransaction } from '@/lib/utils'; import { Dialog } from '@iota/apps-ui-kit'; -import { DetailsView, UnstakeView } from './views'; -import { FormValues } from './views/EnterAmountView'; +import { DetailsView } from './views'; import { TransactionDialogView } from '../TransactionDialog'; import { StakeDialogView } from './enums/view.enums'; -import { Transaction } from '@iota/iota-sdk/transactions'; const INITIAL_VALUES = { amount: '', }; interface StakeDialogProps { - isOpen: boolean; handleClose: () => void; view: StakeDialogView | undefined; setView: (view: StakeDialogView) => void; @@ -48,12 +34,12 @@ interface StakeDialogProps { onSuccess?: (digest: string) => void; selectedValidator?: string; setSelectedValidator?: (validator: string) => void; + onUnstakeClick?: () => void; } export function StakeDialog({ onSuccess, isTimelockedStaking, - isOpen, handleClose, view, setView, @@ -61,6 +47,7 @@ export function StakeDialog({ maxStakableTimelockedAmount, selectedValidator = '', setSelectedValidator, + onUnstakeClick, }: StakeDialogProps): JSX.Element { const account = useCurrentAccount(); const senderAddress = account?.address ?? ''; @@ -79,137 +66,69 @@ export function StakeDialog({ maxStakableTimelockedAmount ?? coinBalance, coinSymbol, coinDecimals, - view === StakeDialogView.Unstake, + false, minimumStake, ), - [maxStakableTimelockedAmount, coinBalance, coinSymbol, coinDecimals, view, minimumStake], + [maxStakableTimelockedAmount, coinBalance, coinSymbol, coinDecimals, minimumStake], ); const formik = useFormik({ initialValues: INITIAL_VALUES, validationSchema: validationSchema, - onSubmit: onSubmit, + onSubmit: () => undefined, validateOnMount: true, }); const amount = formik.values.amount || `${MIN_NUMBER_IOTA_TO_STAKE}`; const amountWithoutDecimals = parseAmount(amount, coinDecimals); - const { data: currentEpochMs } = useGetCurrentEpochStartTimestamp(); - const { data: timelockedObjects } = useGetAllOwnedObjects(senderAddress, { - StructType: TIMELOCK_IOTA_TYPE, - }); - let groupedTimelockObjects: GroupedTimelockObject[] = []; - if (isTimelockedStaking && timelockedObjects && currentEpochMs) { - groupedTimelockObjects = prepareObjectsForTimelockedStakingTransaction( - timelockedObjects, - amountWithoutDecimals, - currentEpochMs, - ); - } - - const { data: newStakeData, isLoading: isTransactionLoading } = useNewStakeTransaction( - selectedValidator, - amountWithoutDecimals, - senderAddress, - isTimelockedStaking, - groupedTimelockObjects, - ); - const { mutateAsync: signAndExecuteTransaction, isPending } = useSignAndExecuteTransaction(); - const { addNotification } = useNotifications(); const { data: rollingAverageApys } = useGetValidatorsApy(); const validators = Object.keys(rollingAverageApys ?? {}) ?? []; function handleBack(): void { - setView?.(StakeDialogView.SelectValidator); + setView(StakeDialogView.SelectValidator); } function handleValidatorSelect(validator: string): void { setSelectedValidator?.(validator); } + function setViewBasedOnStakingType() { + setView( + isTimelockedStaking + ? StakeDialogView.EnterTimelockedAmount + : StakeDialogView.EnterAmount, + ); + } + function selectValidatorHandleNext(): void { if (selectedValidator) { - setView?.( - isTimelockedStaking - ? StakeDialogView.EnterTimelockedAmount - : StakeDialogView.EnterAmount, - ); + setViewBasedOnStakingType(); } } - function detailsHandleUnstake() { - setView?.(StakeDialogView.Unstake); - } - function detailsHandleStake() { - setView?.(StakeDialogView.SelectValidator); - } - - function handleStake(): void { - if (isTimelockedStaking && groupedTimelockObjects.length === 0) { - addNotification('Invalid stake amount. Please try again.', NotificationType.Error); - return; - } - if (!newStakeData?.transaction) { - addNotification('Stake transaction was not created', NotificationType.Error); - return; + if (stakedDetails) { + setSelectedValidator?.(stakedDetails.validatorAddress); + setViewBasedOnStakingType(); } - signAndExecuteTransaction( - { - transaction: newStakeData?.transaction, - }, - { - onSuccess: (tx) => { - onSuccess?.(tx.digest); - addNotification('Stake transaction has been sent'); - setTxDigest(tx.digest); - setView?.(StakeDialogView.TransactionDetails); - }, - onError: () => { - addNotification('Stake transaction was not sent', NotificationType.Error); - }, - }, - ); } - function handleUnstake(transaction: Transaction): void { - if (!transaction) { - addNotification('Unstake transaction was not created', NotificationType.Error); - return; - } - signAndExecuteTransaction( - { - transaction: transaction, - }, - { - onSuccess: (tx) => { - onSuccess?.(tx.digest); - addNotification('Unstake transaction has been sent'); - setTxDigest(tx.digest); - setView?.(StakeDialogView.TransactionDetails); - }, - onError: () => { - addNotification('Unstake transaction was not sent', NotificationType.Error); - }, - }, - ); - } - - function onSubmit(_: FormValues, { resetForm }: FormikHelpers<FormValues>) { - handleStake(); - resetForm(); + function handleTransactionSuccess(digest: string) { + onSuccess?.(digest); + setTxDigest(digest); + setView(StakeDialogView.TransactionDetails); } return ( - <Dialog open={isOpen} onOpenChange={() => handleClose()}> + <Dialog open onOpenChange={() => handleClose()}> <FormikProvider value={formik}> <> {view === StakeDialogView.Details && stakedDetails && ( <DetailsView handleStake={detailsHandleStake} - handleUnstake={detailsHandleUnstake} + handleUnstake={onUnstakeClick} stakedDetails={stakedDetails} handleClose={handleClose} /> @@ -228,29 +147,20 @@ export function StakeDialog({ selectedValidator={selectedValidator} handleClose={handleClose} onBack={handleBack} - onStake={handleStake} - gasBudget={newStakeData?.gasBudget} - isTransactionLoading={isTransactionLoading} + amountWithoutDecimals={amountWithoutDecimals} + senderAddress={senderAddress} + onSuccess={handleTransactionSuccess} /> )} {view === StakeDialogView.EnterTimelockedAmount && ( <EnterTimelockedAmountView selectedValidator={selectedValidator} maxStakableTimelockedAmount={maxStakableTimelockedAmount ?? BigInt(0)} - hasGroupedTimelockObjects={groupedTimelockObjects.length > 0} handleClose={handleClose} onBack={handleBack} - onStake={handleStake} - gasBudget={newStakeData?.gasBudget} - isTransactionLoading={isTransactionLoading} - /> - )} - {view === StakeDialogView.Unstake && stakedDetails && ( - <UnstakeView - extendedStake={stakedDetails} - handleClose={handleClose} - onUnstake={handleUnstake} - isPending={isPending} + senderAddress={senderAddress} + onSuccess={handleTransactionSuccess} + amountWithoutDecimals={amountWithoutDecimals} /> )} {view === StakeDialogView.TransactionDetails && ( diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/enums/view.enums.ts b/apps/wallet-dashboard/components/Dialogs/Staking/enums/view.enums.ts index 1bdb66a93ed..eb4f6cf20f5 100644 --- a/apps/wallet-dashboard/components/Dialogs/Staking/enums/view.enums.ts +++ b/apps/wallet-dashboard/components/Dialogs/Staking/enums/view.enums.ts @@ -5,7 +5,6 @@ export enum StakeDialogView { Details = 'Details', SelectValidator = 'SelectValidator', EnterAmount = 'EnterAmount', - Unstake = 'Unstake', EnterTimelockedAmount = 'EnterTimelockedAmount', TransactionDetails = 'TransactionDetails', } diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/index.ts b/apps/wallet-dashboard/components/Dialogs/Staking/index.ts index bf9af6d49a4..e32885d1475 100644 --- a/apps/wallet-dashboard/components/Dialogs/Staking/index.ts +++ b/apps/wallet-dashboard/components/Dialogs/Staking/index.ts @@ -2,5 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 export * from './enums'; -export * from './StakeDialog'; export * from './hooks'; + +export * from './StakeDialog'; diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/views/DetailsView.tsx b/apps/wallet-dashboard/components/Dialogs/Staking/views/DetailsView.tsx index 0cdba0031e1..48ebf1b4f3c 100644 --- a/apps/wallet-dashboard/components/Dialogs/Staking/views/DetailsView.tsx +++ b/apps/wallet-dashboard/components/Dialogs/Staking/views/DetailsView.tsx @@ -33,11 +33,11 @@ import { formatAddress, IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; import { DialogLayout, DialogLayoutFooter, DialogLayoutBody } from '../../layout'; interface StakeDialogProps { - stakedDetails: ExtendedDelegatedStake; - showActiveStatus?: boolean; handleClose: () => void; - handleUnstake: () => void; handleStake: () => void; + stakedDetails: ExtendedDelegatedStake; + showActiveStatus?: boolean; + handleUnstake?: () => void; } export function DetailsView({ diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterAmountView.tsx b/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterAmountView.tsx index b3869faed2b..a2c7f61d0db 100644 --- a/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterAmountView.tsx +++ b/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterAmountView.tsx @@ -26,11 +26,13 @@ import { } from '@iota/apps-ui-kit'; import { Field, type FieldProps, useFormikContext } from 'formik'; import { Exclamation } from '@iota/ui-icons'; -import { useCurrentAccount, useIotaClientQuery } from '@iota/dapp-kit'; +import { useIotaClientQuery, useSignAndExecuteTransaction } from '@iota/dapp-kit'; import { Validator } from './Validator'; import { StakedInfo } from './StakedInfo'; import { DialogLayout, DialogLayoutBody, DialogLayoutFooter } from '../../layout'; +import { useNewStakeTransaction, useNotifications } from '@/hooks'; +import { NotificationType } from '@/stores/notificationStore'; export interface FormValues { amount: string; @@ -39,37 +41,43 @@ export interface FormValues { interface EnterAmountViewProps { selectedValidator: string; onBack: () => void; - onStake: () => void; showActiveStatus?: boolean; - gasBudget?: string | number | null; handleClose: () => void; - isTransactionLoading?: boolean; + amountWithoutDecimals: bigint; + senderAddress: string; + onSuccess: (digest: string) => void; } function EnterAmountView({ selectedValidator: selectedValidatorAddress, onBack, - onStake, - gasBudget = 0, handleClose, - isTransactionLoading, + amountWithoutDecimals, + senderAddress, + onSuccess, }: EnterAmountViewProps): JSX.Element { const coinType = IOTA_TYPE_ARG; const { data: metadata } = useCoinMetadata(coinType); const decimals = metadata?.decimals ?? 0; - const account = useCurrentAccount(); - const accountAddress = account?.address; + const { addNotification } = useNotifications(); - const { values, errors } = useFormikContext<FormValues>(); + const { values, errors, resetForm } = useFormikContext<FormValues>(); const amount = values.amount; + const { data: newStakeData, isLoading: isTransactionLoading } = useNewStakeTransaction( + selectedValidatorAddress, + amountWithoutDecimals, + senderAddress, + ); + const { data: system } = useIotaClientQuery('getLatestIotaSystemState'); - const { data: iotaBalance } = useBalance(accountAddress!); + const { data: iotaBalance } = useBalance(senderAddress!); const coinBalance = BigInt(iotaBalance?.totalBalance || 0); + const { mutateAsync: signAndExecuteTransaction } = useSignAndExecuteTransaction(); - const gasBudgetBigInt = BigInt(gasBudget ?? 0); - const [gas, symbol] = useFormatCoin(gasBudget, IOTA_TYPE_ARG); + const gasBudgetBigInt = BigInt(newStakeData?.gasBudget ?? 0); + const [gas, symbol] = useFormatCoin(newStakeData?.gasBudget, IOTA_TYPE_ARG); const maxTokenBalance = coinBalance - gasBudgetBigInt; const [maxTokenFormatted, maxTokenFormattedSymbol] = useFormatCoin( @@ -89,6 +97,28 @@ function EnterAmountView({ const hasEnoughRemaingBalance = maxTokenBalance > parseAmount(values.amount, decimals) + BigInt(2) * gasBudgetBigInt; + function handleStake(): void { + if (!newStakeData?.transaction) { + addNotification('Stake transaction was not created', NotificationType.Error); + return; + } + signAndExecuteTransaction( + { + transaction: newStakeData?.transaction, + }, + { + onSuccess: (tx) => { + onSuccess(tx.digest); + addNotification('Stake transaction has been sent'); + resetForm(); + }, + onError: () => { + addNotification('Stake transaction was not sent', NotificationType.Error); + }, + }, + ); + } + return ( <DialogLayout> <Header title="Enter amount" onClose={handleClose} onBack={onBack} titleCentered /> @@ -104,7 +134,7 @@ function EnterAmountView({ </div> <StakedInfo validatorAddress={selectedValidatorAddress} - accountAddress={accountAddress!} + accountAddress={senderAddress!} /> <div className="my-md w-full"> <Field name="amount"> @@ -174,7 +204,7 @@ function EnterAmountView({ <Button fullWidth type={ButtonType.Primary} - onClick={onStake} + onClick={handleStake} disabled={!amount || !!errors?.amount} text="Stake" /> diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterTimelockedAmountView.tsx b/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterTimelockedAmountView.tsx index 9eaeb41b6a2..af365e15f30 100644 --- a/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterTimelockedAmountView.tsx +++ b/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterTimelockedAmountView.tsx @@ -1,8 +1,15 @@ // Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -import React from 'react'; -import { useFormatCoin, CoinFormat, useStakeTxnInfo } from '@iota/core'; +import React, { useEffect, useState } from 'react'; +import { + useFormatCoin, + CoinFormat, + useStakeTxnInfo, + GroupedTimelockObject, + useGetAllOwnedObjects, + TIMELOCK_IOTA_TYPE, +} from '@iota/core'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; import { Button, @@ -19,11 +26,17 @@ import { } from '@iota/apps-ui-kit'; import { Field, type FieldProps, useFormikContext } from 'formik'; import { Exclamation, Loader } from '@iota/ui-icons'; -import { useCurrentAccount, useIotaClientQuery } from '@iota/dapp-kit'; - +import { useIotaClientQuery, useSignAndExecuteTransaction } from '@iota/dapp-kit'; import { Validator } from './Validator'; import { StakedInfo } from './StakedInfo'; import { DialogLayout, DialogLayoutBody, DialogLayoutFooter } from '../../layout'; +import { + useGetCurrentEpochStartTimestamp, + useNewStakeTimelockedTransaction, + useNotifications, +} from '@/hooks'; +import { NotificationType } from '@/stores/notificationStore'; +import { prepareObjectsForTimelockedStakingTransaction } from '@/lib/utils'; export interface FormValues { amount: string; @@ -32,32 +45,51 @@ export interface FormValues { interface EnterTimelockedAmountViewProps { selectedValidator: string; maxStakableTimelockedAmount: bigint; + amountWithoutDecimals: bigint; + senderAddress: string; onBack: () => void; - onStake: () => void; - gasBudget?: string | number | null; handleClose: () => void; - hasGroupedTimelockObjects?: boolean; - isTransactionLoading?: boolean; + onSuccess: (digest: string) => void; } function EnterTimelockedAmountView({ - selectedValidator: selectedValidatorAddress, + selectedValidator, maxStakableTimelockedAmount, - hasGroupedTimelockObjects, + amountWithoutDecimals, + senderAddress, onBack, - onStake, - gasBudget, handleClose, - isTransactionLoading, + onSuccess, }: EnterTimelockedAmountViewProps): JSX.Element { - const account = useCurrentAccount(); - const accountAddress = account?.address; + const { addNotification } = useNotifications(); + const { mutateAsync: signAndExecuteTransaction } = useSignAndExecuteTransaction(); + const [groupedTimelockObjects, setGroupedTimelockObjects] = useState<GroupedTimelockObject[]>( + [], + ); + const { data: newStakeData, isLoading: isTransactionLoading } = + useNewStakeTimelockedTransaction(selectedValidator, senderAddress, groupedTimelockObjects); + const { data: currentEpochMs } = useGetCurrentEpochStartTimestamp(); + const { data: timelockedObjects } = useGetAllOwnedObjects(senderAddress, { + StructType: TIMELOCK_IOTA_TYPE, + }); + + useEffect(() => { + if (timelockedObjects && currentEpochMs) { + const groupedTimelockObjects = prepareObjectsForTimelockedStakingTransaction( + timelockedObjects, + amountWithoutDecimals, + currentEpochMs, + ); + setGroupedTimelockObjects(groupedTimelockObjects); + } + }, [timelockedObjects, currentEpochMs, amountWithoutDecimals]); - const { values, errors } = useFormikContext<FormValues>(); + const { values, errors, resetForm } = useFormikContext<FormValues>(); const amount = values.amount; + const hasGroupedTimelockObjects = groupedTimelockObjects.length > 0; const { data: system } = useIotaClientQuery('getLatestIotaSystemState'); - const [gas, symbol] = useFormatCoin(gasBudget ?? 0, IOTA_TYPE_ARG); + const [gas, symbol] = useFormatCoin(newStakeData?.gasBudget ?? 0, IOTA_TYPE_ARG); const [maxTokenFormatted, maxTokenFormattedSymbol] = useFormatCoin( maxStakableTimelockedAmount, @@ -71,6 +103,32 @@ function EnterTimelockedAmountView({ system?.epoch, ); + function handleStake(): void { + if (groupedTimelockObjects.length === 0) { + addNotification('Invalid stake amount. Please try again.', NotificationType.Error); + return; + } + if (!newStakeData?.transaction) { + addNotification('Stake transaction was not created', NotificationType.Error); + return; + } + signAndExecuteTransaction( + { + transaction: newStakeData?.transaction, + }, + { + onSuccess: (tx) => { + onSuccess?.(tx.digest); + addNotification('Stake transaction has been sent'); + resetForm(); + }, + onError: () => { + addNotification('Stake transaction was not sent', NotificationType.Error); + }, + }, + ); + } + return ( <DialogLayout> <Header title="Enter amount" onClose={handleClose} onBack={onBack} titleCentered /> @@ -78,15 +136,11 @@ function EnterTimelockedAmountView({ <div className="flex w-full flex-col justify-between"> <div> <div className="mb-md"> - <Validator - address={selectedValidatorAddress} - isSelected - showAction={false} - /> + <Validator address={selectedValidator} isSelected showAction={false} /> </div> <StakedInfo - validatorAddress={selectedValidatorAddress} - accountAddress={accountAddress!} + validatorAddress={selectedValidator} + accountAddress={senderAddress!} /> <div className="my-md w-full"> <Field name="amount"> @@ -162,7 +216,7 @@ function EnterTimelockedAmountView({ isTransactionLoading || !hasGroupedTimelockObjects } - onClick={onStake} + onClick={handleStake} text="Stake" icon={ isTransactionLoading ? ( diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/views/UnstakeView.tsx b/apps/wallet-dashboard/components/Dialogs/Staking/views/UnstakeView.tsx deleted file mode 100644 index 302d1de5514..00000000000 --- a/apps/wallet-dashboard/components/Dialogs/Staking/views/UnstakeView.tsx +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -import { - Header, - Button, - KeyValueInfo, - Divider, - ButtonType, - Panel, - LoadingIndicator, - InfoBoxType, - InfoBoxStyle, - InfoBox, -} from '@iota/apps-ui-kit'; -import { - createUnstakeTransaction, - ExtendedDelegatedStake, - GAS_SYMBOL, - TimeUnit, - useFormatCoin, - useGetTimeBeforeEpochNumber, - useGetStakingValidatorDetails, - useTimeAgo, - useTransactionGasBudget, -} from '@iota/core'; -import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; -import { useMemo } from 'react'; -import { useCurrentAccount } from '@iota/dapp-kit'; -import { Loader, Warning } from '@iota/ui-icons'; -import { useUnstakeTransaction } from '@/hooks'; -import { ValidatorStakingData } from '@/components'; -import { DialogLayout, DialogLayoutFooter, DialogLayoutBody } from '../../layout'; -import { Transaction } from '@iota/iota-sdk/transactions'; - -interface UnstakeViewProps { - extendedStake: ExtendedDelegatedStake; - handleClose: () => void; - onUnstake: (unstakeTransaction: Transaction) => void; - isPending: boolean; -} - -export function UnstakeView({ - extendedStake, - handleClose, - onUnstake, - isPending, -}: UnstakeViewProps): JSX.Element { - const stakingReward = BigInt(extendedStake.estimatedReward ?? '').toString(); - const [rewards, rewardSymbol] = useFormatCoin(stakingReward, IOTA_TYPE_ARG); - const activeAddress = useCurrentAccount()?.address ?? null; - - const { - totalStake: [tokenBalance], - totalStakeOriginal, - epoch, - systemDataResult, - delegatedStakeDataResult, - } = useGetStakingValidatorDetails({ - accountAddress: activeAddress, - validatorAddress: extendedStake.validatorAddress, - stakeId: extendedStake.stakedIotaId, - unstake: true, - }); - - const { isLoading: loadingValidators, error: errorValidators } = systemDataResult; - const { - isLoading: isLoadingDelegatedStakeData, - isError, - error: delegatedStakeDataError, - } = delegatedStakeDataResult; - - const delegationId = extendedStake?.stakedIotaId; - - const [totalIota] = useFormatCoin( - BigInt(stakingReward || 0) + totalStakeOriginal, - IOTA_TYPE_ARG, - ); - - const transaction = useMemo( - () => createUnstakeTransaction(extendedStake.stakedIotaId), - [extendedStake], - ); - const { data: gasBudget } = useTransactionGasBudget(activeAddress, transaction); - - const { data: currentEpochEndTime } = useGetTimeBeforeEpochNumber(epoch + 1 || 0); - const currentEpochEndTimeAgo = useTimeAgo({ - timeFrom: currentEpochEndTime, - endLabel: '--', - shortedTimeLabel: false, - shouldEnd: true, - maxTimeUnit: TimeUnit.ONE_HOUR, - }); - - const { data: unstakeData } = useUnstakeTransaction( - extendedStake.stakedIotaId, - activeAddress || '', - ); - - function handleUnstake(): void { - if (!unstakeData) return; - onUnstake(unstakeData.transaction); - } - - const currentEpochEndTimeFormatted = - currentEpochEndTime > 0 ? currentEpochEndTimeAgo : `Epoch #${epoch}`; - - if (isLoadingDelegatedStakeData || loadingValidators) { - return ( - <div className="flex h-full w-full items-center justify-center p-2"> - <LoadingIndicator /> - </div> - ); - } - - if (isError || errorValidators) { - return ( - <div className="mb-2 flex h-full w-full items-center justify-center p-2"> - <InfoBox - title="Something went wrong" - supportingText={delegatedStakeDataError?.message ?? 'An error occurred'} - style={InfoBoxStyle.Default} - type={InfoBoxType.Error} - icon={<Warning />} - /> - </div> - ); - } - - return ( - <DialogLayout> - <Header title="Unstake" onClose={handleClose} onBack={handleClose} titleCentered /> - <DialogLayoutBody> - <div className="flex flex-col gap-y-md"> - <ValidatorStakingData - validatorAddress={extendedStake.validatorAddress} - stakeId={extendedStake.stakedIotaId} - isUnstake - /> - - <Panel hasBorder> - <div className="flex flex-col gap-y-sm p-md"> - <KeyValueInfo - keyText="Current Epoch Ends" - value={currentEpochEndTimeFormatted} - fullwidth - /> - <Divider /> - <KeyValueInfo - keyText="Your Stake" - value={tokenBalance} - supportingLabel={GAS_SYMBOL} - fullwidth - /> - <KeyValueInfo - keyText="Rewards Earned" - value={rewards} - supportingLabel={rewardSymbol} - fullwidth - /> - <Divider /> - <KeyValueInfo - keyText="Total unstaked IOTA" - value={totalIota} - supportingLabel={GAS_SYMBOL} - fullwidth - /> - </div> - </Panel> - - <Panel hasBorder> - <div className="flex flex-col gap-y-sm p-md"> - <KeyValueInfo - keyText="Gas Fees" - value={gasBudget || '-'} - supportingLabel={GAS_SYMBOL} - fullwidth - /> - </div> - </Panel> - </div> - </DialogLayoutBody> - - <DialogLayoutFooter> - <Button - type={ButtonType.Secondary} - fullWidth - onClick={handleUnstake} - disabled={isPending || !delegationId} - text="Unstake" - icon={ - isPending ? ( - <Loader className="animate-spin" data-testid="loading-indicator" /> - ) : null - } - iconAfterText - /> - </DialogLayoutFooter> - </DialogLayout> - ); -} diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/views/index.ts b/apps/wallet-dashboard/components/Dialogs/Staking/views/index.ts index 8ed3cfb4dee..685926f46f6 100644 --- a/apps/wallet-dashboard/components/Dialogs/Staking/views/index.ts +++ b/apps/wallet-dashboard/components/Dialogs/Staking/views/index.ts @@ -5,4 +5,3 @@ export { default as EnterAmountView } from './EnterAmountView'; export { default as EnterTimelockedAmountView } from './EnterTimelockedAmountView'; export { default as SelectValidatorView } from './SelectValidatorView'; export * from './DetailsView'; -export * from './UnstakeView'; diff --git a/apps/wallet-dashboard/components/Dialogs/TransactionDialog.tsx b/apps/wallet-dashboard/components/Dialogs/TransactionDialog.tsx index c1b6a845b01..8b78f53d190 100644 --- a/apps/wallet-dashboard/components/Dialogs/TransactionDialog.tsx +++ b/apps/wallet-dashboard/components/Dialogs/TransactionDialog.tsx @@ -46,7 +46,9 @@ export function TransactionDialogView({ renderValidatorLogo={Validator} /> ) : ( - <LoadingIndicator /> + <div className="flex h-full w-full justify-center"> + <LoadingIndicator /> + </div> )} </DialogLayoutBody> <DialogLayoutFooter> diff --git a/apps/wallet-dashboard/components/Dialogs/index.ts b/apps/wallet-dashboard/components/Dialogs/index.ts index 97ee2fabbad..3987a39aabf 100644 --- a/apps/wallet-dashboard/components/Dialogs/index.ts +++ b/apps/wallet-dashboard/components/Dialogs/index.ts @@ -4,4 +4,5 @@ export * from './SendToken'; export * from './ReceiveFundsDialog'; export * from './Staking'; +export * from './unstake'; export * from './vesting'; diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/UnstakeDialog.tsx b/apps/wallet-dashboard/components/Dialogs/unstake/UnstakeDialog.tsx new file mode 100644 index 00000000000..16ef52b41bb --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/unstake/UnstakeDialog.tsx @@ -0,0 +1,56 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Dialog } from '@iota/apps-ui-kit'; +import { UnstakeTimelockedObjectsView, UnstakeView } from './views'; +import { ExtendedDelegatedStake } from '@iota/core'; +import { TimelockedStakedObjectsGrouped } from '@/lib/utils'; +import { UnstakeDialogView } from './enums'; +import { IotaSignAndExecuteTransactionOutput } from '@iota/wallet-standard'; +import { TransactionDialogView } from '../TransactionDialog'; + +interface UnstakeDialogProps { + view: UnstakeDialogView; + handleClose: () => void; + onSuccess: (tx: IotaSignAndExecuteTransactionOutput) => void; + onBack?: (view: UnstakeDialogView) => (() => void) | undefined; + groupedTimelockedObjects?: TimelockedStakedObjectsGrouped; + extendedStake?: ExtendedDelegatedStake; + txDigest?: string; +} + +export function UnstakeDialog({ + view, + handleClose, + onSuccess, + extendedStake, + groupedTimelockedObjects, + onBack, + txDigest, +}: UnstakeDialogProps): React.JSX.Element { + return ( + <Dialog open onOpenChange={handleClose}> + {view === UnstakeDialogView.Unstake && extendedStake && ( + <UnstakeView + extendedStake={extendedStake} + handleClose={handleClose} + onBack={onBack?.(UnstakeDialogView.Unstake)} + showActiveStatus + onSuccess={onSuccess} + /> + )} + + {view === UnstakeDialogView.TimelockedUnstake && groupedTimelockedObjects && ( + <UnstakeTimelockedObjectsView + onClose={handleClose} + groupedTimelockedObjects={groupedTimelockedObjects} + onBack={onBack?.(UnstakeDialogView.TimelockedUnstake)} + onSuccess={onSuccess} + /> + )} + {view === UnstakeDialogView.TransactionDetails && ( + <TransactionDialogView txDigest={txDigest} onClose={handleClose} /> + )} + </Dialog> + ); +} diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/enums/index.ts b/apps/wallet-dashboard/components/Dialogs/unstake/enums/index.ts new file mode 100644 index 00000000000..75ff18fcbaf --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/unstake/enums/index.ts @@ -0,0 +1,4 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export * from './views.enums'; diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/enums/views.enums.ts b/apps/wallet-dashboard/components/Dialogs/unstake/enums/views.enums.ts new file mode 100644 index 00000000000..1b0b313dcce --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/unstake/enums/views.enums.ts @@ -0,0 +1,8 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export enum UnstakeDialogView { + Unstake = 'unstake', + TimelockedUnstake = 'timelockedUnstake', + TransactionDetails = 'transactionDetails', +} diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/hooks/index.ts b/apps/wallet-dashboard/components/Dialogs/unstake/hooks/index.ts new file mode 100644 index 00000000000..8834415eafd --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/unstake/hooks/index.ts @@ -0,0 +1,4 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export * from './useUnstakeDialog'; diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/hooks/useUnstakeDialog.ts b/apps/wallet-dashboard/components/Dialogs/unstake/hooks/useUnstakeDialog.ts new file mode 100644 index 00000000000..88de6c40f25 --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/unstake/hooks/useUnstakeDialog.ts @@ -0,0 +1,41 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { ComponentProps, useState } from 'react'; +import { UnstakeDialogView } from '../enums'; +import type { UnstakeDialog } from '../UnstakeDialog'; + +export function useUnstakeDialog() { + const [isOpen, setIsOpen] = useState(false); + const [view, setView] = useState<UnstakeDialogView>(UnstakeDialogView.Unstake); + const [txDigest, setTxDigest] = useState<string | undefined>(); + + function openUnstakeDialog(view?: UnstakeDialogView) { + setIsOpen(true); + if (view) { + setView(view); + } + } + + function handleClose() { + setIsOpen(false); + } + + const defaultDialogProps: Omit<ComponentProps<typeof UnstakeDialog>, 'onSuccess'> = { + view, + handleClose: () => setIsOpen(false), + txDigest, + }; + + return { + isOpen, + setIsOpen, + view, + setView, + openUnstakeDialog, + txDigest, + setTxDigest, + defaultDialogProps, + handleClose, + }; +} diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/index.ts b/apps/wallet-dashboard/components/Dialogs/unstake/index.ts new file mode 100644 index 00000000000..05b9b934af5 --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/unstake/index.ts @@ -0,0 +1,8 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export * from './views'; +export * from './enums'; +export * from './hooks'; + +export * from './UnstakeDialog'; diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeTimelockedObjectsView.tsx b/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeTimelockedObjectsView.tsx new file mode 100644 index 00000000000..45e34ee5cf0 --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeTimelockedObjectsView.tsx @@ -0,0 +1,213 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { StakeRewardsPanel, ValidatorStakingData } from '@/components'; +import { DialogLayout, DialogLayoutBody, DialogLayoutFooter } from '../../layout'; +import { Validator } from '../../Staking/views/Validator'; +import { useNewUnstakeTimelockedTransaction, useNotifications } from '@/hooks'; +import { + Collapsible, + TimeUnit, + useFormatCoin, + useGetActiveValidatorsInfo, + useTimeAgo, +} from '@iota/core'; +import { ExtendedDelegatedTimelockedStake, TimelockedStakedObjectsGrouped } from '@/lib/utils'; +import { formatAddress, IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; +import { + Panel, + LoadingIndicator, + KeyValueInfo, + Header, + ButtonType, + Button, +} from '@iota/apps-ui-kit'; +import { useCurrentAccount, useSignAndExecuteTransaction } from '@iota/dapp-kit'; +import { IotaSignAndExecuteTransactionOutput } from '@iota/wallet-standard'; +import { NotificationType } from '@/stores/notificationStore'; + +interface UnstakeTimelockedObjectsViewProps { + onClose: () => void; + groupedTimelockedObjects: TimelockedStakedObjectsGrouped; + onSuccess: (tx: IotaSignAndExecuteTransactionOutput) => void; + onBack?: () => void; +} + +export function UnstakeTimelockedObjectsView({ + groupedTimelockedObjects, + onClose, + onBack, + onSuccess, +}: UnstakeTimelockedObjectsViewProps) { + const { addNotification } = useNotifications(); + const activeAddress = useCurrentAccount()?.address ?? ''; + const { data: activeValidators } = useGetActiveValidatorsInfo(); + + const stakes = groupedTimelockedObjects.stakes; + const timelockedStakedIotaIds = stakes.map((stake) => stake.timelockedStakedIotaId); + + const { data: unstakeData, isPending: isUnstakeTxPending } = useNewUnstakeTimelockedTransaction( + activeAddress, + timelockedStakedIotaIds, + ); + const { mutateAsync: signAndExecuteTransaction, isPending: isTransactionPending } = + useSignAndExecuteTransaction(); + + const validatorInfo = activeValidators?.find( + ({ iotaAddress: validatorAddress }) => + validatorAddress === groupedTimelockedObjects.validatorAddress, + ); + + const stakeId = stakes[0].timelockedStakedIotaId; + const totalStakedAmount = stakes.reduce((acc, stake) => acc + parseInt(stake.principal), 0); + const totalRewards = stakes.reduce( + (acc, stake) => acc + (stake.status === 'Active' ? parseInt(stake.estimatedReward) : 0), + 0, + ); + + const [rewardsPoolFormatted, rewardsToken] = useFormatCoin( + validatorInfo?.rewardsPool, + IOTA_TYPE_ARG, + ); + + function handleCopySuccess() { + addNotification('Copied to clipboard'); + } + + async function handleUnstake(): Promise<void> { + if (!unstakeData) return; + + await signAndExecuteTransaction( + { + transaction: unstakeData.transaction, + }, + { + onSuccess: (tx) => { + addNotification('Unstake transaction has been sent'); + onSuccess(tx); + }, + }, + ).catch(() => { + addNotification('Unstake transaction was not sent', NotificationType.Error); + }); + } + + return ( + <DialogLayout> + <Header title="Unstake" onClose={onClose} onBack={onBack} /> + <DialogLayoutBody> + <div className="flex flex-col gap-md"> + <Validator + address={groupedTimelockedObjects.validatorAddress} + isSelected + showActiveStatus + /> + + {stakeId && ( + <ValidatorStakingData + key={stakeId} + validatorAddress={groupedTimelockedObjects.validatorAddress} + stakeId={stakeId} + isUnstake + /> + )} + + <StakeRewardsPanel + stakingRewards={totalRewards} + totalStaked={totalStakedAmount} + isTimelocked + /> + + <Panel hasBorder> + <div className="flex flex-col gap-y-sm p-md"> + <KeyValueInfo + keyText="Stake Request Epoch" + value={groupedTimelockedObjects.stakeRequestEpoch} + fullwidth + /> + {rewardsPoolFormatted && ( + <KeyValueInfo + keyText="Rewards Pool" + value={rewardsPoolFormatted} + supportingLabel={rewardsToken} + fullwidth + /> + )} + <KeyValueInfo keyText="Total Stakes" value={stakes.length} fullwidth /> + </div> + </Panel> + + {stakes.map((stake, index) => ( + <TimelockedStakeCollapsible + title={`Stake Nº${index + 1}`} + key={stake.timelockedStakedIotaId} + stake={stake} + handleCopySuccess={handleCopySuccess} + /> + ))} + </div> + </DialogLayoutBody> + <DialogLayoutFooter> + <Button + onClick={handleUnstake} + text="Unstake" + icon={!unstakeData || isUnstakeTxPending ? <LoadingIndicator /> : undefined} + disabled={!unstakeData || isTransactionPending || isUnstakeTxPending} + type={ButtonType.Secondary} + fullWidth + /> + </DialogLayoutFooter> + </DialogLayout> + ); +} + +interface TimelockedStakeCollapsibleProps { + stake: ExtendedDelegatedTimelockedStake; + title: string; + handleCopySuccess: () => void; +} +function TimelockedStakeCollapsible({ + stake, + title, + handleCopySuccess, +}: TimelockedStakeCollapsibleProps) { + const currentEpochEndTimeAgo = useTimeAgo({ + timeFrom: Number(stake.expirationTimestampMs), + endLabel: '--', + shortedTimeLabel: false, + shouldEnd: true, + maxTimeUnit: TimeUnit.ONE_DAY, + }); + return ( + <Collapsible defaultOpen key={stake.timelockedStakedIotaId} title={title}> + <Panel> + <div className="flex flex-col gap-y-sm p-md--rs py-sm"> + <KeyValueInfo + keyText="Stake ID" + value={formatAddress(stake.timelockedStakedIotaId)} + valueHoverTitle={stake.timelockedStakedIotaId} + onCopySuccess={handleCopySuccess} + copyText={stake.timelockedStakedIotaId} + fullwidth + /> + <KeyValueInfo + keyText="Expiration time" + value={currentEpochEndTimeAgo} + fullwidth + /> + {stake.label && ( + <KeyValueInfo + keyText="Label" + value={formatAddress(stake.label)} + copyText={stake.label} + valueHoverTitle={stake.label} + onCopySuccess={handleCopySuccess} + fullwidth + /> + )} + <KeyValueInfo keyText="Status" value={stake.status} fullwidth /> + </div> + </Panel> + </Collapsible> + ); +} diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeView.tsx b/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeView.tsx new file mode 100644 index 00000000000..5d07eadcec3 --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeView.tsx @@ -0,0 +1,167 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { + Header, + Button, + KeyValueInfo, + ButtonType, + Panel, + LoadingIndicator, + InfoBoxType, + InfoBoxStyle, + InfoBox, +} from '@iota/apps-ui-kit'; +import { + ExtendedDelegatedStake, + GAS_SYMBOL, + useFormatCoin, + useGetStakingValidatorDetails, +} from '@iota/core'; +import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; +import { useCurrentAccount, useSignAndExecuteTransaction } from '@iota/dapp-kit'; +import { Warning } from '@iota/ui-icons'; +import { StakeRewardsPanel, ValidatorStakingData } from '@/components'; +import { DialogLayout, DialogLayoutFooter, DialogLayoutBody } from '../../layout'; +import { Validator } from '../../Staking/views/Validator'; +import { useNewUnstakeTransaction, useNotifications } from '@/hooks'; +import { IotaSignAndExecuteTransactionOutput } from '@iota/wallet-standard'; +import { NotificationType } from '@/stores/notificationStore'; + +interface UnstakeDialogProps { + extendedStake: ExtendedDelegatedStake; + handleClose: () => void; + onSuccess: (tx: IotaSignAndExecuteTransactionOutput) => void; + showActiveStatus?: boolean; + onBack?: () => void; +} + +export function UnstakeView({ + extendedStake, + handleClose, + onBack, + onSuccess, + showActiveStatus, +}: UnstakeDialogProps): JSX.Element { + const activeAddress = useCurrentAccount()?.address ?? ''; + const { addNotification } = useNotifications(); + const { data: unstakeData, isPending: isUnstakeTxPending } = useNewUnstakeTransaction( + activeAddress, + extendedStake.stakedIotaId, + ); + const [gasFormatted] = useFormatCoin(unstakeData?.gasBudget, IOTA_TYPE_ARG); + + const { mutateAsync: signAndExecuteTransaction, isPending: isTransactionPending } = + useSignAndExecuteTransaction(); + + const { totalStakeOriginal, systemDataResult, delegatedStakeDataResult } = + useGetStakingValidatorDetails({ + accountAddress: activeAddress, + validatorAddress: extendedStake.validatorAddress, + stakeId: extendedStake.stakedIotaId, + unstake: true, + }); + + const { isLoading: loadingValidators, error: errorValidators } = systemDataResult; + const { + isLoading: isLoadingDelegatedStakeData, + isError, + error: delegatedStakeDataError, + } = delegatedStakeDataResult; + + const delegationId = extendedStake?.stakedIotaId; + const isPreparingUnstake = !unstakeData || isUnstakeTxPending; + + async function handleUnstake(): Promise<void> { + if (!unstakeData) return; + + await signAndExecuteTransaction( + { + transaction: unstakeData.transaction, + }, + { + onSuccess: (tx) => { + addNotification('Unstake transaction has been sent'); + onSuccess(tx); + }, + }, + ).catch(() => { + addNotification('Unstake transaction was not sent', NotificationType.Error); + }); + } + + if (isLoadingDelegatedStakeData || loadingValidators) { + return ( + <div className="flex h-full w-full items-center justify-center p-2"> + <LoadingIndicator /> + </div> + ); + } + + if (isError || errorValidators) { + return ( + <div className="mb-2 flex h-full w-full items-center justify-center p-2"> + <InfoBox + title="Something went wrong" + supportingText={delegatedStakeDataError?.message ?? 'An error occurred'} + style={InfoBoxStyle.Default} + type={InfoBoxType.Error} + icon={<Warning />} + /> + </div> + ); + } + + return ( + <DialogLayout> + <Header title="Unstake" onClose={handleClose} onBack={onBack} titleCentered /> + <DialogLayoutBody> + <div className="flex flex-col gap-y-md"> + <Validator + address={extendedStake.validatorAddress} + isSelected + showActiveStatus={showActiveStatus} + /> + + <ValidatorStakingData + validatorAddress={extendedStake.validatorAddress} + stakeId={extendedStake.stakedIotaId} + isUnstake + /> + + <StakeRewardsPanel + stakingRewards={extendedStake.estimatedReward} + totalStaked={totalStakeOriginal} + /> + + <Panel hasBorder> + <div className="flex flex-col gap-y-sm p-md"> + <KeyValueInfo + keyText="Gas Fees" + value={gasFormatted || '-'} + supportingLabel={GAS_SYMBOL} + fullwidth + /> + </div> + </Panel> + </div> + </DialogLayoutBody> + + <DialogLayoutFooter> + <Button + type={ButtonType.Secondary} + fullWidth + onClick={handleUnstake} + disabled={isPreparingUnstake || isTransactionPending || !delegationId} + text="Unstake" + icon={ + isPreparingUnstake ? ( + <LoadingIndicator data-testid="loading-indicator" /> + ) : null + } + iconAfterText + /> + </DialogLayoutFooter> + </DialogLayout> + ); +} diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/views/index.ts b/apps/wallet-dashboard/components/Dialogs/unstake/views/index.ts new file mode 100644 index 00000000000..88b177871cd --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/unstake/views/index.ts @@ -0,0 +1,5 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export * from './UnstakeView'; +export * from './UnstakeTimelockedObjectsView'; diff --git a/apps/wallet-dashboard/components/Popup/Popups/SendAssetPopup.tsx b/apps/wallet-dashboard/components/Popup/Popups/SendAssetPopup.tsx deleted file mode 100644 index 679c4002d96..00000000000 --- a/apps/wallet-dashboard/components/Popup/Popups/SendAssetPopup.tsx +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -import React, { useCallback, useState } from 'react'; -import { IotaObjectData } from '@iota/iota-sdk/client'; -import { VisualAssetTile, Input } from '@/components'; -import { Button } from '@/components/Buttons'; -import { FlexDirection } from '@/lib/ui/enums'; -import { useCurrentAccount } from '@iota/dapp-kit'; -import { createNftSendValidationSchema, ValidationError } from '@iota/core'; -import { useRouter } from 'next/navigation'; -import { useNotifications } from '@/hooks'; -import { NotificationType } from '@/stores/notificationStore'; -import { useCreateSendAssetTransaction } from '@/hooks'; -import { ASSETS_ROUTE } from '@/lib/constants/routes.constants'; - -interface SendAssetPopupProps { - asset: IotaObjectData; - onClose: () => void; -} - -export default function SendAssetPopup({ asset, onClose }: SendAssetPopupProps): JSX.Element { - const [recipientAddress, setRecipientAddress] = useState<string>(''); - const [errors, setErrors] = useState<string[]>([]); - const activeAddress = useCurrentAccount()?.address; - const router = useRouter(); - const { addNotification } = useNotifications(); - const { mutation: sendAsset } = useCreateSendAssetTransaction( - asset.objectId, - onSendAssetSuccess, - onSendAssetError, - ); - - const schema = createNftSendValidationSchema(activeAddress || '', asset.objectId); - - async function handleAddressChange(address: string): Promise<void> { - setRecipientAddress(address); - - try { - await schema.validate({ to: address }); - setErrors([]); - } catch (error) { - if (error instanceof ValidationError) { - setErrors(error.errors); - } - } - } - - function onSendAssetSuccess() { - addNotification('Transfer transaction successful', NotificationType.Success); - onClose?.(); - router.push(ASSETS_ROUTE.path + '/assets'); - } - - function onSendAssetError() { - addNotification('Transfer transaction failed', NotificationType.Error); - onClose?.(); - } - - const handleSendAsset = useCallback(async () => { - try { - await sendAsset.mutateAsync(recipientAddress); - } catch (error) { - addNotification('Transfer transaction failed', NotificationType.Error); - } - }, [recipientAddress, sendAsset, addNotification]); - - return ( - <div className="flex flex-col space-y-4"> - <VisualAssetTile asset={asset} flexDirection={FlexDirection.Column} /> - <div className="flex flex-col space-y-2"> - <Input - type="text" - value={recipientAddress} - placeholder="Enter Address" - onChange={(e) => handleAddressChange(e.target.value)} - label="Enter recipient address" - error={errors[0]} - /> - </div> - <Button onClick={handleSendAsset}>Send</Button> - <Button onClick={onClose}>Cancel</Button> - </div> - ); -} diff --git a/apps/wallet-dashboard/components/Popup/Popups/UnstakePopup.tsx b/apps/wallet-dashboard/components/Popup/Popups/UnstakePopup.tsx deleted file mode 100644 index 0518809fced..00000000000 --- a/apps/wallet-dashboard/components/Popup/Popups/UnstakePopup.tsx +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -import React from 'react'; -import { Button } from '@/components'; -import { useUnstakeTransaction } from '@/hooks'; -import { useCurrentAccount, useSignAndExecuteTransaction } from '@iota/dapp-kit'; -import { ExtendedDelegatedStake } from '@iota/core'; - -interface UnstakePopupProps { - extendedStake: ExtendedDelegatedStake; - closePopup: () => void; -} - -function UnstakePopup({ extendedStake, closePopup }: UnstakePopupProps): JSX.Element { - const account = useCurrentAccount(); - const { data: unstakeData } = useUnstakeTransaction( - extendedStake.stakedIotaId, - account?.address || '', - ); - const { mutateAsync: signAndExecuteTransaction, isPending } = useSignAndExecuteTransaction(); - - async function handleUnstake(): Promise<void> { - if (!unstakeData) return; - await signAndExecuteTransaction({ - transaction: unstakeData.transaction, - }); - closePopup(); - } - - return ( - <div className="flex min-w-[300px] flex-col gap-2"> - <p>Stake ID: {extendedStake.stakedIotaId}</p> - <p>Validator: {extendedStake.validatorAddress}</p> - <p>Stake: {extendedStake.principal}</p> - {extendedStake.status === 'Active' && ( - <p>Estimated reward: {extendedStake.estimatedReward}</p> - )} - <p>Gas Fees: {unstakeData?.gasBudget?.toString() || '--'}</p> - {isPending ? ( - <Button disabled>Loading...</Button> - ) : ( - <Button onClick={handleUnstake}>Confirm Unstake</Button> - )} - </div> - ); -} - -export default UnstakePopup; diff --git a/apps/wallet-dashboard/components/Popup/Popups/VestingPopup/TimelockedUnstakePopup.tsx b/apps/wallet-dashboard/components/Popup/Popups/VestingPopup/TimelockedUnstakePopup.tsx deleted file mode 100644 index 9cfdc96f035..00000000000 --- a/apps/wallet-dashboard/components/Popup/Popups/VestingPopup/TimelockedUnstakePopup.tsx +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -import React from 'react'; -import { Button } from '@/components'; -import { useNotifications, useTimelockedUnstakeTransaction } from '@/hooks'; -import { useSignAndExecuteTransaction } from '@iota/dapp-kit'; -import { IotaValidatorSummary } from '@iota/iota-sdk/client'; -import { NotificationType } from '@/stores/notificationStore'; -import { TimelockedStakedObjectsGrouped } from '@/lib/utils'; - -interface UnstakePopupProps { - accountAddress: string; - delegatedStake: TimelockedStakedObjectsGrouped; - validatorInfo: IotaValidatorSummary; - closePopup: () => void; - onSuccess?: (digest: string) => void; -} - -function TimelockedUnstakePopup({ - accountAddress, - delegatedStake, - validatorInfo, - closePopup, - onSuccess, -}: UnstakePopupProps): JSX.Element { - const objectIds = delegatedStake.stakes.map((stake) => stake.timelockedStakedIotaId); - const { data: timelockedUnstake } = useTimelockedUnstakeTransaction(objectIds, accountAddress); - const { mutateAsync: signAndExecuteTransaction, isPending } = useSignAndExecuteTransaction(); - const { addNotification } = useNotifications(); - - async function handleTimelockedUnstake(): Promise<void> { - if (!timelockedUnstake) return; - signAndExecuteTransaction( - { - transaction: timelockedUnstake.transaction, - }, - { - onSuccess: (tx) => { - if (onSuccess) { - onSuccess(tx.digest); - } - }, - }, - ) - .then(() => { - closePopup(); - addNotification('Unstake transaction has been sent'); - }) - .catch(() => { - addNotification('Unstake transaction was not sent', NotificationType.Error); - }); - } - - return ( - <div className="flex min-w-[300px] flex-col gap-2"> - <p>Validator Name: {validatorInfo.name}</p> - <p>Validator Address: {delegatedStake.validatorAddress}</p> - <p>Stake Request Epoch: {delegatedStake.stakeRequestEpoch}</p> - <p>Rewards: {validatorInfo.rewardsPool}</p> - <p>Total Stakes: {delegatedStake.stakes.length}</p> - {delegatedStake.stakes.map((stake, index) => { - return ( - <div key={stake.timelockedStakedIotaId} className="m-4 flex flex-col"> - <span> - Stake {index + 1}: {stake.timelockedStakedIotaId} - </span> - <span>Expiration time: {stake.expirationTimestampMs}</span> - <span>Label: {stake.label}</span> - <span>Status: {stake.status}</span> - </div> - ); - })} - <p>Gas Fees: {timelockedUnstake?.gasBudget?.toString() || '--'}</p> - {isPending ? ( - <Button disabled>Loading...</Button> - ) : ( - <Button onClick={handleTimelockedUnstake}>Confirm Unstake</Button> - )} - </div> - ); -} - -export default TimelockedUnstakePopup; diff --git a/apps/wallet-dashboard/components/Popup/Popups/VestingPopup/index.ts b/apps/wallet-dashboard/components/Popup/Popups/VestingPopup/index.ts deleted file mode 100644 index 2a8ca3b61df..00000000000 --- a/apps/wallet-dashboard/components/Popup/Popups/VestingPopup/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -export { default as TimelockedUnstakePopup } from './TimelockedUnstakePopup'; diff --git a/apps/wallet-dashboard/components/Popup/Popups/index.ts b/apps/wallet-dashboard/components/Popup/Popups/index.ts deleted file mode 100644 index ebdfc7f7391..00000000000 --- a/apps/wallet-dashboard/components/Popup/Popups/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -export { default as UnstakePopup } from './UnstakePopup'; -export { default as SendAssetPopup } from './SendAssetPopup'; - -export * from './VestingPopup'; diff --git a/apps/wallet-dashboard/components/Popup/index.ts b/apps/wallet-dashboard/components/Popup/index.ts index baeafee23a7..8acf67167f9 100644 --- a/apps/wallet-dashboard/components/Popup/index.ts +++ b/apps/wallet-dashboard/components/Popup/index.ts @@ -3,5 +3,3 @@ export { default as Popup } from './Popup'; export { default as PopupProvider } from './PopupProvider'; - -export * from './Popups'; diff --git a/apps/wallet-dashboard/components/StakeRewardsPanel.tsx b/apps/wallet-dashboard/components/StakeRewardsPanel.tsx new file mode 100644 index 00000000000..a7e5e84619c --- /dev/null +++ b/apps/wallet-dashboard/components/StakeRewardsPanel.tsx @@ -0,0 +1,70 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Divider, KeyValueInfo, Panel } from '@iota/apps-ui-kit'; +import { TimeUnit, useFormatCoin, useGetTimeBeforeEpochNumber, useTimeAgo } from '@iota/core'; +import { useIotaClientQuery } from '@iota/dapp-kit'; +import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; + +interface StakeRewardsPanelProps { + stakingRewards: string | number | undefined; + totalStaked: number | bigint; + isTimelocked?: boolean; +} +export function StakeRewardsPanel({ + stakingRewards, + totalStaked, + isTimelocked, +}: StakeRewardsPanelProps) { + const { epoch = '0' } = useIotaClientQuery('getLatestIotaSystemState')?.data || {}; + const [rewards, symbol] = useFormatCoin(stakingRewards ?? 0, IOTA_TYPE_ARG); + const [stakedBalance] = useFormatCoin(totalStaked, IOTA_TYPE_ARG); + const [stakedAndRewards] = useFormatCoin( + BigInt(stakingRewards || 0) + BigInt(totalStaked), + IOTA_TYPE_ARG, + ); + + const { data: currentEpochEndTime } = useGetTimeBeforeEpochNumber(Number(epoch) + 1); + const currentEpochEndTimeAgo = useTimeAgo({ + timeFrom: currentEpochEndTime, + endLabel: '--', + shortedTimeLabel: false, + shouldEnd: true, + maxTimeUnit: TimeUnit.ONE_HOUR, + }); + + const currentEpochEndTimeFormatted = + currentEpochEndTime > 0 ? currentEpochEndTimeAgo : `Epoch #${epoch}`; + + return ( + <Panel hasBorder> + <div className="flex flex-col gap-y-sm p-md"> + <KeyValueInfo + keyText="Current Epoch Ends" + value={currentEpochEndTimeFormatted} + fullwidth + /> + <Divider /> + <KeyValueInfo + keyText="Your Stake" + value={stakedBalance} + supportingLabel={symbol} + fullwidth + /> + <KeyValueInfo + keyText="Rewards Earned" + value={rewards} + supportingLabel={symbol} + fullwidth + /> + <Divider /> + <KeyValueInfo + keyText={'Total unstaked ' + (isTimelocked ? 'Timelocked' : 'IOTA')} + value={stakedAndRewards} + supportingLabel={symbol} + fullwidth + /> + </div> + </Panel> + ); +} diff --git a/apps/wallet-dashboard/components/index.ts b/apps/wallet-dashboard/components/index.ts index 1e655a49bdc..f85f12e1beb 100644 --- a/apps/wallet-dashboard/components/index.ts +++ b/apps/wallet-dashboard/components/index.ts @@ -26,5 +26,6 @@ export * from './tiles'; export * from './migration'; export * from './Toaster'; export * from './Banner'; +export * from './StakeRewardsPanel'; export * from './MigrationOverview'; export * from './staked-timelock-object'; diff --git a/apps/wallet-dashboard/components/staking-overview/StartStaking.tsx b/apps/wallet-dashboard/components/staking-overview/StartStaking.tsx index 828abc974ab..573a254a3d2 100644 --- a/apps/wallet-dashboard/components/staking-overview/StartStaking.tsx +++ b/apps/wallet-dashboard/components/staking-overview/StartStaking.tsx @@ -35,7 +35,6 @@ export function StartStaking() { {isDialogStakeOpen && stakeDialogView && ( <StakeDialog stakedDetails={selectedStake} - isOpen={isDialogStakeOpen} handleClose={handleCloseStakeDialog} view={stakeDialogView} setView={setStakeDialogView} diff --git a/apps/wallet-dashboard/components/staking-overview/index.ts b/apps/wallet-dashboard/components/staking-overview/index.ts index 88d8d1794ef..a2fdb941d58 100644 --- a/apps/wallet-dashboard/components/staking-overview/index.ts +++ b/apps/wallet-dashboard/components/staking-overview/index.ts @@ -2,3 +2,4 @@ // SPDX-License-Identifier: Apache-2.0 export * from './StakingOverview'; +export * from './StartStaking'; diff --git a/apps/wallet-dashboard/hooks/index.ts b/apps/wallet-dashboard/hooks/index.ts index f33eda9c3fc..2bb5d86ba7e 100644 --- a/apps/wallet-dashboard/hooks/index.ts +++ b/apps/wallet-dashboard/hooks/index.ts @@ -1,7 +1,7 @@ // Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -export * from './useUnstakeTransaction'; +export * from './useNewUnstakeTransaction'; export * from './usePopups'; export * from './useNewStakeTransaction'; export * from './useNotifications'; diff --git a/apps/wallet-dashboard/hooks/useNewStakeTransaction.ts b/apps/wallet-dashboard/hooks/useNewStakeTransaction.ts index 7bd856cf77d..3e45ccd6144 100644 --- a/apps/wallet-dashboard/hooks/useNewStakeTransaction.ts +++ b/apps/wallet-dashboard/hooks/useNewStakeTransaction.ts @@ -9,26 +9,54 @@ import { import { useIotaClient } from '@iota/dapp-kit'; import { useQuery } from '@tanstack/react-query'; -export function useNewStakeTransaction( +export function useNewStakeTransaction(validator: string, amount: bigint, senderAddress: string) { + const client = useIotaClient(); + return useQuery({ + // eslint-disable-next-line @tanstack/query/exhaustive-deps + queryKey: ['stake-transaction', validator, amount.toString(), senderAddress], + queryFn: async () => { + const transaction = createStakeTransaction(amount, validator); + transaction.setSender(senderAddress); + await transaction.build({ client }); + return transaction; + }, + enabled: !!amount && !!validator && !!senderAddress, + gcTime: 0, + select: (transaction) => { + return { + transaction, + gasBudget: transaction.getData().gasData.budget, + }; + }, + }); +} + +export function useNewStakeTimelockedTransaction( validator: string, - amount: bigint, senderAddress: string, - isTimelockedStaking: boolean = false, - groupedTimelockObjects?: GroupedTimelockObject[], + groupedTimelockObjects: GroupedTimelockObject[], ) { + const amount = groupedTimelockObjects.reduce( + (acc, obj) => acc + (obj.totalLockedAmount - (obj.splitAmount ?? 0n)), + 0n, + ); const client = useIotaClient(); return useQuery({ // eslint-disable-next-line @tanstack/query/exhaustive-deps - queryKey: ['stake-transaction', validator, amount.toString(), senderAddress], + queryKey: [ + 'stake-timelocked-transaction', + validator, + senderAddress, + amount.toString(), + groupedTimelockObjects.length, + ], queryFn: async () => { - const transaction = isTimelockedStaking - ? createTimelockedStakeTransaction(groupedTimelockObjects || [], validator) - : createStakeTransaction(amount, validator); + const transaction = createTimelockedStakeTransaction(groupedTimelockObjects, validator); transaction.setSender(senderAddress); await transaction.build({ client }); return transaction; }, - enabled: !!amount && !!validator && !!senderAddress, + enabled: !!(validator && senderAddress && groupedTimelockObjects?.length), gcTime: 0, select: (transaction) => { return { diff --git a/apps/wallet-dashboard/hooks/useNewUnstakeTransaction.ts b/apps/wallet-dashboard/hooks/useNewUnstakeTransaction.ts new file mode 100644 index 00000000000..5704507f448 --- /dev/null +++ b/apps/wallet-dashboard/hooks/useNewUnstakeTransaction.ts @@ -0,0 +1,55 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { createTimelockedUnstakeTransaction, createUnstakeTransaction } from '@iota/core'; +import { useIotaClient } from '@iota/dapp-kit'; +import { useQuery } from '@tanstack/react-query'; + +export function useNewUnstakeTransaction(senderAddress: string, unstakeIotaId: string) { + const client = useIotaClient(); + + return useQuery({ + // eslint-disable-next-line @tanstack/query/exhaustive-deps + queryKey: ['unstake-transaction', unstakeIotaId, senderAddress], + queryFn: async () => { + const transaction = createUnstakeTransaction(unstakeIotaId); + transaction.setSender(senderAddress); + await transaction.build({ client }); + return transaction; + }, + enabled: !!(senderAddress && unstakeIotaId), + gcTime: 0, + select: (transaction) => { + return { + transaction, + gasBudget: transaction.getData().gasData.budget, + }; + }, + }); +} + +export function useNewUnstakeTimelockedTransaction( + senderAddress: string, + timelockedUnstakeIotaIds: string[], +) { + const client = useIotaClient(); + + return useQuery({ + // eslint-disable-next-line @tanstack/query/exhaustive-deps + queryKey: ['timelocked-unstake-transaction', timelockedUnstakeIotaIds, senderAddress], + queryFn: async () => { + const transaction = createTimelockedUnstakeTransaction(timelockedUnstakeIotaIds); + transaction.setSender(senderAddress); + await transaction.build({ client }); + return transaction; + }, + enabled: !!(senderAddress && timelockedUnstakeIotaIds?.length), + gcTime: 0, + select: (transaction) => { + return { + transaction, + gasBudget: transaction.getData().gasData.budget, + }; + }, + }); +} diff --git a/apps/wallet-dashboard/hooks/useUnstakeTransaction.ts b/apps/wallet-dashboard/hooks/useUnstakeTransaction.ts deleted file mode 100644 index 9f8644eda4c..00000000000 --- a/apps/wallet-dashboard/hooks/useUnstakeTransaction.ts +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -import { createUnstakeTransaction } from '@iota/core'; -import { useIotaClient } from '@iota/dapp-kit'; -import { useQuery } from '@tanstack/react-query'; - -export function useUnstakeTransaction(stakedIotaId: string, senderAddress: string) { - const client = useIotaClient(); - return useQuery({ - // eslint-disable-next-line @tanstack/query/exhaustive-deps - queryKey: ['unstake-transaction', stakedIotaId, senderAddress], - queryFn: async () => { - const transaction = createUnstakeTransaction(stakedIotaId); - transaction.setSender(senderAddress); - await transaction.build({ client }); - return transaction; - }, - enabled: !!stakedIotaId && !!senderAddress, - gcTime: 0, - select: (transaction) => { - return { - transaction, - gasBudget: transaction.getData().gasData.budget, - }; - }, - }); -} diff --git a/apps/wallet-dashboard/package.json b/apps/wallet-dashboard/package.json index 3cf781bca2f..dfa1df8a693 100644 --- a/apps/wallet-dashboard/package.json +++ b/apps/wallet-dashboard/package.json @@ -22,6 +22,7 @@ "@iota/dapp-kit": "workspace:*", "@iota/iota-sdk": "workspace:*", "@iota/ui-icons": "workspace:*", + "@iota/wallet-standard": "workspace:*", "@tanstack/react-query": "^5.50.1", "@tanstack/react-virtual": "^3.5.0", "clsx": "^2.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6aba893215d..19bc39c4bca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,13 +60,13 @@ importers: version: 9.1.0(eslint@8.57.1) eslint-import-resolver-typescript: specifier: ^3.6.1 - version: 3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1) + version: 3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-header: specifier: ^3.1.1 version: 3.1.1(eslint@8.57.1) eslint-plugin-import: specifier: ^2.29.1 - version: 2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + version: 2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-license-check: specifier: link:linting/license-check version: link:linting/license-check @@ -145,7 +145,7 @@ importers: devDependencies: '@nestjs/cli': specifier: ^10.0.0 - version: 10.4.5(@swc/core@1.7.28) + version: 10.4.5(@swc/core@1.7.28(@swc/helpers@0.5.5)) '@nestjs/schematics': specifier: ^10.0.0 version: 10.1.4(chokidar@3.6.0)(typescript@5.6.2) @@ -181,7 +181,7 @@ importers: version: 5.2.1(@types/eslint@8.56.12)(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.3.3) jest: specifier: ^29.5.0 - version: 29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@types/node@20.16.9)(typescript@5.6.2)) + version: 29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)) prettier: specifier: ^3.3.1 version: 3.3.3 @@ -193,13 +193,13 @@ importers: version: 6.3.4 ts-jest: specifier: ^29.1.0 - version: 29.2.5(@babel/core@7.25.2)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.2))(jest@29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@types/node@20.16.9)(typescript@5.6.2)))(typescript@5.6.2) + version: 29.2.5(@babel/core@7.25.2)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.2))(jest@29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)))(typescript@5.6.2) ts-loader: specifier: ^9.4.4 - version: 9.5.1(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28)) + version: 9.5.1(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) ts-node: specifier: ^10.9.1 - version: 10.9.2(@swc/core@1.7.28)(@types/node@20.16.9)(typescript@5.6.2) + version: 10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2) tsconfig-paths: specifier: ^4.2.0 version: 4.2.0 @@ -278,13 +278,13 @@ importers: devDependencies: '@headlessui/tailwindcss': specifier: ^0.1.3 - version: 0.1.3(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2))) + version: 0.1.3(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2))) '@tailwindcss/aspect-ratio': specifier: ^0.4.2 - version: 0.4.2(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2))) + version: 0.4.2(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2))) '@tailwindcss/forms': specifier: ^0.5.7 - version: 0.5.9(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2))) + version: 0.5.9(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2))) '@types/react': specifier: ^18.3.3 version: 18.3.9 @@ -296,7 +296,7 @@ importers: version: 8.4.47 tailwindcss: specifier: ^3.3.3 - version: 3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2)) + version: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2)) typescript: specifier: ^5.5.3 version: 5.6.2 @@ -519,7 +519,7 @@ importers: version: 2.0.8 tailwindcss: specifier: ^3.3.3 - version: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28)(@types/node@20.16.9)(typescript@5.6.2)) + version: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)) tsconfig-paths: specifier: ^4.2.0 version: 4.2.0 @@ -646,7 +646,7 @@ importers: version: 4.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@7.6.20) tailwindcss: specifier: ^3.3.3 - version: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28)(@types/node@20.16.9)(typescript@5.6.2)) + version: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)) typescript: specifier: ^5.5.3 version: 5.6.2 @@ -911,7 +911,7 @@ importers: version: 0.10.7 '@types/webpack': specifier: ^5.28.1 - version: 5.28.5(@swc/core@1.7.28)(webpack-cli@5.1.4(webpack@5.95.0)) + version: 5.28.5(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4(webpack@5.95.0)) '@types/zxcvbn': specifier: ^4.4.1 version: 4.4.5 @@ -920,19 +920,19 @@ importers: version: 4.3.1(vite@5.4.8(@types/node@20.16.9)(sass@1.79.3)(terser@5.34.0)) copy-webpack-plugin: specifier: ^11.0.0 - version: 11.0.0(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)) + version: 11.0.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) cross-env: specifier: ^7.0.3 version: 7.0.3 css-loader: specifier: ^6.7.3 - version: 6.11.0(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)) + version: 6.11.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) dotenv: specifier: ^16.4.5 version: 16.4.5 eslint-webpack-plugin: specifier: ^4.0.1 - version: 4.2.0(eslint@8.57.1)(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)) + version: 4.2.0(eslint@8.57.1)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) git-rev-sync: specifier: ^3.0.2 version: 3.0.2 @@ -941,10 +941,10 @@ importers: version: 15.11.7 html-webpack-plugin: specifier: ^5.5.3 - version: 5.6.0(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)) + version: 5.6.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) mini-css-extract-plugin: specifier: ^2.7.6 - version: 2.9.1(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)) + version: 2.9.1(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) onchange: specifier: ^7.1.0 version: 7.1.0 @@ -953,7 +953,7 @@ importers: version: 8.4.47 postcss-loader: specifier: ^7.3.3 - version: 7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)) + version: 7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) postcss-preset-env: specifier: ^9.0.0 version: 9.6.0(postcss@8.4.47) @@ -962,19 +962,19 @@ importers: version: 1.79.3 sass-loader: specifier: ^13.3.2 - version: 13.3.3(sass@1.79.3)(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)) + version: 13.3.3(sass@1.79.3)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) tailwindcss: specifier: ^3.3.3 - version: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28)(@types/node@20.16.9)(typescript@5.6.2)) + version: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)) tailwindcss-animate: specifier: ^1.0.7 - version: 1.0.7(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.28)(@types/node@20.16.9)(typescript@5.6.2))) + version: 1.0.7(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2))) ts-loader: specifier: ^9.4.4 - version: 9.5.1(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)) + version: 9.5.1(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) ts-node: specifier: ^10.9.1 - version: 10.9.2(@swc/core@1.7.28)(@types/node@20.16.9)(typescript@5.6.2) + version: 10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2) tsconfig-paths: specifier: ^4.2.0 version: 4.2.0 @@ -995,7 +995,7 @@ importers: version: 7.12.0(body-parser@1.20.3) webpack: specifier: ^5.79.0 - version: 5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4) + version: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) webpack-cli: specifier: ^5.0.1 version: 5.1.4(webpack@5.95.0) @@ -1026,6 +1026,9 @@ importers: '@iota/ui-icons': specifier: workspace:* version: link:../ui-icons + '@iota/wallet-standard': + specifier: workspace:* + version: link:../../sdk/wallet-standard '@tanstack/react-query': specifier: ^5.50.1 version: 5.56.2(react@18.3.1) @@ -1068,16 +1071,16 @@ importers: version: 14.2.3(eslint@8.57.1)(typescript@5.6.2) jest: specifier: ^29.5.0 - version: 29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@types/node@20.16.9)(typescript@5.6.2)) + version: 29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)) postcss: specifier: ^8.4.31 version: 8.4.47 tailwindcss: specifier: ^3.3.3 - version: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28)(@types/node@20.16.9)(typescript@5.6.2)) + version: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)) ts-jest: specifier: ^29.1.0 - version: 29.2.5(@babel/core@7.25.2)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.2))(jest@29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@types/node@20.16.9)(typescript@5.6.2)))(typescript@5.6.2) + version: 29.2.5(@babel/core@7.25.2)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.2))(jest@29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)))(typescript@5.6.2) typescript: specifier: ^5.5.3 version: 5.6.2 @@ -1117,7 +1120,7 @@ importers: devDependencies: '@headlessui/tailwindcss': specifier: ^0.1.3 - version: 0.1.3(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2))) + version: 0.1.3(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2))) '@types/react': specifier: ^18.3.3 version: 18.3.9 @@ -1135,7 +1138,7 @@ importers: version: 8.4.47 tailwindcss: specifier: ^3.3.3 - version: 3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2)) + version: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2)) typescript: specifier: ^5.5.3 version: 5.6.2 @@ -1229,7 +1232,7 @@ importers: devDependencies: '@tailwindcss/forms': specifier: ^0.5.7 - version: 0.5.9(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2))) + version: 0.5.9(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2))) '@tsconfig/docusaurus': specifier: ^2.0.3 version: 2.0.3 @@ -1250,10 +1253,10 @@ importers: version: 8.4.47 tailwindcss: specifier: ^3.3.3 - version: 3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2)) + version: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2)) tailwindcss-animate: specifier: ^1.0.7 - version: 1.0.7(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2))) + version: 1.0.7(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2))) typescript: specifier: ^5.5.3 version: 5.6.2 @@ -1299,7 +1302,7 @@ importers: version: 8.4.47 tailwindcss: specifier: ^3.3.3 - version: 3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2)) + version: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2)) typescript: specifier: ^5.5.3 version: 5.6.2 @@ -1320,25 +1323,25 @@ importers: version: 3.6.1(@algolia/client-search@4.24.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/core': specifier: 3.5.2 - version: 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + version: 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) '@docusaurus/preset-classic': specifier: 3.5.2 - version: 3.5.2(@algolia/client-search@4.24.0)(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + version: 3.5.2(@algolia/client-search@4.24.0)(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) '@docusaurus/remark-plugin-npm2yarn': specifier: ^3.5.2 version: 3.5.2 '@docusaurus/theme-common': specifier: ^3.5.2 - version: 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + version: 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/theme-live-codeblock': specifier: ^3.5.2 - version: 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + version: 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) '@docusaurus/theme-mermaid': specifier: ^3.5.2 - version: 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + version: 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) '@docusaurus/theme-search-algolia': specifier: ^3.5.2 - version: 3.5.2(@algolia/client-search@4.24.0)(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + version: 3.5.2(@algolia/client-search@4.24.0)(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) '@emotion/react': specifier: ^11.11.4 version: 11.13.3(@types/react@18.3.9)(react@18.3.1) @@ -1347,7 +1350,7 @@ importers: version: 11.13.0(@emotion/react@11.13.3(@types/react@18.3.9)(react@18.3.1))(@types/react@18.3.9)(react@18.3.1) '@graphql-markdown/docusaurus': specifier: ^1.24.1 - version: 1.26.2(@docusaurus/logger@3.5.2)(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(graphql-config@5.1.2(@types/node@22.7.3)(graphql@16.9.0)(typescript@5.6.2))(graphql@16.9.0)(prettier@3.3.3)(typescript@5.6.2) + version: 1.26.2(@docusaurus/logger@3.5.2)(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(graphql-config@5.1.2(@types/node@22.7.3)(graphql@16.9.0)(typescript@5.6.2))(graphql@16.9.0)(prettier@3.3.3)(typescript@5.6.2) '@graphql-tools/graphql-file-loader': specifier: ^8.0.1 version: 8.0.1(graphql@16.9.0) @@ -1383,7 +1386,7 @@ importers: version: 3.2.0 docusaurus-theme-search-typesense: specifier: 0.20.0-0 - version: 0.20.0-0(@algolia/client-search@4.24.0)(@babel/runtime@7.25.6)(@docusaurus/core@3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/theme-common@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.9)(algoliasearch@4.24.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + version: 0.20.0-0(iea5eyhbiud2dlcqtud2g4pxzm) dotenv: specifier: ^16.4.5 version: 16.4.5 @@ -1446,7 +1449,7 @@ importers: version: 6.0.0 tailwindcss: specifier: ^3.3.3 - version: 3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2)) + version: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2)) web3: specifier: ^4.2.2 version: 4.13.0(typescript@5.6.2)(zod@3.23.8) @@ -1456,13 +1459,13 @@ importers: version: 7.25.2(@babel/core@7.25.2) '@docusaurus/module-type-aliases': specifier: 3.5.2 - version: 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/tsconfig': specifier: 3.5.2 version: 3.5.2 '@docusaurus/types': specifier: 3.5.2 - version: 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@metamask/providers': specifier: ^10.2.1 version: 10.2.1 @@ -2040,7 +2043,7 @@ importers: version: 5.6.2 typescript-json-schema: specifier: ^0.64.0 - version: 0.64.0(@swc/core@1.7.28) + version: 0.64.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) packages: @@ -18518,7 +18521,7 @@ snapshots: transitivePeerDependencies: - '@algolia/client-search' - '@docusaurus/core@3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/core@3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': dependencies: '@babel/core': 7.25.2 '@babel/generator': 7.25.6 @@ -18532,12 +18535,12 @@ snapshots: '@babel/traverse': 7.25.6 '@docusaurus/cssnano-preset': 3.4.0 '@docusaurus/logger': 3.4.0 - '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) + '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) autoprefixer: 10.4.20(postcss@8.4.47) - babel-loader: 9.2.1(@babel/core@7.25.2)(webpack@5.95.0) + babel-loader: 9.2.1(@babel/core@7.25.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) babel-plugin-dynamic-import-node: 2.3.3 boxen: 6.2.1 chalk: 4.1.2 @@ -18546,34 +18549,34 @@ snapshots: cli-table3: 0.6.5 combine-promises: 1.2.0 commander: 5.1.0 - copy-webpack-plugin: 11.0.0(webpack@5.95.0) + copy-webpack-plugin: 11.0.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) core-js: 3.38.1 - css-loader: 6.11.0(webpack@5.95.0) - css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.95.0) + css-loader: 6.11.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) + css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) cssnano: 6.1.2(postcss@8.4.47) del: 6.1.1 detect-port: 1.6.1 escape-html: 1.0.3 eta: 2.2.0 eval: 0.1.8 - file-loader: 6.2.0(webpack@5.95.0) + file-loader: 6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) fs-extra: 11.2.0 html-minifier-terser: 7.2.0 html-tags: 3.3.1 - html-webpack-plugin: 5.6.0(webpack@5.95.0) + html-webpack-plugin: 5.6.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) leven: 3.1.0 lodash: 4.17.21 - mini-css-extract-plugin: 2.9.1(webpack@5.95.0) + mini-css-extract-plugin: 2.9.1(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) p-map: 4.0.0 postcss: 8.4.47 - postcss-loader: 7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0) + postcss-loader: 7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) prompts: 2.4.2 react: 18.3.1 - react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)(webpack@5.95.0) + react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) react-dom: 18.3.1(react@18.3.1) react-helmet-async: 1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' - react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.95.0) + react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) react-router: 5.3.4(react@18.3.1) react-router-config: 5.1.1(react-router@5.3.4(react@18.3.1))(react@18.3.1) react-router-dom: 5.3.4(react@18.3.1) @@ -18581,15 +18584,15 @@ snapshots: semver: 7.6.3 serve-handler: 6.1.5 shelljs: 0.8.5 - terser-webpack-plugin: 5.3.10(webpack@5.95.0) + terser-webpack-plugin: 5.3.10(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) tslib: 2.7.0 update-notifier: 6.0.2 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0) - webpack: 5.95.0 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) webpack-bundle-analyzer: 4.10.2 - webpack-dev-server: 4.15.2(webpack@5.95.0) + webpack-dev-server: 4.15.2(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) webpack-merge: 5.10.0 - webpackbar: 5.0.2(webpack@5.95.0) + webpackbar: 5.0.2(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) transitivePeerDependencies: - '@docusaurus/types' - '@parcel/css' @@ -18609,7 +18612,7 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/core@3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/core@3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': dependencies: '@babel/core': 7.25.2 '@babel/generator': 7.25.6 @@ -18623,13 +18626,13 @@ snapshots: '@babel/traverse': 7.25.6 '@docusaurus/cssnano-preset': 3.5.2 '@docusaurus/logger': 3.5.2 - '@docusaurus/mdx-loader': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/mdx-loader': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) + '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) '@mdx-js/react': 3.0.1(@types/react@18.3.9)(react@18.3.1) autoprefixer: 10.4.20(postcss@8.4.47) - babel-loader: 9.2.1(@babel/core@7.25.2)(webpack@5.95.0) + babel-loader: 9.2.1(@babel/core@7.25.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) babel-plugin-dynamic-import-node: 2.3.3 boxen: 6.2.1 chalk: 4.1.2 @@ -18638,34 +18641,34 @@ snapshots: cli-table3: 0.6.5 combine-promises: 1.2.0 commander: 5.1.0 - copy-webpack-plugin: 11.0.0(webpack@5.95.0) + copy-webpack-plugin: 11.0.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) core-js: 3.38.1 - css-loader: 6.11.0(webpack@5.95.0) - css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.95.0) + css-loader: 6.11.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) + css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) cssnano: 6.1.2(postcss@8.4.47) del: 6.1.1 detect-port: 1.6.1 escape-html: 1.0.3 eta: 2.2.0 eval: 0.1.8 - file-loader: 6.2.0(webpack@5.95.0) + file-loader: 6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) fs-extra: 11.2.0 html-minifier-terser: 7.2.0 html-tags: 3.3.1 - html-webpack-plugin: 5.6.0(webpack@5.95.0) + html-webpack-plugin: 5.6.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) leven: 3.1.0 lodash: 4.17.21 - mini-css-extract-plugin: 2.9.1(webpack@5.95.0) + mini-css-extract-plugin: 2.9.1(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) p-map: 4.0.0 postcss: 8.4.47 - postcss-loader: 7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0) + postcss-loader: 7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) prompts: 2.4.2 react: 18.3.1 - react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)(webpack@5.95.0) + react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) react-dom: 18.3.1(react@18.3.1) react-helmet-async: 1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' - react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.95.0) + react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) react-router: 5.3.4(react@18.3.1) react-router-config: 5.1.1(react-router@5.3.4(react@18.3.1))(react@18.3.1) react-router-dom: 5.3.4(react@18.3.1) @@ -18673,15 +18676,15 @@ snapshots: semver: 7.6.3 serve-handler: 6.1.5 shelljs: 0.8.5 - terser-webpack-plugin: 5.3.10(webpack@5.95.0) + terser-webpack-plugin: 5.3.10(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) tslib: 2.7.0 update-notifier: 6.0.2 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0) - webpack: 5.95.0 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) webpack-bundle-analyzer: 4.10.2 - webpack-dev-server: 4.15.2(webpack@5.95.0) + webpack-dev-server: 4.15.2(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) webpack-merge: 5.10.0 - webpackbar: 5.0.2(webpack@5.95.0) + webpackbar: 5.0.2(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) transitivePeerDependencies: - '@docusaurus/types' - '@parcel/css' @@ -18725,16 +18728,16 @@ snapshots: chalk: 4.1.2 tslib: 2.7.0 - '@docusaurus/mdx-loader@3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': + '@docusaurus/mdx-loader@3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: '@docusaurus/logger': 3.4.0 - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) + '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) '@mdx-js/mdx': 3.0.1 '@slorber/remark-comment': 1.0.0 escape-html: 1.0.3 estree-util-value-to-estree: 3.1.2 - file-loader: 6.2.0(webpack@5.95.0) + file-loader: 6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) fs-extra: 11.2.0 image-size: 1.1.1 mdast-util-mdx: 3.0.0 @@ -18750,9 +18753,9 @@ snapshots: tslib: 2.7.0 unified: 11.0.5 unist-util-visit: 5.0.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) vfile: 6.0.3 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) transitivePeerDependencies: - '@docusaurus/types' - '@swc/core' @@ -18762,16 +18765,16 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/mdx-loader@3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': + '@docusaurus/mdx-loader@3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: '@docusaurus/logger': 3.5.2 - '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) + '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) '@mdx-js/mdx': 3.0.1 '@slorber/remark-comment': 1.0.0 escape-html: 1.0.3 estree-util-value-to-estree: 3.1.2 - file-loader: 6.2.0(webpack@5.95.0) + file-loader: 6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) fs-extra: 11.2.0 image-size: 1.1.1 mdast-util-mdx: 3.0.0 @@ -18787,9 +18790,9 @@ snapshots: tslib: 2.7.0 unified: 11.0.5 unist-util-visit: 5.0.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) vfile: 6.0.3 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) transitivePeerDependencies: - '@docusaurus/types' - '@swc/core' @@ -18799,9 +18802,9 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/module-type-aliases@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/module-type-aliases@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/history': 4.7.11 '@types/react': 18.3.9 '@types/react-router-config': 5.0.11 @@ -18817,9 +18820,9 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/module-type-aliases@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/module-type-aliases@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/history': 4.7.11 '@types/react': 18.3.9 '@types/react-router-config': 5.0.11 @@ -18835,17 +18838,17 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/plugin-content-blog@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-content-blog@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) '@docusaurus/logger': 3.5.2 - '@docusaurus/mdx-loader': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/mdx-loader': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) + '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) cheerio: 1.0.0-rc.12 feed: 4.2.2 fs-extra: 11.2.0 @@ -18857,7 +18860,7 @@ snapshots: tslib: 2.7.0 unist-util-visit: 5.0.0 utility-types: 3.11.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) transitivePeerDependencies: - '@mdx-js/react' - '@parcel/css' @@ -18877,16 +18880,16 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-content-docs@3.4.0(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-content-docs@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) '@docusaurus/logger': 3.4.0 - '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/module-type-aliases': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/module-type-aliases': 3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) + '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) '@types/react-router-config': 5.0.11 combine-promises: 1.2.0 fs-extra: 11.2.0 @@ -18896,7 +18899,7 @@ snapshots: react-dom: 18.3.1(react@18.3.1) tslib: 2.7.0 utility-types: 3.11.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) transitivePeerDependencies: - '@parcel/css' - '@rspack/core' @@ -18915,17 +18918,17 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) '@docusaurus/logger': 3.5.2 - '@docusaurus/mdx-loader': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/module-type-aliases': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/mdx-loader': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/module-type-aliases': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) + '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) '@types/react-router-config': 5.0.11 combine-promises: 1.2.0 fs-extra: 11.2.0 @@ -18935,7 +18938,7 @@ snapshots: react-dom: 18.3.1(react@18.3.1) tslib: 2.7.0 utility-types: 3.11.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) transitivePeerDependencies: - '@mdx-js/react' - '@parcel/css' @@ -18955,18 +18958,18 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-content-pages@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-content-pages@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/mdx-loader': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/mdx-loader': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) + '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) fs-extra: 11.2.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) tslib: 2.7.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) transitivePeerDependencies: - '@mdx-js/react' - '@parcel/css' @@ -18986,11 +18989,11 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-debug@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-debug@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) fs-extra: 11.2.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -19015,11 +19018,11 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-google-analytics@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-google-analytics@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) tslib: 2.7.0 @@ -19042,11 +19045,11 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-google-gtag@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-google-gtag@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) '@types/gtag.js': 0.0.12 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -19070,11 +19073,11 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-google-tag-manager@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-google-tag-manager@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) tslib: 2.7.0 @@ -19097,14 +19100,14 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-sitemap@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-sitemap@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) '@docusaurus/logger': 3.5.2 - '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) + '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) fs-extra: 11.2.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -19129,21 +19132,21 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/preset-classic@3.5.2(@algolia/client-search@4.24.0)(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': - dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-content-blog': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-content-pages': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-debug': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-google-analytics': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-google-gtag': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-google-tag-manager': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-sitemap': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/theme-classic': 3.5.2(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/theme-search-algolia': 3.5.2(@algolia/client-search@4.24.0)(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/preset-classic@3.5.2(@algolia/client-search@4.24.0)(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + dependencies: + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-content-blog': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-content-pages': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-debug': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-google-analytics': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-google-gtag': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-google-tag-manager': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-sitemap': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/theme-classic': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/theme-search-algolia': 3.5.2(@algolia/client-search@4.24.0)(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) transitivePeerDependencies: @@ -19183,20 +19186,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@docusaurus/theme-classic@3.5.2(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/theme-classic@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/mdx-loader': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/module-type-aliases': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-blog': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-content-pages': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/mdx-loader': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/module-type-aliases': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-blog': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-content-pages': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/theme-translations': 3.5.2 - '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) + '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) '@mdx-js/react': 3.0.1(@types/react@18.3.9)(react@18.3.1) clsx: 2.1.1 copy-text-to-clipboard: 3.2.0 @@ -19231,13 +19234,13 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/theme-common@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': + '@docusaurus/theme-common@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: - '@docusaurus/mdx-loader': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/module-type-aliases': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/mdx-loader': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/module-type-aliases': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) + '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) '@types/history': 4.7.11 '@types/react': 18.3.9 '@types/react-router-config': 5.0.11 @@ -19257,12 +19260,12 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/theme-live-codeblock@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/theme-live-codeblock@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/theme-translations': 3.5.2 - '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) '@philpl/buble': 0.19.7 clsx: 2.1.1 fs-extra: 11.2.0 @@ -19291,13 +19294,13 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/theme-mermaid@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/theme-mermaid@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/module-type-aliases': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/module-type-aliases': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) mermaid: 10.9.3 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -19322,16 +19325,16 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/theme-search-algolia@3.5.2(@algolia/client-search@4.24.0)(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/theme-search-algolia@3.5.2(@algolia/client-search@4.24.0)(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': dependencies: '@docsearch/react': 3.6.1(@algolia/client-search@4.24.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) '@docusaurus/logger': 3.5.2 - '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/theme-translations': 3.5.2 - '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) + '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) algoliasearch: 4.24.0 algoliasearch-helper: 3.22.5(algoliasearch@4.24.0) clsx: 2.1.1 @@ -19377,7 +19380,7 @@ snapshots: '@docusaurus/tsconfig@3.5.2': {} - '@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@mdx-js/mdx': 3.0.1 '@types/history': 4.7.11 @@ -19388,7 +19391,7 @@ snapshots: react-dom: 18.3.1(react@18.3.1) react-helmet-async: 1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) utility-types: 3.11.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) webpack-merge: 5.10.0 transitivePeerDependencies: - '@swc/core' @@ -19397,7 +19400,7 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@mdx-js/mdx': 3.0.1 '@types/history': 4.7.11 @@ -19408,7 +19411,7 @@ snapshots: react-dom: 18.3.1(react@18.3.1) react-helmet-async: 1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) utility-types: 3.11.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) webpack-merge: 5.10.0 transitivePeerDependencies: - '@swc/core' @@ -19417,29 +19420,29 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils-common@3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': + '@docusaurus/utils-common@3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': dependencies: tslib: 2.7.0 optionalDependencies: - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-common@3.4.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': + '@docusaurus/utils-common@3.4.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': dependencies: tslib: 2.7.0 optionalDependencies: - '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-common@3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': + '@docusaurus/utils-common@3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': dependencies: tslib: 2.7.0 optionalDependencies: - '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation@3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2)': + '@docusaurus/utils-validation@3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2)': dependencies: '@docusaurus/logger': 3.4.0 - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) + '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) fs-extra: 11.2.0 joi: 17.13.3 js-yaml: 4.1.0 @@ -19454,11 +19457,11 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils-validation@3.4.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2)': + '@docusaurus/utils-validation@3.4.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2)': dependencies: '@docusaurus/logger': 3.4.0 - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils': 3.4.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) + '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) fs-extra: 11.2.0 joi: 17.13.3 js-yaml: 4.1.0 @@ -19473,11 +19476,11 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils-validation@3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2)': + '@docusaurus/utils-validation@3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2)': dependencies: '@docusaurus/logger': 3.5.2 - '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) + '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) fs-extra: 11.2.0 joi: 17.13.3 js-yaml: 4.1.0 @@ -19492,13 +19495,13 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils@3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2)': + '@docusaurus/utils@3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2)': dependencies: '@docusaurus/logger': 3.4.0 - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) '@svgr/webpack': 8.1.0(typescript@5.6.2) escape-string-regexp: 4.0.0 - file-loader: 6.2.0(webpack@5.95.0) + file-loader: 6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) fs-extra: 11.2.0 github-slugger: 1.5.0 globby: 11.1.0 @@ -19511,11 +19514,11 @@ snapshots: resolve-pathname: 3.0.0 shelljs: 0.8.5 tslib: 2.7.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) utility-types: 3.11.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) optionalDependencies: - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) transitivePeerDependencies: - '@swc/core' - esbuild @@ -19524,13 +19527,13 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils@3.4.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2)': + '@docusaurus/utils@3.4.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2)': dependencies: '@docusaurus/logger': 3.4.0 - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) '@svgr/webpack': 8.1.0(typescript@5.6.2) escape-string-regexp: 4.0.0 - file-loader: 6.2.0(webpack@5.95.0) + file-loader: 6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) fs-extra: 11.2.0 github-slugger: 1.5.0 globby: 11.1.0 @@ -19543,11 +19546,11 @@ snapshots: resolve-pathname: 3.0.0 shelljs: 0.8.5 tslib: 2.7.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) utility-types: 3.11.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) optionalDependencies: - '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) transitivePeerDependencies: - '@swc/core' - esbuild @@ -19556,13 +19559,13 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils@3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2)': + '@docusaurus/utils@3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2)': dependencies: '@docusaurus/logger': 3.5.2 - '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) '@svgr/webpack': 8.1.0(typescript@5.6.2) escape-string-regexp: 4.0.0 - file-loader: 6.2.0(webpack@5.95.0) + file-loader: 6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) fs-extra: 11.2.0 github-slugger: 1.5.0 globby: 11.1.0 @@ -19575,11 +19578,11 @@ snapshots: resolve-pathname: 3.0.0 shelljs: 0.8.5 tslib: 2.7.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) utility-types: 3.11.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) optionalDependencies: - '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) transitivePeerDependencies: - '@swc/core' - esbuild @@ -20144,24 +20147,24 @@ snapshots: - encoding - supports-color - '@graphql-markdown/core@1.12.0(@graphql-markdown/printer-legacy@1.9.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(graphql@16.9.0)(prettier@3.3.3)(typescript@5.6.2))(graphql-config@5.1.2(@types/node@22.7.3)(graphql@16.9.0)(typescript@5.6.2))(graphql@16.9.0)(prettier@3.3.3)': + '@graphql-markdown/core@1.12.0(@graphql-markdown/printer-legacy@1.9.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(graphql@16.9.0)(prettier@3.3.3)(typescript@5.6.2))(graphql-config@5.1.2(@types/node@22.7.3)(graphql@16.9.0)(typescript@5.6.2))(graphql@16.9.0)(prettier@3.3.3)': dependencies: '@graphql-markdown/graphql': 1.1.4(graphql@16.9.0)(prettier@3.3.3) '@graphql-markdown/logger': 1.0.4 '@graphql-markdown/utils': 1.7.0(prettier@3.3.3) optionalDependencies: - '@graphql-markdown/printer-legacy': 1.9.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(graphql@16.9.0)(prettier@3.3.3)(typescript@5.6.2) + '@graphql-markdown/printer-legacy': 1.9.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(graphql@16.9.0)(prettier@3.3.3)(typescript@5.6.2) graphql-config: 5.1.2(@types/node@22.7.3)(graphql@16.9.0)(typescript@5.6.2) transitivePeerDependencies: - graphql - prettier - '@graphql-markdown/docusaurus@1.26.2(@docusaurus/logger@3.5.2)(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(graphql-config@5.1.2(@types/node@22.7.3)(graphql@16.9.0)(typescript@5.6.2))(graphql@16.9.0)(prettier@3.3.3)(typescript@5.6.2)': + '@graphql-markdown/docusaurus@1.26.2(@docusaurus/logger@3.5.2)(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(graphql-config@5.1.2(@types/node@22.7.3)(graphql@16.9.0)(typescript@5.6.2))(graphql@16.9.0)(prettier@3.3.3)(typescript@5.6.2)': dependencies: '@docusaurus/logger': 3.5.2 - '@graphql-markdown/core': 1.12.0(@graphql-markdown/printer-legacy@1.9.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(graphql@16.9.0)(prettier@3.3.3)(typescript@5.6.2))(graphql-config@5.1.2(@types/node@22.7.3)(graphql@16.9.0)(typescript@5.6.2))(graphql@16.9.0)(prettier@3.3.3) + '@graphql-markdown/core': 1.12.0(@graphql-markdown/printer-legacy@1.9.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(graphql@16.9.0)(prettier@3.3.3)(typescript@5.6.2))(graphql-config@5.1.2(@types/node@22.7.3)(graphql@16.9.0)(typescript@5.6.2))(graphql@16.9.0)(prettier@3.3.3) '@graphql-markdown/logger': 1.0.4 - '@graphql-markdown/printer-legacy': 1.9.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(graphql@16.9.0)(prettier@3.3.3)(typescript@5.6.2) + '@graphql-markdown/printer-legacy': 1.9.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(graphql@16.9.0)(prettier@3.3.3)(typescript@5.6.2) transitivePeerDependencies: - '@docusaurus/types' - '@graphql-markdown/diff' @@ -20186,9 +20189,9 @@ snapshots: '@graphql-markdown/logger@1.0.4': {} - '@graphql-markdown/printer-legacy@1.9.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(graphql@16.9.0)(prettier@3.3.3)(typescript@5.6.2)': + '@graphql-markdown/printer-legacy@1.9.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(graphql@16.9.0)(prettier@3.3.3)(typescript@5.6.2)': dependencies: - '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) '@graphql-markdown/graphql': 1.1.4(graphql@16.9.0)(prettier@3.3.3) '@graphql-markdown/utils': 1.7.0(prettier@3.3.3) transitivePeerDependencies: @@ -20526,9 +20529,9 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@headlessui/tailwindcss@0.1.3(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2)))': + '@headlessui/tailwindcss@0.1.3(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2)))': dependencies: - tailwindcss: 3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2)) + tailwindcss: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2)) '@hookform/resolvers@3.9.0(react-hook-form@7.53.0(react@18.3.1))': dependencies: @@ -20606,7 +20609,7 @@ snapshots: jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@types/node@20.16.9)(typescript@5.6.2))': + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0(node-notifier@10.0.0) @@ -20620,7 +20623,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.16.9)(typescript@5.6.2)) + jest-config: 29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -21132,7 +21135,7 @@ snapshots: cache-manager: 5.7.6 rxjs: 7.8.1 - '@nestjs/cli@10.4.5(@swc/core@1.7.28)': + '@nestjs/cli@10.4.5(@swc/core@1.7.28(@swc/helpers@0.5.5))': dependencies: '@angular-devkit/core': 17.3.8(chokidar@3.6.0) '@angular-devkit/schematics': 17.3.8(chokidar@3.6.0) @@ -21142,7 +21145,7 @@ snapshots: chokidar: 3.6.0 cli-table3: 0.6.5 commander: 4.1.1 - fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.3.3)(webpack@5.94.0(@swc/core@1.7.28)) + fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.3.3)(webpack@5.94.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) glob: 10.4.2 inquirer: 8.2.6 node-emoji: 1.11.0 @@ -21151,7 +21154,7 @@ snapshots: tsconfig-paths: 4.2.0 tsconfig-paths-webpack-plugin: 4.1.0 typescript: 5.3.3 - webpack: 5.94.0(@swc/core@1.7.28) + webpack: 5.94.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) webpack-node-externals: 3.0.0 optionalDependencies: '@swc/core': 1.7.28(@swc/helpers@0.5.5) @@ -23860,14 +23863,14 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@tailwindcss/aspect-ratio@0.4.2(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2)))': + '@tailwindcss/aspect-ratio@0.4.2(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2)))': dependencies: - tailwindcss: 3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2)) + tailwindcss: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2)) - '@tailwindcss/forms@0.5.9(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2)))': + '@tailwindcss/forms@0.5.9(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2)))': dependencies: mini-svg-data-uri: 1.4.4 - tailwindcss: 3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2)) + tailwindcss: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2)) '@tanstack/eslint-plugin-query@5.58.1(eslint@8.57.1)(typescript@5.6.2)': dependencies: @@ -24371,11 +24374,11 @@ snapshots: '@types/webextension-polyfill@0.10.7': {} - '@types/webpack@5.28.5(@swc/core@1.7.28)(webpack-cli@5.1.4(webpack@5.95.0))': + '@types/webpack@5.28.5(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4(webpack@5.95.0))': dependencies: '@types/node': 20.16.9 tapable: 2.2.1 - webpack: 5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) transitivePeerDependencies: - '@swc/core' - esbuild @@ -25150,19 +25153,19 @@ snapshots: '@webassemblyjs/ast': 1.12.1 '@xtuc/long': 4.2.2 - '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4))': + '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4))': dependencies: - webpack: 5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack@5.95.0) - '@webpack-cli/info@2.0.2(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4))': + '@webpack-cli/info@2.0.2(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4))': dependencies: - webpack: 5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack@5.95.0) - '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4))': + '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4))': dependencies: - webpack: 5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack@5.95.0) '@whatwg-node/events@0.0.3': {} @@ -25651,12 +25654,12 @@ snapshots: transitivePeerDependencies: - supports-color - babel-loader@9.2.1(@babel/core@7.25.2)(webpack@5.95.0): + babel-loader@9.2.1(@babel/core@7.25.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: '@babel/core': 7.25.2 find-cache-dir: 4.0.0 schema-utils: 4.2.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) babel-plugin-dynamic-import-node@2.3.3: dependencies: @@ -26456,7 +26459,7 @@ snapshots: copy-text-to-clipboard@3.2.0: {} - copy-webpack-plugin@11.0.0(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)): + copy-webpack-plugin@11.0.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)): dependencies: fast-glob: 3.3.2 glob-parent: 6.0.2 @@ -26464,9 +26467,9 @@ snapshots: normalize-path: 3.0.0 schema-utils: 4.2.0 serialize-javascript: 6.0.2 - webpack: 5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) - copy-webpack-plugin@11.0.0(webpack@5.95.0): + copy-webpack-plugin@11.0.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: fast-glob: 3.3.2 glob-parent: 6.0.2 @@ -26474,7 +26477,7 @@ snapshots: normalize-path: 3.0.0 schema-utils: 4.2.0 serialize-javascript: 6.0.2 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) core-js-compat@3.38.1: dependencies: @@ -26544,13 +26547,13 @@ snapshots: crc-32@1.2.2: {} - create-jest@29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.16.9)(typescript@5.6.2)): + create-jest@29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.16.9)(typescript@5.6.2)) + jest-config: 29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -26614,7 +26617,7 @@ snapshots: postcss-selector-parser: 6.1.2 postcss-value-parser: 4.2.0 - css-loader@6.11.0(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)): + css-loader@6.11.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)): dependencies: icss-utils: 5.1.0(postcss@8.4.47) postcss: 8.4.47 @@ -26625,9 +26628,9 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.6.3 optionalDependencies: - webpack: 5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) - css-loader@6.11.0(webpack@5.95.0): + css-loader@6.11.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: icss-utils: 5.1.0(postcss@8.4.47) postcss: 8.4.47 @@ -26638,9 +26641,9 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.6.3 optionalDependencies: - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) - css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(webpack@5.95.0): + css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: '@jridgewell/trace-mapping': 0.3.25 cssnano: 6.1.2(postcss@8.4.47) @@ -26648,7 +26651,7 @@ snapshots: postcss: 8.4.47 schema-utils: 4.2.0 serialize-javascript: 6.0.2 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) optionalDependencies: clean-css: 5.3.3 @@ -27197,15 +27200,15 @@ snapshots: dependencies: typedoc-plugin-markdown: 4.2.10(typedoc@0.26.11(typescript@5.6.2)) - docusaurus-theme-search-typesense@0.20.0-0(@algolia/client-search@4.24.0)(@babel/runtime@7.25.6)(@docusaurus/core@3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/theme-common@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.9)(algoliasearch@4.24.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16): + docusaurus-theme-search-typesense@0.20.0-0(iea5eyhbiud2dlcqtud2g4pxzm): dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) '@docusaurus/logger': 3.4.0 - '@docusaurus/plugin-content-docs': 3.4.0(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/plugin-content-docs': 3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/theme-translations': 3.4.0 - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) + '@docusaurus/utils': 3.4.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) + '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) algoliasearch-helper: 3.22.5(algoliasearch@4.24.0) clsx: 1.2.1 eta: 2.2.0 @@ -27621,8 +27624,8 @@ snapshots: '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.6.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1) - eslint-plugin-import: 2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.1) eslint-plugin-react: 7.37.0(eslint@8.57.1) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) @@ -27645,26 +27648,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1): - dependencies: - '@nolyfill/is-core-module': 1.0.39 - debug: 4.3.7(supports-color@8.1.1) - enhanced-resolve: 5.17.1 - eslint: 8.57.1 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1) - fast-glob: 3.3.2 - get-tsconfig: 4.8.1 - is-bun-module: 1.2.1 - is-glob: 4.0.3 - optionalDependencies: - eslint-plugin-import: 2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) - transitivePeerDependencies: - - '@typescript-eslint/parser' - - eslint-import-resolver-node - - eslint-import-resolver-webpack - - supports-color - - eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1): + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.3.7(supports-color@8.1.1) @@ -27676,24 +27660,13 @@ snapshots: is-bun-module: 1.2.1 is-glob: 4.0.3 optionalDependencies: - eslint-plugin-import: 2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + eslint-plugin-import: 2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1) transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-node - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.6.2) - eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1) - transitivePeerDependencies: - - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 @@ -27701,7 +27674,7 @@ snapshots: '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.6.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) transitivePeerDependencies: - supports-color @@ -27709,7 +27682,7 @@ snapshots: dependencies: eslint: 8.57.1 - eslint-plugin-import@2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): + eslint-plugin-import@2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -27835,7 +27808,7 @@ snapshots: eslint-visitor-keys@4.1.0: {} - eslint-webpack-plugin@4.2.0(eslint@8.57.1)(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)): + eslint-webpack-plugin@4.2.0(eslint@8.57.1)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)): dependencies: '@types/eslint': 8.56.12 eslint: 8.57.1 @@ -27843,7 +27816,7 @@ snapshots: micromatch: 4.0.8 normalize-path: 3.0.0 schema-utils: 4.2.0 - webpack: 5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) eslint@8.57.1: dependencies: @@ -28208,11 +28181,11 @@ snapshots: dependencies: flat-cache: 3.2.0 - file-loader@6.2.0(webpack@5.95.0): + file-loader@6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) file-system-cache@2.3.0: dependencies: @@ -28320,7 +28293,7 @@ snapshots: forever-agent@0.6.1: {} - fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)(webpack@5.95.0): + fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: '@babel/code-frame': 7.24.7 '@types/json-schema': 7.0.15 @@ -28336,12 +28309,12 @@ snapshots: semver: 7.6.3 tapable: 1.1.3 typescript: 5.6.2 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) optionalDependencies: eslint: 8.57.1 vue-template-compiler: 2.7.16 - fork-ts-checker-webpack-plugin@9.0.2(typescript@5.3.3)(webpack@5.94.0(@swc/core@1.7.28)): + fork-ts-checker-webpack-plugin@9.0.2(typescript@5.3.3)(webpack@5.94.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: '@babel/code-frame': 7.24.7 chalk: 4.1.2 @@ -28356,7 +28329,7 @@ snapshots: semver: 7.6.3 tapable: 2.2.1 typescript: 5.3.3 - webpack: 5.94.0(@swc/core@1.7.28) + webpack: 5.94.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) form-data-encoder@2.1.4: {} @@ -29139,7 +29112,7 @@ snapshots: html-void-elements@3.0.0: {} - html-webpack-plugin@5.6.0(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)): + html-webpack-plugin@5.6.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -29147,9 +29120,9 @@ snapshots: pretty-error: 4.0.0 tapable: 2.2.1 optionalDependencies: - webpack: 5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) - html-webpack-plugin@5.6.0(webpack@5.95.0): + html-webpack-plugin@5.6.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -29157,7 +29130,7 @@ snapshots: pretty-error: 4.0.0 tapable: 2.2.1 optionalDependencies: - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) htmlparser2@6.1.0: dependencies: @@ -29799,16 +29772,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@types/node@20.16.9)(typescript@5.6.2)): + jest-cli@29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@types/node@20.16.9)(typescript@5.6.2)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.16.9)(typescript@5.6.2)) + create-jest: 29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.16.9)(typescript@5.6.2)) + jest-config: 29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -29820,7 +29793,7 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.16.9)(typescript@5.6.2)): + jest-config@29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)): dependencies: '@babel/core': 7.25.2 '@jest/test-sequencer': 29.7.0 @@ -29846,7 +29819,7 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 20.16.9 - ts-node: 10.9.2(@swc/core@1.7.28)(@types/node@20.16.9)(typescript@5.6.2) + ts-node: 10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -30077,12 +30050,12 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@types/node@20.16.9)(typescript@5.6.2)): + jest@29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@types/node@20.16.9)(typescript@5.6.2)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@types/node@20.16.9)(typescript@5.6.2)) + jest-cli: 29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)) optionalDependencies: node-notifier: 10.0.0 transitivePeerDependencies: @@ -31366,17 +31339,17 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.9.1(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)): + mini-css-extract-plugin@2.9.1(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)): dependencies: schema-utils: 4.2.0 tapable: 2.2.1 - webpack: 5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) - mini-css-extract-plugin@2.9.1(webpack@5.95.0): + mini-css-extract-plugin@2.9.1(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: schema-utils: 4.2.0 tapable: 2.2.1 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) mini-svg-data-uri@1.4.4: {} @@ -32313,39 +32286,39 @@ snapshots: '@csstools/utilities': 1.0.0(postcss@8.4.47) postcss: 8.4.47 - postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2(@swc/core@1.7.28)(@types/node@20.16.9)(typescript@5.6.2)): + postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)): dependencies: lilconfig: 3.1.2 yaml: 2.5.1 optionalDependencies: postcss: 8.4.47 - ts-node: 10.9.2(@swc/core@1.7.28)(@types/node@20.16.9)(typescript@5.6.2) + ts-node: 10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2) - postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2)): + postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2)): dependencies: lilconfig: 3.1.2 yaml: 2.5.1 optionalDependencies: postcss: 8.4.47 - ts-node: 10.9.2(@types/node@22.7.3)(typescript@5.6.2) + ts-node: 10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2) - postcss-loader@7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)): + postcss-loader@7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)): dependencies: cosmiconfig: 8.3.6(typescript@5.6.2) jiti: 1.21.6 postcss: 8.4.47 semver: 7.6.3 - webpack: 5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) transitivePeerDependencies: - typescript - postcss-loader@7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0): + postcss-loader@7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: cosmiconfig: 8.3.6(typescript@5.6.2) jiti: 1.21.6 postcss: 8.4.47 semver: 7.6.3 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) transitivePeerDependencies: - typescript @@ -32850,7 +32823,7 @@ snapshots: react: 18.3.1 tween-functions: 1.2.0 - react-dev-utils@12.0.1(eslint@8.57.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)(webpack@5.95.0): + react-dev-utils@12.0.1(eslint@8.57.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: '@babel/code-frame': 7.24.7 address: 1.2.2 @@ -32861,7 +32834,7 @@ snapshots: escape-string-regexp: 4.0.0 filesize: 8.0.7 find-up: 5.0.0 - fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)(webpack@5.95.0) + fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) global-modules: 2.0.0 globby: 11.1.0 gzip-size: 6.0.0 @@ -32876,7 +32849,7 @@ snapshots: shell-quote: 1.8.1 strip-ansi: 6.0.1 text-table: 0.2.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) optionalDependencies: typescript: 5.6.2 transitivePeerDependencies: @@ -32977,11 +32950,11 @@ snapshots: sucrase: 3.35.0 use-editable: 2.3.3(react@18.3.1) - react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.95.0): + react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: '@babel/runtime': 7.25.6 react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) react-number-format@5.4.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: @@ -33680,10 +33653,10 @@ snapshots: safer-buffer@2.1.2: {} - sass-loader@13.3.3(sass@1.79.3)(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)): + sass-loader@13.3.3(sass@1.79.3)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)): dependencies: neo-async: 2.6.2 - webpack: 5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) optionalDependencies: sass: 1.79.3 @@ -34413,15 +34386,15 @@ snapshots: tailwind-merge@2.5.2: {} - tailwindcss-animate@1.0.7(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.28)(@types/node@20.16.9)(typescript@5.6.2))): + tailwindcss-animate@1.0.7(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2))): dependencies: - tailwindcss: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28)(@types/node@20.16.9)(typescript@5.6.2)) + tailwindcss: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)) - tailwindcss-animate@1.0.7(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2))): + tailwindcss-animate@1.0.7(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2))): dependencies: - tailwindcss: 3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2)) + tailwindcss: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2)) - tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.28)(@types/node@20.16.9)(typescript@5.6.2)): + tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -34440,7 +34413,7 @@ snapshots: postcss: 8.4.47 postcss-import: 15.1.0(postcss@8.4.47) postcss-js: 4.0.1(postcss@8.4.47) - postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@swc/core@1.7.28)(@types/node@20.16.9)(typescript@5.6.2)) + postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)) postcss-nested: 6.2.0(postcss@8.4.47) postcss-selector-parser: 6.1.2 resolve: 1.22.8 @@ -34448,7 +34421,7 @@ snapshots: transitivePeerDependencies: - ts-node - tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2)): + tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -34467,7 +34440,7 @@ snapshots: postcss: 8.4.47 postcss-import: 15.1.0(postcss@8.4.47) postcss-js: 4.0.1(postcss@8.4.47) - postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2)) + postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2)) postcss-nested: 6.2.0(postcss@8.4.47) postcss-selector-parser: 6.1.2 resolve: 1.22.8 @@ -34523,48 +34496,39 @@ snapshots: term-size@2.2.1: {} - terser-webpack-plugin@5.3.10(@swc/core@1.7.28)(webpack@5.94.0(@swc/core@1.7.28)): + terser-webpack-plugin@5.3.10(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack@5.94.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.34.0 - webpack: 5.94.0(@swc/core@1.7.28) + webpack: 5.94.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) optionalDependencies: '@swc/core': 1.7.28(@swc/helpers@0.5.5) - terser-webpack-plugin@5.3.10(@swc/core@1.7.28)(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)): + terser-webpack-plugin@5.3.10(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.34.0 - webpack: 5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) optionalDependencies: '@swc/core': 1.7.28(@swc/helpers@0.5.5) - terser-webpack-plugin@5.3.10(@swc/core@1.7.28)(webpack@5.95.0(@swc/core@1.7.28)): + terser-webpack-plugin@5.3.10(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.34.0 - webpack: 5.95.0(@swc/core@1.7.28) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) optionalDependencies: '@swc/core': 1.7.28(@swc/helpers@0.5.5) - terser-webpack-plugin@5.3.10(webpack@5.95.0): - dependencies: - '@jridgewell/trace-mapping': 0.3.25 - jest-worker: 27.5.1 - schema-utils: 3.3.0 - serialize-javascript: 6.0.2 - terser: 5.34.0 - webpack: 5.95.0 - terser@5.34.0: dependencies: '@jridgewell/source-map': 0.3.6 @@ -34709,12 +34673,12 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-jest@29.2.5(@babel/core@7.25.2)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.2))(jest@29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@types/node@20.16.9)(typescript@5.6.2)))(typescript@5.6.2): + ts-jest@29.2.5(@babel/core@7.25.2)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.2))(jest@29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)))(typescript@5.6.2): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@types/node@20.16.9)(typescript@5.6.2)) + jest: 29.7.0(@types/node@20.16.9)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -34728,7 +34692,7 @@ snapshots: '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.25.2) - ts-loader@9.5.1(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)): + ts-loader@9.5.1(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)): dependencies: chalk: 4.1.2 enhanced-resolve: 5.17.1 @@ -34736,9 +34700,9 @@ snapshots: semver: 7.6.3 source-map: 0.7.4 typescript: 5.6.2 - webpack: 5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) - ts-loader@9.5.1(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28)): + ts-loader@9.5.1(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: chalk: 4.1.2 enhanced-resolve: 5.17.1 @@ -34746,11 +34710,11 @@ snapshots: semver: 7.6.3 source-map: 0.7.4 typescript: 5.6.2 - webpack: 5.95.0(@swc/core@1.7.28) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) ts-log@2.2.5: {} - ts-node@10.9.2(@swc/core@1.7.28)(@types/node@16.18.111)(typescript@5.1.6): + ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@16.18.111)(typescript@5.1.6): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 @@ -34770,7 +34734,7 @@ snapshots: optionalDependencies: '@swc/core': 1.7.28(@swc/helpers@0.5.5) - ts-node@10.9.2(@swc/core@1.7.28)(@types/node@20.16.9)(typescript@5.6.2): + ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 @@ -34790,7 +34754,7 @@ snapshots: optionalDependencies: '@swc/core': 1.7.28(@swc/helpers@0.5.5) - ts-node@10.9.2(@types/node@22.7.3)(typescript@5.6.2): + ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 @@ -34807,6 +34771,8 @@ snapshots: typescript: 5.6.2 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + optionalDependencies: + '@swc/core': 1.7.28(@swc/helpers@0.5.5) optional: true ts-retry-promise@0.8.1: {} @@ -34976,14 +34942,14 @@ snapshots: transitivePeerDependencies: - supports-color - typescript-json-schema@0.64.0(@swc/core@1.7.28): + typescript-json-schema@0.64.0(@swc/core@1.7.28(@swc/helpers@0.5.5)): dependencies: '@types/json-schema': 7.0.15 '@types/node': 16.18.111 glob: 7.2.3 path-equal: 1.2.5 safe-stable-stringify: 2.5.0 - ts-node: 10.9.2(@swc/core@1.7.28)(@types/node@16.18.111)(typescript@5.1.6) + ts-node: 10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@16.18.111)(typescript@5.1.6) typescript: 5.1.6 yargs: 17.7.2 transitivePeerDependencies: @@ -35224,14 +35190,14 @@ snapshots: dependencies: punycode: 2.3.1 - url-loader@4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0): + url-loader@4.1.1(file-loader@6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: loader-utils: 2.0.4 mime-types: 2.1.35 schema-utils: 3.3.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) optionalDependencies: - file-loader: 6.2.0(webpack@5.95.0) + file-loader: 6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) url-parse@1.5.10: dependencies: @@ -35978,9 +35944,9 @@ snapshots: webpack-cli@5.1.4(webpack@5.95.0): dependencies: '@discoveryjs/json-ext': 0.5.7 - '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)) - '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)) - '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)) + '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) + '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) + '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) colorette: 2.0.20 commander: 10.0.1 cross-spawn: 7.0.5 @@ -35989,19 +35955,19 @@ snapshots: import-local: 3.2.0 interpret: 3.1.1 rechoir: 0.8.0 - webpack: 5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) webpack-merge: 5.10.0 - webpack-dev-middleware@5.3.4(webpack@5.95.0): + webpack-dev-middleware@5.3.4(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: colorette: 2.0.20 memfs: 3.5.3 mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.2.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) - webpack-dev-server@4.15.2(webpack@5.95.0): + webpack-dev-server@4.15.2(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -36031,10 +35997,10 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 5.3.4(webpack@5.95.0) + webpack-dev-middleware: 5.3.4(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) ws: 8.18.0 optionalDependencies: - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) transitivePeerDependencies: - bufferutil - debug @@ -36053,37 +36019,7 @@ snapshots: webpack-virtual-modules@0.6.2: {} - webpack@5.94.0(@swc/core@1.7.28): - dependencies: - '@types/estree': 1.0.6 - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/wasm-edit': 1.12.1 - '@webassemblyjs/wasm-parser': 1.12.1 - acorn: 8.12.1 - acorn-import-attributes: 1.9.5(acorn@8.12.1) - browserslist: 4.24.0 - chrome-trace-event: 1.0.4 - enhanced-resolve: 5.17.1 - es-module-lexer: 1.5.4 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 3.3.0 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(@swc/core@1.7.28)(webpack@5.94.0(@swc/core@1.7.28)) - watchpack: 2.4.2 - webpack-sources: 3.2.3 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - - webpack@5.95.0: + webpack@5.94.0(@swc/core@1.7.28(@swc/helpers@0.5.5)): dependencies: '@types/estree': 1.0.6 '@webassemblyjs/ast': 1.12.1 @@ -36105,7 +36041,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(webpack@5.95.0) + terser-webpack-plugin: 5.3.10(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack@5.94.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) watchpack: 2.4.2 webpack-sources: 3.2.3 transitivePeerDependencies: @@ -36113,7 +36049,7 @@ snapshots: - esbuild - uglify-js - webpack@5.95.0(@swc/core@1.7.28): + webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)): dependencies: '@types/estree': 1.0.6 '@webassemblyjs/ast': 1.12.1 @@ -36135,7 +36071,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(@swc/core@1.7.28)(webpack@5.95.0(@swc/core@1.7.28)) + terser-webpack-plugin: 5.3.10(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) watchpack: 2.4.2 webpack-sources: 3.2.3 transitivePeerDependencies: @@ -36143,7 +36079,7 @@ snapshots: - esbuild - uglify-js - webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4): + webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4): dependencies: '@types/estree': 1.0.6 '@webassemblyjs/ast': 1.12.1 @@ -36165,7 +36101,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(@swc/core@1.7.28)(webpack@5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4)) + terser-webpack-plugin: 5.3.10(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) watchpack: 2.4.2 webpack-sources: 3.2.3 optionalDependencies: @@ -36175,13 +36111,13 @@ snapshots: - esbuild - uglify-js - webpackbar@5.0.2(webpack@5.95.0): + webpackbar@5.0.2(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: chalk: 4.1.2 consola: 2.15.3 pretty-time: 1.1.0 std-env: 3.7.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) websocket-driver@0.7.4: dependencies: From 82ffdcce7cf3bed0d3288a9302fd8d8843fb028b Mon Sep 17 00:00:00 2001 From: Lucas Tortora <85233773+lucas-tortora@users.noreply.github.com> Date: Tue, 17 Dec 2024 13:07:09 -0300 Subject: [PATCH 13/14] task(devx): Switch to algolia search (#4447) * task(devx): Switch to algolia search * feat(devx): update pnpm-lock * fix(devx): remove typesense dep * fix(devx) update pnpm-lock --- docs/site/docusaurus.config.js | 24 +- docs/site/package.json | 1 - pnpm-lock.yaml | 671 +++------------------------------ 3 files changed, 62 insertions(+), 634 deletions(-) diff --git a/docs/site/docusaurus.config.js b/docs/site/docusaurus.config.js index feb04ab538a..df5b62b56b3 100644 --- a/docs/site/docusaurus.config.js +++ b/docs/site/docusaurus.config.js @@ -191,29 +191,15 @@ const config = { type: "text/css", }, ], - themes: ["@docusaurus/theme-mermaid", 'docusaurus-theme-search-typesense', + themes: ["@docusaurus/theme-mermaid", '@saucelabs/theme-github-codeblock', '@docusaurus/theme-live-codeblock'], themeConfig: /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ ({ - typesense: { - // Replace this with the name of your index/collection. - // It should match the "index_name" entry in the scraper's "config.json" file. - typesenseCollectionName: 'IOTADocs', - typesenseServerConfig: { - nodes: [ - { - host: 'docs-search.iota.org', - port: '', - protocol: 'https', - }, - ], - apiKey: 'C!jA3iCujG*PjK!eUVWFBxnU', - }, - // Optional: Typesense search parameters: https://typesense.org/docs/0.24.0/api/search.html#search-parameters - typesenseSearchParameters: {}, - // Optional - contextualSearch: true, + algolia: { + apiKey: '24b141ea7e65db2181463e44dbe564a5', + appId: '9PMBZGRP3B', + indexName: 'iota', }, image: "img/iota-doc-og.png", docs: { diff --git a/docs/site/package.json b/docs/site/package.json index 3962ebe7ef2..d8d580fffdf 100644 --- a/docs/site/package.json +++ b/docs/site/package.json @@ -43,7 +43,6 @@ "axios": "^1.7.4", "clsx": "^2.1.1", "copy-text-to-clipboard": "^3.2.0", - "docusaurus-theme-search-typesense": "0.20.0-0", "dotenv": "^16.4.5", "graphql": "^16.9.0", "graphql-config": "^5.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 19bc39c4bca..9ec2db66a8f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,7 +60,7 @@ importers: version: 9.1.0(eslint@8.57.1) eslint-import-resolver-typescript: specifier: ^3.6.1 - version: 3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + version: 3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1) eslint-plugin-header: specifier: ^3.1.1 version: 3.1.1(eslint@8.57.1) @@ -120,7 +120,7 @@ importers: version: link:../../sdk/typescript '@nestjs/cache-manager': specifier: ^2.2.2 - version: 2.2.2(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(cache-manager@5.7.6)(rxjs@7.8.1) + version: 2.2.2(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4)(cache-manager@5.7.6)(rxjs@7.8.1) '@nestjs/common': specifier: ^10.0.0 version: 10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -135,7 +135,7 @@ importers: version: 10.4.4(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4) '@nestjs/schedule': specifier: ^4.0.2 - version: 4.1.1(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1)) + version: 4.1.1(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4) cache-manager: specifier: ^5.6.1 version: 5.7.6 @@ -151,7 +151,7 @@ importers: version: 10.1.4(chokidar@3.6.0)(typescript@5.6.2) '@nestjs/testing': specifier: ^10.0.0 - version: 10.4.4(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4)) + version: 10.4.4(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4)(@nestjs/platform-express@10.4.4) '@types/express': specifier: ^4.17.17 version: 4.17.21 @@ -911,7 +911,7 @@ importers: version: 0.10.7 '@types/webpack': specifier: ^5.28.1 - version: 5.28.5(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4(webpack@5.95.0)) + version: 5.28.5(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) '@types/zxcvbn': specifier: ^4.4.1 version: 4.4.5 @@ -920,19 +920,19 @@ importers: version: 4.3.1(vite@5.4.8(@types/node@20.16.9)(sass@1.79.3)(terser@5.34.0)) copy-webpack-plugin: specifier: ^11.0.0 - version: 11.0.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) + version: 11.0.0(webpack@5.95.0) cross-env: specifier: ^7.0.3 version: 7.0.3 css-loader: specifier: ^6.7.3 - version: 6.11.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) + version: 6.11.0(webpack@5.95.0) dotenv: specifier: ^16.4.5 version: 16.4.5 eslint-webpack-plugin: specifier: ^4.0.1 - version: 4.2.0(eslint@8.57.1)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) + version: 4.2.0(eslint@8.57.1)(webpack@5.95.0) git-rev-sync: specifier: ^3.0.2 version: 3.0.2 @@ -941,10 +941,10 @@ importers: version: 15.11.7 html-webpack-plugin: specifier: ^5.5.3 - version: 5.6.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) + version: 5.6.0(webpack@5.95.0) mini-css-extract-plugin: specifier: ^2.7.6 - version: 2.9.1(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) + version: 2.9.1(webpack@5.95.0) onchange: specifier: ^7.1.0 version: 7.1.0 @@ -953,7 +953,7 @@ importers: version: 8.4.47 postcss-loader: specifier: ^7.3.3 - version: 7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) + version: 7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0) postcss-preset-env: specifier: ^9.0.0 version: 9.6.0(postcss@8.4.47) @@ -962,7 +962,7 @@ importers: version: 1.79.3 sass-loader: specifier: ^13.3.2 - version: 13.3.3(sass@1.79.3)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) + version: 13.3.3(sass@1.79.3)(webpack@5.95.0) tailwindcss: specifier: ^3.3.3 version: 3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2)) @@ -971,7 +971,7 @@ importers: version: 1.0.7(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2))) ts-loader: specifier: ^9.4.4 - version: 9.5.1(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) + version: 9.5.1(typescript@5.6.2)(webpack@5.95.0) ts-node: specifier: ^10.9.1 version: 10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@20.16.9)(typescript@5.6.2) @@ -1384,9 +1384,6 @@ importers: copy-text-to-clipboard: specifier: ^3.2.0 version: 3.2.0 - docusaurus-theme-search-typesense: - specifier: 0.20.0-0 - version: 0.20.0-0(iea5eyhbiud2dlcqtud2g4pxzm) dotenv: specifier: ^16.4.5 version: 16.4.5 @@ -2067,9 +2064,6 @@ packages: '@adraffy/ens-normalize@1.11.0': resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==} - '@algolia/autocomplete-core@1.8.2': - resolution: {integrity: sha512-mTeshsyFhAqw/ebqNsQpMtbnjr+qVOSKXArEj4K0d7sqc8It1XD0gkASwecm9mF/jlOQ4Z9RNg1HbdA8JPdRwQ==} - '@algolia/autocomplete-core@1.9.3': resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==} @@ -2078,21 +2072,12 @@ packages: peerDependencies: search-insights: '>= 1 < 3' - '@algolia/autocomplete-preset-algolia@1.8.2': - resolution: {integrity: sha512-J0oTx4me6ZM9kIKPuL3lyU3aB8DEvpVvR6xWmHVROx5rOYJGQcZsdG4ozxwcOyiiu3qxMkIbzntnV1S1VWD8yA==} - peerDependencies: - '@algolia/client-search': '>= 4.9.1 < 6' - algoliasearch: '>= 4.9.1 < 6' - '@algolia/autocomplete-preset-algolia@1.9.3': resolution: {integrity: sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==} peerDependencies: '@algolia/client-search': '>= 4.9.1 < 6' algoliasearch: '>= 4.9.1 < 6' - '@algolia/autocomplete-shared@1.8.2': - resolution: {integrity: sha512-b6Z/X4MczChMcfhk6kfRmBzPgjoPzuS9KGR4AFsiLulLNRAAqhP+xZTKtMnZGhLuc61I20d5WqlId02AZvcO6g==} - '@algolia/autocomplete-shared@1.9.3': resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==} peerDependencies: @@ -3313,14 +3298,6 @@ packages: search-insights: optional: true - '@docusaurus/core@3.4.0': - resolution: {integrity: sha512-g+0wwmN2UJsBqy2fQRQ6fhXruoEa62JDeEa5d8IdTJlMoaDaEDfHh7WjwGRn4opuTQWpjAwP/fbcgyHKlE+64w==} - engines: {node: '>=18.0'} - hasBin: true - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - '@docusaurus/core@3.5.2': resolution: {integrity: sha512-4Z1WkhCSkX4KO0Fw5m/Vuc7Q3NxBG53NE5u59Rs96fWkMPZVSrzEPP16/Nk6cWb/shK7xXPndTmalJtw7twL/w==} engines: {node: '>=18.0'} @@ -3330,29 +3307,14 @@ packages: react: ^18.0.0 react-dom: ^18.0.0 - '@docusaurus/cssnano-preset@3.4.0': - resolution: {integrity: sha512-qwLFSz6v/pZHy/UP32IrprmH5ORce86BGtN0eBtG75PpzQJAzp9gefspox+s8IEOr0oZKuQ/nhzZ3xwyc3jYJQ==} - engines: {node: '>=18.0'} - '@docusaurus/cssnano-preset@3.5.2': resolution: {integrity: sha512-D3KiQXOMA8+O0tqORBrTOEQyQxNIfPm9jEaJoALjjSjc2M/ZAWcUfPQEnwr2JB2TadHw2gqWgpZckQmrVWkytA==} engines: {node: '>=18.0'} - '@docusaurus/logger@3.4.0': - resolution: {integrity: sha512-bZwkX+9SJ8lB9kVRkXw+xvHYSMGG4bpYHKGXeXFvyVc79NMeeBSGgzd4TQLHH+DYeOJoCdl8flrFJVxlZ0wo/Q==} - engines: {node: '>=18.0'} - '@docusaurus/logger@3.5.2': resolution: {integrity: sha512-LHC540SGkeLfyT3RHK3gAMK6aS5TRqOD4R72BEU/DE2M/TY8WwEUAMY576UUc/oNJXv8pGhBmQB6N9p3pt8LQw==} engines: {node: '>=18.0'} - '@docusaurus/mdx-loader@3.4.0': - resolution: {integrity: sha512-kSSbrrk4nTjf4d+wtBA9H+FGauf2gCax89kV8SUSJu3qaTdSIKdWERlngsiHaCFgZ7laTJ8a67UFf+xlFPtuTw==} - engines: {node: '>=18.0'} - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - '@docusaurus/mdx-loader@3.5.2': resolution: {integrity: sha512-ku3xO9vZdwpiMIVd8BzWV0DCqGEbCP5zs1iHfKX50vw6jX8vQo0ylYo1YJMZyz6e+JFJ17HYHT5FzVidz2IflA==} engines: {node: '>=18.0'} @@ -3360,12 +3322,6 @@ packages: react: ^18.0.0 react-dom: ^18.0.0 - '@docusaurus/module-type-aliases@3.4.0': - resolution: {integrity: sha512-A1AyS8WF5Bkjnb8s+guTDuYmUiwJzNrtchebBHpc0gz0PyHJNMaybUlSrmJjHVcGrya0LKI4YcR3lBDQfXRYLw==} - peerDependencies: - react: '*' - react-dom: '*' - '@docusaurus/module-type-aliases@3.5.2': resolution: {integrity: sha512-Z+Xu3+2rvKef/YKTMxZHsEXp1y92ac0ngjDiExRdqGTmEKtCUpkbNYH8v5eXo5Ls+dnW88n6WTa+Q54kLOkwPg==} peerDependencies: @@ -3380,13 +3336,6 @@ packages: react: ^18.0.0 react-dom: ^18.0.0 - '@docusaurus/plugin-content-docs@3.4.0': - resolution: {integrity: sha512-HkUCZffhBo7ocYheD9oZvMcDloRnGhBMOZRyVcAQRFmZPmNqSyISlXA1tQCIxW+r478fty97XXAGjNYzBjpCsg==} - engines: {node: '>=18.0'} - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - '@docusaurus/plugin-content-docs@3.5.2': resolution: {integrity: sha512-Bt+OXn/CPtVqM3Di44vHjE7rPCEsRCB/DMo2qoOuozB9f7+lsdrHvD0QCHdBs0uhz6deYJDppAr2VgqybKPlVQ==} engines: {node: '>=18.0'} @@ -3488,10 +3437,6 @@ packages: react: ^18.0.0 react-dom: ^18.0.0 - '@docusaurus/theme-translations@3.4.0': - resolution: {integrity: sha512-zSxCSpmQCCdQU5Q4CnX/ID8CSUUI3fvmq4hU/GNP/XoAWtXo9SAVnM3TzpU8Gb//H3WCsT8mJcTfyOk3d9ftNg==} - engines: {node: '>=18.0'} - '@docusaurus/theme-translations@3.5.2': resolution: {integrity: sha512-GPZLcu4aT1EmqSTmbdpVrDENGR2yObFEX8ssEFYTCiAIVc0EihNSdOIBTazUvgNqwvnoU1A8vIs1xyzc3LITTw==} engines: {node: '>=18.0'} @@ -3499,27 +3444,12 @@ packages: '@docusaurus/tsconfig@3.5.2': resolution: {integrity: sha512-rQ7toURCFnWAIn8ubcquDs0ewhPwviMzxh6WpRjBW7sJVCXb6yzwUaY3HMNa0VXCFw+qkIbFywrMTf+Pb4uHWQ==} - '@docusaurus/types@3.4.0': - resolution: {integrity: sha512-4jcDO8kXi5Cf9TcyikB/yKmz14f2RZ2qTRerbHAsS+5InE9ZgSLBNLsewtFTcTOXSVcbU3FoGOzcNWAmU1TR0A==} - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - '@docusaurus/types@3.5.2': resolution: {integrity: sha512-N6GntLXoLVUwkZw7zCxwy9QiuEXIcTVzA9AkmNw16oc0AP3SXLrMmDMMBIfgqwuKWa6Ox6epHol9kMtJqekACw==} peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - '@docusaurus/utils-common@3.4.0': - resolution: {integrity: sha512-NVx54Wr4rCEKsjOH5QEVvxIqVvm+9kh7q8aYTU5WzUU9/Hctd6aTrcZ3G0Id4zYJ+AeaG5K5qHA4CY5Kcm2iyQ==} - engines: {node: '>=18.0'} - peerDependencies: - '@docusaurus/types': '*' - peerDependenciesMeta: - '@docusaurus/types': - optional: true - '@docusaurus/utils-common@3.5.2': resolution: {integrity: sha512-i0AZjHiRgJU6d7faQngIhuHKNrszpL/SHQPgF1zH4H+Ij6E9NBYGy6pkcGWToIv7IVPbs+pQLh1P3whn0gWXVg==} engines: {node: '>=18.0'} @@ -3529,23 +3459,10 @@ packages: '@docusaurus/types': optional: true - '@docusaurus/utils-validation@3.4.0': - resolution: {integrity: sha512-hYQ9fM+AXYVTWxJOT1EuNaRnrR2WGpRdLDQG07O8UOpsvCPWUVOeo26Rbm0JWY2sGLfzAb+tvJ62yF+8F+TV0g==} - engines: {node: '>=18.0'} - '@docusaurus/utils-validation@3.5.2': resolution: {integrity: sha512-m+Foq7augzXqB6HufdS139PFxDC5d5q2QKZy8q0qYYvGdI6nnlNsGH4cIGsgBnV7smz+mopl3g4asbSDvMV0jA==} engines: {node: '>=18.0'} - '@docusaurus/utils@3.4.0': - resolution: {integrity: sha512-fRwnu3L3nnWaXOgs88BVBmG1yGjcQqZNHG+vInhEa2Sz2oQB+ZjbEMO5Rh9ePFpZ0YDiDUhpaVjwmS+AU2F14g==} - engines: {node: '>=18.0'} - peerDependencies: - '@docusaurus/types': '*' - peerDependenciesMeta: - '@docusaurus/types': - optional: true - '@docusaurus/utils@3.5.2': resolution: {integrity: sha512-33QvcNFh+Gv+C2dP9Y9xWEzMgf3JzrpL2nW9PopidiohS1nDcyknKRx2DWaFvyVTTYIkkABVSr073VTj/NITNA==} engines: {node: '>=18.0'} @@ -8744,10 +8661,6 @@ packages: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} - clsx@1.2.1: - resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} - engines: {node: '>=6'} - clsx@2.0.0: resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==} engines: {node: '>=6'} @@ -9630,15 +9543,6 @@ packages: peerDependencies: typedoc-plugin-markdown: '>=4.0.0' - docusaurus-theme-search-typesense@0.20.0-0: - resolution: {integrity: sha512-MW6fLJsZYfKKDRXC6pTe77OMhyQBishJO/L1M14hZymavKW2IyYFy+Mczp8TXL9QqvkLsW7Ja7YtnWXjmt5sCw==} - engines: {node: '>=18'} - peerDependencies: - '@docusaurus/core': 3.4.0 - '@docusaurus/theme-common': 3.4.0 - react: ^18.0.0 - react-dom: ^18.0.0 - dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} @@ -12126,10 +12030,6 @@ packages: resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} engines: {node: '>=18'} - loglevel@1.9.2: - resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} - engines: {node: '>= 0.6.0'} - longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -15851,35 +15751,6 @@ packages: engines: {node: '>=14.17'} hasBin: true - typesense-docsearch-css@0.4.1: - resolution: {integrity: sha512-mN8K18pfIpCrhzsMAJBzoS7l/YDcC4P3f9vsScenUceXmC8n3FCPldmF10dKDJmK3Lr7aAScQt70jCA5126y2w==} - - typesense-docsearch-react@3.4.1: - resolution: {integrity: sha512-d0PQym/B/p5oP+hfdFEOH6goiKa1JLR63bikZSDGq1+jT2FtuwNrdMGVBZZMNFUsXVsJRA8ULHJpsREmfSJmVw==} - peerDependencies: - '@types/react': '>= 16.8.0 < 19.0.0' - react: '>= 16.8.0 < 19.0.0' - react-dom: '>= 16.8.0 < 19.0.0' - peerDependenciesMeta: - '@types/react': - optional: true - react: - optional: true - react-dom: - optional: true - - typesense-instantsearch-adapter@2.8.0: - resolution: {integrity: sha512-2q4QVpHoUV0ncf1XOqIC0dufOTkFRxQ0mHzg//H3WK02ZYqdNNPCAacZODhQlltl1cNJdTI8Y4uuGVd6fJuGzw==} - engines: {node: '>=16'} - peerDependencies: - '@babel/runtime': ^7.17.2 - - typesense@1.8.2: - resolution: {integrity: sha512-aBpePjA99Qvo+OP2pJwMpvga4Jrm1Y2oV5NsrWXBxlqUDNEUCPZBIksPv2Hq0jxQxHhLLyJVbjXjByXsvpCDVA==} - engines: {node: '>=18'} - peerDependencies: - '@babel/runtime': ^7.23.2 - ua-parser-js@1.0.39: resolution: {integrity: sha512-k24RCVWlEcjkdOxYmVJgeD/0a1TiSpqLg+ZalVGV9lsnr4yqu0w7tX/x2xX6G4zpkgQnRf89lxuZ1wsbjXM8lw==} hasBin: true @@ -16817,10 +16688,6 @@ snapshots: '@adraffy/ens-normalize@1.11.0': {} - '@algolia/autocomplete-core@1.8.2': - dependencies: - '@algolia/autocomplete-shared': 1.8.2 - '@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)': dependencies: '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) @@ -16837,20 +16704,12 @@ snapshots: - '@algolia/client-search' - algoliasearch - '@algolia/autocomplete-preset-algolia@1.8.2(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)': - dependencies: - '@algolia/autocomplete-shared': 1.8.2 - '@algolia/client-search': 4.24.0 - algoliasearch: 4.24.0 - '@algolia/autocomplete-preset-algolia@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)': dependencies: '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) '@algolia/client-search': 4.24.0 algoliasearch: 4.24.0 - '@algolia/autocomplete-shared@1.8.2': {} - '@algolia/autocomplete-shared@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)': dependencies: '@algolia/client-search': 4.24.0 @@ -18521,97 +18380,6 @@ snapshots: transitivePeerDependencies: - '@algolia/client-search' - '@docusaurus/core@3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': - dependencies: - '@babel/core': 7.25.2 - '@babel/generator': 7.25.6 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-transform-runtime': 7.25.4(@babel/core@7.25.2) - '@babel/preset-env': 7.25.4(@babel/core@7.25.2) - '@babel/preset-react': 7.24.7(@babel/core@7.25.2) - '@babel/preset-typescript': 7.24.7(@babel/core@7.25.2) - '@babel/runtime': 7.25.6 - '@babel/runtime-corejs3': 7.25.6 - '@babel/traverse': 7.25.6 - '@docusaurus/cssnano-preset': 3.4.0 - '@docusaurus/logger': 3.4.0 - '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) - autoprefixer: 10.4.20(postcss@8.4.47) - babel-loader: 9.2.1(@babel/core@7.25.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - babel-plugin-dynamic-import-node: 2.3.3 - boxen: 6.2.1 - chalk: 4.1.2 - chokidar: 3.6.0 - clean-css: 5.3.3 - cli-table3: 0.6.5 - combine-promises: 1.2.0 - commander: 5.1.0 - copy-webpack-plugin: 11.0.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - core-js: 3.38.1 - css-loader: 6.11.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - cssnano: 6.1.2(postcss@8.4.47) - del: 6.1.1 - detect-port: 1.6.1 - escape-html: 1.0.3 - eta: 2.2.0 - eval: 0.1.8 - file-loader: 6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - fs-extra: 11.2.0 - html-minifier-terser: 7.2.0 - html-tags: 3.3.1 - html-webpack-plugin: 5.6.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - leven: 3.1.0 - lodash: 4.17.21 - mini-css-extract-plugin: 2.9.1(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - p-map: 4.0.0 - postcss: 8.4.47 - postcss-loader: 7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - prompts: 2.4.2 - react: 18.3.1 - react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - react-dom: 18.3.1(react@18.3.1) - react-helmet-async: 1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' - react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - react-router: 5.3.4(react@18.3.1) - react-router-config: 5.1.1(react-router@5.3.4(react@18.3.1))(react@18.3.1) - react-router-dom: 5.3.4(react@18.3.1) - rtl-detect: 1.1.2 - semver: 7.6.3 - serve-handler: 6.1.5 - shelljs: 0.8.5 - terser-webpack-plugin: 5.3.10(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - tslib: 2.7.0 - update-notifier: 6.0.2 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) - webpack-bundle-analyzer: 4.10.2 - webpack-dev-server: 4.15.2(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - webpack-merge: 5.10.0 - webpackbar: 5.0.2(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - transitivePeerDependencies: - - '@docusaurus/types' - - '@parcel/css' - - '@rspack/core' - - '@swc/core' - - '@swc/css' - - bufferutil - - csso - - debug - - esbuild - - eslint - - lightningcss - - supports-color - - typescript - - uglify-js - - utf-8-validate - - vue-template-compiler - - webpack-cli - '@docusaurus/core@3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': dependencies: '@babel/core': 7.25.2 @@ -18704,13 +18472,6 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/cssnano-preset@3.4.0': - dependencies: - cssnano-preset-advanced: 6.1.2(postcss@8.4.47) - postcss: 8.4.47 - postcss-sort-media-queries: 5.2.0(postcss@8.4.47) - tslib: 2.7.0 - '@docusaurus/cssnano-preset@3.5.2': dependencies: cssnano-preset-advanced: 6.1.2(postcss@8.4.47) @@ -18718,53 +18479,11 @@ snapshots: postcss-sort-media-queries: 5.2.0(postcss@8.4.47) tslib: 2.7.0 - '@docusaurus/logger@3.4.0': - dependencies: - chalk: 4.1.2 - tslib: 2.7.0 - '@docusaurus/logger@3.5.2': dependencies: chalk: 4.1.2 tslib: 2.7.0 - '@docusaurus/mdx-loader@3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': - dependencies: - '@docusaurus/logger': 3.4.0 - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) - '@mdx-js/mdx': 3.0.1 - '@slorber/remark-comment': 1.0.0 - escape-html: 1.0.3 - estree-util-value-to-estree: 3.1.2 - file-loader: 6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - fs-extra: 11.2.0 - image-size: 1.1.1 - mdast-util-mdx: 3.0.0 - mdast-util-to-string: 4.0.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - rehype-raw: 7.0.0 - remark-directive: 3.0.0 - remark-emoji: 4.0.1 - remark-frontmatter: 5.0.0 - remark-gfm: 4.0.0 - stringify-object: 3.3.0 - tslib: 2.7.0 - unified: 11.0.5 - unist-util-visit: 5.0.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - vfile: 6.0.3 - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) - transitivePeerDependencies: - - '@docusaurus/types' - - '@swc/core' - - esbuild - - supports-color - - typescript - - uglify-js - - webpack-cli - '@docusaurus/mdx-loader@3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: '@docusaurus/logger': 3.5.2 @@ -18802,24 +18521,6 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/module-type-aliases@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@docusaurus/types': 3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@types/history': 4.7.11 - '@types/react': 18.3.9 - '@types/react-router-config': 5.0.11 - '@types/react-router-dom': 5.3.3 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-helmet-async: 2.0.5(react@18.3.1) - react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' - transitivePeerDependencies: - - '@swc/core' - - esbuild - - supports-color - - uglify-js - - webpack-cli - '@docusaurus/module-type-aliases@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -18880,44 +18581,6 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-content-docs@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': - dependencies: - '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/logger': 3.4.0 - '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/module-type-aliases': 3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/types': 3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) - '@types/react-router-config': 5.0.11 - combine-promises: 1.2.0 - fs-extra: 11.2.0 - js-yaml: 4.1.0 - lodash: 4.17.21 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - tslib: 2.7.0 - utility-types: 3.11.0 - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) - transitivePeerDependencies: - - '@parcel/css' - - '@rspack/core' - - '@swc/core' - - '@swc/css' - - bufferutil - - csso - - debug - - esbuild - - eslint - - lightningcss - - supports-color - - typescript - - uglify-js - - utf-8-validate - - vue-template-compiler - - webpack-cli - '@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': dependencies: '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) @@ -19368,11 +19031,6 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/theme-translations@3.4.0': - dependencies: - fs-extra: 11.2.0 - tslib: 2.7.0 - '@docusaurus/theme-translations@3.5.2': dependencies: fs-extra: 11.2.0 @@ -19380,26 +19038,6 @@ snapshots: '@docusaurus/tsconfig@3.5.2': {} - '@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@mdx-js/mdx': 3.0.1 - '@types/history': 4.7.11 - '@types/react': 18.3.9 - commander: 5.1.0 - joi: 17.13.3 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-helmet-async: 1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - utility-types: 3.11.0 - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) - webpack-merge: 5.10.0 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - supports-color - - uglify-js - - webpack-cli - '@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@mdx-js/mdx': 3.0.1 @@ -19420,62 +19058,12 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils-common@3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': - dependencies: - tslib: 2.7.0 - optionalDependencies: - '@docusaurus/types': 3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - - '@docusaurus/utils-common@3.4.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': - dependencies: - tslib: 2.7.0 - optionalDependencies: - '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-common@3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': dependencies: tslib: 2.7.0 optionalDependencies: '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation@3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2)': - dependencies: - '@docusaurus/logger': 3.4.0 - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - fs-extra: 11.2.0 - joi: 17.13.3 - js-yaml: 4.1.0 - lodash: 4.17.21 - tslib: 2.7.0 - transitivePeerDependencies: - - '@docusaurus/types' - - '@swc/core' - - esbuild - - supports-color - - typescript - - uglify-js - - webpack-cli - - '@docusaurus/utils-validation@3.4.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2)': - dependencies: - '@docusaurus/logger': 3.4.0 - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - fs-extra: 11.2.0 - joi: 17.13.3 - js-yaml: 4.1.0 - lodash: 4.17.21 - tslib: 2.7.0 - transitivePeerDependencies: - - '@docusaurus/types' - - '@swc/core' - - esbuild - - supports-color - - typescript - - uglify-js - - webpack-cli - '@docusaurus/utils-validation@3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2)': dependencies: '@docusaurus/logger': 3.5.2 @@ -19495,70 +19083,6 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils@3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2)': - dependencies: - '@docusaurus/logger': 3.4.0 - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@svgr/webpack': 8.1.0(typescript@5.6.2) - escape-string-regexp: 4.0.0 - file-loader: 6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - fs-extra: 11.2.0 - github-slugger: 1.5.0 - globby: 11.1.0 - gray-matter: 4.0.3 - jiti: 1.21.6 - js-yaml: 4.1.0 - lodash: 4.17.21 - micromatch: 4.0.8 - prompts: 2.4.2 - resolve-pathname: 3.0.0 - shelljs: 0.8.5 - tslib: 2.7.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - utility-types: 3.11.0 - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) - optionalDependencies: - '@docusaurus/types': 3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - transitivePeerDependencies: - - '@swc/core' - - esbuild - - supports-color - - typescript - - uglify-js - - webpack-cli - - '@docusaurus/utils@3.4.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2)': - dependencies: - '@docusaurus/logger': 3.4.0 - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@svgr/webpack': 8.1.0(typescript@5.6.2) - escape-string-regexp: 4.0.0 - file-loader: 6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - fs-extra: 11.2.0 - github-slugger: 1.5.0 - globby: 11.1.0 - gray-matter: 4.0.3 - jiti: 1.21.6 - js-yaml: 4.1.0 - lodash: 4.17.21 - micromatch: 4.0.8 - prompts: 2.4.2 - resolve-pathname: 3.0.0 - shelljs: 0.8.5 - tslib: 2.7.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))) - utility-types: 3.11.0 - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) - optionalDependencies: - '@docusaurus/types': 3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - transitivePeerDependencies: - - '@swc/core' - - esbuild - - supports-color - - typescript - - uglify-js - - webpack-cli - '@docusaurus/utils@3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2)': dependencies: '@docusaurus/logger': 3.5.2 @@ -21128,7 +20652,7 @@ snapshots: pump: 3.0.2 tar-fs: 2.1.1 - '@nestjs/cache-manager@2.2.2(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(cache-manager@5.7.6)(rxjs@7.8.1)': + '@nestjs/cache-manager@2.2.2(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4)(cache-manager@5.7.6)(rxjs@7.8.1)': dependencies: '@nestjs/common': 10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.4.4(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -21207,7 +20731,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@nestjs/schedule@4.1.1(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))': + '@nestjs/schedule@4.1.1(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4)': dependencies: '@nestjs/common': 10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.4.4(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -21236,7 +20760,7 @@ snapshots: transitivePeerDependencies: - chokidar - '@nestjs/testing@10.4.4(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4))': + '@nestjs/testing@10.4.4(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4)(@nestjs/platform-express@10.4.4)': dependencies: '@nestjs/common': 10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.4.4(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -24374,7 +23898,7 @@ snapshots: '@types/webextension-polyfill@0.10.7': {} - '@types/webpack@5.28.5(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4(webpack@5.95.0))': + '@types/webpack@5.28.5(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)': dependencies: '@types/node': 20.16.9 tapable: 2.2.1 @@ -25153,17 +24677,17 @@ snapshots: '@webassemblyjs/ast': 1.12.1 '@xtuc/long': 4.2.2 - '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4))': + '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.95.0)': dependencies: webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack@5.95.0) - '@webpack-cli/info@2.0.2(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4))': + '@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.95.0)': dependencies: webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack@5.95.0) - '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4))': + '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack@5.95.0)': dependencies: webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack@5.95.0) @@ -26265,8 +25789,6 @@ snapshots: clone@1.0.4: {} - clsx@1.2.1: {} - clsx@2.0.0: {} clsx@2.1.1: {} @@ -26459,7 +25981,7 @@ snapshots: copy-text-to-clipboard@3.2.0: {} - copy-webpack-plugin@11.0.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)): + copy-webpack-plugin@11.0.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: fast-glob: 3.3.2 glob-parent: 6.0.2 @@ -26467,9 +25989,9 @@ snapshots: normalize-path: 3.0.0 schema-utils: 4.2.0 serialize-javascript: 6.0.2 - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) - copy-webpack-plugin@11.0.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): + copy-webpack-plugin@11.0.0(webpack@5.95.0): dependencies: fast-glob: 3.3.2 glob-parent: 6.0.2 @@ -26477,7 +25999,7 @@ snapshots: normalize-path: 3.0.0 schema-utils: 4.2.0 serialize-javascript: 6.0.2 - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) core-js-compat@3.38.1: dependencies: @@ -26617,7 +26139,7 @@ snapshots: postcss-selector-parser: 6.1.2 postcss-value-parser: 4.2.0 - css-loader@6.11.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)): + css-loader@6.11.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: icss-utils: 5.1.0(postcss@8.4.47) postcss: 8.4.47 @@ -26628,9 +26150,9 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.6.3 optionalDependencies: - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) - css-loader@6.11.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): + css-loader@6.11.0(webpack@5.95.0): dependencies: icss-utils: 5.1.0(postcss@8.4.47) postcss: 8.4.47 @@ -26641,7 +26163,7 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.6.3 optionalDependencies: - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: @@ -27200,49 +26722,6 @@ snapshots: dependencies: typedoc-plugin-markdown: 4.2.10(typedoc@0.26.11(typescript@5.6.2)) - docusaurus-theme-search-typesense@0.20.0-0(iea5eyhbiud2dlcqtud2g4pxzm): - dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/logger': 3.4.0 - '@docusaurus/plugin-content-docs': 3.4.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/theme-translations': 3.4.0 - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.5.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.7.28(@swc/helpers@0.5.5))(typescript@5.6.2) - algoliasearch-helper: 3.22.5(algoliasearch@4.24.0) - clsx: 1.2.1 - eta: 2.2.0 - fs-extra: 10.1.0 - lodash: 4.17.21 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - tslib: 2.7.0 - typesense-docsearch-react: 3.4.1(@algolia/client-search@4.24.0)(@babel/runtime@7.25.6)(@types/react@18.3.9)(algoliasearch@4.24.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - typesense-instantsearch-adapter: 2.8.0(@babel/runtime@7.25.6) - utility-types: 3.11.0 - transitivePeerDependencies: - - '@algolia/client-search' - - '@babel/runtime' - - '@docusaurus/types' - - '@parcel/css' - - '@rspack/core' - - '@swc/core' - - '@swc/css' - - '@types/react' - - algoliasearch - - bufferutil - - csso - - debug - - esbuild - - eslint - - lightningcss - - supports-color - - typescript - - uglify-js - - utf-8-validate - - vue-template-compiler - - webpack-cli - dom-accessibility-api@0.5.16: {} dom-accessibility-api@0.6.3: {} @@ -27624,7 +27103,7 @@ snapshots: '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.6.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1) eslint-plugin-import: 2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.1) eslint-plugin-react: 7.37.0(eslint@8.57.1) @@ -27648,7 +27127,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.3.7(supports-color@8.1.1) @@ -27674,7 +27153,7 @@ snapshots: '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.6.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1) transitivePeerDependencies: - supports-color @@ -27808,7 +27287,7 @@ snapshots: eslint-visitor-keys@4.1.0: {} - eslint-webpack-plugin@4.2.0(eslint@8.57.1)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)): + eslint-webpack-plugin@4.2.0(eslint@8.57.1)(webpack@5.95.0): dependencies: '@types/eslint': 8.56.12 eslint: 8.57.1 @@ -29112,7 +28591,7 @@ snapshots: html-void-elements@3.0.0: {} - html-webpack-plugin@5.6.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)): + html-webpack-plugin@5.6.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -29120,9 +28599,9 @@ snapshots: pretty-error: 4.0.0 tapable: 2.2.1 optionalDependencies: - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) - html-webpack-plugin@5.6.0(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): + html-webpack-plugin@5.6.0(webpack@5.95.0): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -29130,7 +28609,7 @@ snapshots: pretty-error: 4.0.0 tapable: 2.2.1 optionalDependencies: - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) htmlparser2@6.1.0: dependencies: @@ -30454,8 +29933,6 @@ snapshots: strip-ansi: 7.1.0 wrap-ansi: 9.0.0 - loglevel@1.9.2: {} - longest-streak@3.1.0: {} loose-envify@1.4.0: @@ -31339,17 +30816,17 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.9.1(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)): + mini-css-extract-plugin@2.9.1(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: schema-utils: 4.2.0 tapable: 2.2.1 - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) - mini-css-extract-plugin@2.9.1(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): + mini-css-extract-plugin@2.9.1(webpack@5.95.0): dependencies: schema-utils: 4.2.0 tapable: 2.2.1 - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) mini-svg-data-uri@1.4.4: {} @@ -32302,23 +31779,23 @@ snapshots: postcss: 8.4.47 ts-node: 10.9.2(@swc/core@1.7.28(@swc/helpers@0.5.5))(@types/node@22.7.3)(typescript@5.6.2) - postcss-loader@7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)): + postcss-loader@7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: cosmiconfig: 8.3.6(typescript@5.6.2) jiti: 1.21.6 postcss: 8.4.47 semver: 7.6.3 - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) transitivePeerDependencies: - typescript - postcss-loader@7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): + postcss-loader@7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0): dependencies: cosmiconfig: 8.3.6(typescript@5.6.2) jiti: 1.21.6 postcss: 8.4.47 semver: 7.6.3 - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) transitivePeerDependencies: - typescript @@ -33653,7 +33130,7 @@ snapshots: safer-buffer@2.1.2: {} - sass-loader@13.3.3(sass@1.79.3)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)): + sass-loader@13.3.3(sass@1.79.3)(webpack@5.95.0): dependencies: neo-async: 2.6.2 webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) @@ -34507,25 +33984,25 @@ snapshots: optionalDependencies: '@swc/core': 1.7.28(@swc/helpers@0.5.5) - terser-webpack-plugin@5.3.10(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)): + terser-webpack-plugin@5.3.10(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.34.0 - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) optionalDependencies: '@swc/core': 1.7.28(@swc/helpers@0.5.5) - terser-webpack-plugin@5.3.10(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): + terser-webpack-plugin@5.3.10(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack@5.95.0): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.34.0 - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) optionalDependencies: '@swc/core': 1.7.28(@swc/helpers@0.5.5) @@ -34692,7 +34169,7 @@ snapshots: '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.25.2) - ts-loader@9.5.1(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)): + ts-loader@9.5.1(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): dependencies: chalk: 4.1.2 enhanced-resolve: 5.17.1 @@ -34700,9 +34177,9 @@ snapshots: semver: 7.6.3 source-map: 0.7.4 typescript: 5.6.2 - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) - ts-loader@9.5.1(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))): + ts-loader@9.5.1(typescript@5.6.2)(webpack@5.95.0): dependencies: chalk: 4.1.2 enhanced-resolve: 5.17.1 @@ -34710,7 +34187,7 @@ snapshots: semver: 7.6.3 source-map: 0.7.4 typescript: 5.6.2 - webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5)) + webpack: 5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4) ts-log@2.2.5: {} @@ -34966,40 +34443,6 @@ snapshots: typescript@5.6.2: {} - typesense-docsearch-css@0.4.1: {} - - typesense-docsearch-react@3.4.1(@algolia/client-search@4.24.0)(@babel/runtime@7.25.6)(@types/react@18.3.9)(algoliasearch@4.24.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@algolia/autocomplete-core': 1.8.2 - '@algolia/autocomplete-preset-algolia': 1.8.2(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) - typesense: 1.8.2(@babel/runtime@7.25.6) - typesense-docsearch-css: 0.4.1 - typesense-instantsearch-adapter: 2.8.0(@babel/runtime@7.25.6) - optionalDependencies: - '@types/react': 18.3.9 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - transitivePeerDependencies: - - '@algolia/client-search' - - '@babel/runtime' - - algoliasearch - - debug - - typesense-instantsearch-adapter@2.8.0(@babel/runtime@7.25.6): - dependencies: - '@babel/runtime': 7.25.6 - typesense: 1.8.2(@babel/runtime@7.25.6) - transitivePeerDependencies: - - debug - - typesense@1.8.2(@babel/runtime@7.25.6): - dependencies: - '@babel/runtime': 7.25.6 - axios: 1.7.7(debug@4.3.7) - loglevel: 1.9.2 - transitivePeerDependencies: - - debug - ua-parser-js@1.0.39: {} uc.micro@2.1.0: {} @@ -35944,9 +35387,9 @@ snapshots: webpack-cli@5.1.4(webpack@5.95.0): dependencies: '@discoveryjs/json-ext': 0.5.7 - '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) - '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) - '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) + '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.95.0) + '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4)(webpack@5.95.0) + '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4)(webpack@5.95.0) colorette: 2.0.20 commander: 10.0.1 cross-spawn: 7.0.5 @@ -36101,7 +35544,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack@5.95.0(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack-cli@5.1.4)) + terser-webpack-plugin: 5.3.10(@swc/core@1.7.28(@swc/helpers@0.5.5))(webpack@5.95.0) watchpack: 2.4.2 webpack-sources: 3.2.3 optionalDependencies: From 070a6353f2f202473ac2fa58569df57fa4094804 Mon Sep 17 00:00:00 2001 From: cpl121 <100352899+cpl121@users.noreply.github.com> Date: Tue, 17 Dec 2024 18:19:13 +0100 Subject: [PATCH 14/14] chore(ts-sdk): regenerate graphql and json rpc to update comments (#4519) --- sdk/typescript/src/client/types/params.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sdk/typescript/src/client/types/params.ts b/sdk/typescript/src/client/types/params.ts index feb1c6ccf3c..6d6a88d5b48 100644 --- a/sdk/typescript/src/client/types/params.ts +++ b/sdk/typescript/src/client/types/params.ts @@ -326,7 +326,8 @@ export interface GetValidatorsApyParams {} /** Return list of events for a specified query criteria. */ export interface QueryEventsParams { /** - * The event query criteria. See [Event filter](https://docs.iota.org/developer/iota-101/using-events#applying-event-filters) + * The event query criteria. See + * [Event filter](https://docs.iota.org/developer/iota-101/using-events#applying-event-filters) * documentation for examples. */ query: RpcTypes.IotaEventFilter; @@ -353,7 +354,8 @@ export type QueryTransactionBlocksParams = { export interface SubscribeEventParams { /** * The filter criteria of the event stream. See - * [Event filter](https://docs.iota.org/developer/iota-101/using-events#applying-event-filters) documentation for examples. + * [Event filter](https://docs.iota.org/developer/iota-101/using-events#applying-event-filters) + * documentation for examples. */ filter: RpcTypes.IotaEventFilter; }