From 9347c2d4981920f350a57ea87828c28b1c2a7f22 Mon Sep 17 00:00:00 2001 From: Buffrr Date: Fri, 10 Oct 2025 23:24:25 +0200 Subject: [PATCH 01/10] Update README with Subspaces development details --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 5981d2b..4ee4520 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,11 @@ Checkout [releases](https://github.com/spacesprotocol/spaces/releases) for an immediately usable binary version of this software. +## Work on Subspaces + +Spaces is live on mainnet. Subspaces is live on testnet4, and development work is happening on the [subspaces branch](https://github.com/spacesprotocol/spaces/tree/subspaces). + + ## What does it do? Spaces are sovereign Bitcoin identities. They leverage the existing infrastructure and security of Bitcoin without requiring a new blockchain or any modifications to Bitcoin itself [learn more](https://spacesprotocol.org). From 2a936686d187426efb6c90ccb6b7f35258d27ada Mon Sep 17 00:00:00 2001 From: Alex Tsokurov Date: Thu, 27 Nov 2025 18:45:59 +0100 Subject: [PATCH 02/10] set 0 height for recovered wallets --- client/src/rpc.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/client/src/rpc.rs b/client/src/rpc.rs index 447a583..736a920 100644 --- a/client/src/rpc.rs +++ b/client/src/rpc.rs @@ -513,14 +513,13 @@ impl WalletManager { .map_err(|_| anyhow!("Mnemonic generation error"))?; let start_block = self.get_wallet_start_block(client).await?; - self.setup_new_wallet(name.to_string(), mnemonic.to_string(), start_block)?; + self.setup_new_wallet(name.to_string(), mnemonic.to_string(), Some(start_block.height))?; self.load_wallet(name).await?; Ok(mnemonic.to_string()) } - pub async fn recover_wallet(&self, client: &reqwest::Client, name: &str, mnemonic: &str) -> anyhow::Result<()> { - let start_block = self.get_wallet_start_block(client).await?; - self.setup_new_wallet(name.to_string(), mnemonic.to_string(), start_block)?; + pub async fn recover_wallet(&self, name: &str, mnemonic: &str) -> anyhow::Result<()> { + self.setup_new_wallet(name.to_string(), mnemonic.to_string(), None)?; self.load_wallet(name).await?; Ok(()) } @@ -529,14 +528,14 @@ impl WalletManager { &self, name: String, mnemonic: String, - start_block: BlockId, + start_block_height: Option, ) -> anyhow::Result<()> { let wallet_path = self.data_dir.join(&name); if wallet_path.exists() { return Err(anyhow!(format!("Wallet `{}` already exists", name))); } - let export = self.wallet_from_mnemonic(name.clone(), mnemonic, start_block)?; + let export = self.wallet_from_mnemonic(name.clone(), mnemonic, start_block_height)?; fs::create_dir_all(&wallet_path)?; let wallet_export_path = wallet_path.join("wallet.json"); let mut file = fs::File::create(wallet_export_path)?; @@ -548,7 +547,7 @@ impl WalletManager { &self, name: String, mnemonic: String, - start_block: BlockId, + start_block_height: Option, ) -> anyhow::Result { let (network, _) = self.fallback_network(); let xpriv = Self::descriptor_from_mnemonic(network, &mnemonic)?; @@ -558,7 +557,7 @@ impl WalletManager { .network(network) .create_wallet_no_persist()?; let export = - WalletExport::export_wallet(&tmp, &name, start_block.height).map_err(|e| anyhow!(e))?; + WalletExport::export_wallet(&tmp, &name, start_block_height.unwrap_or_default()).map_err(|e| anyhow!(e))?; Ok(export) } @@ -946,7 +945,7 @@ impl RpcServer for RpcServerImpl { async fn wallet_recover(&self, name: &str, mnemonic: String) -> Result<(), ErrorObjectOwned> { self.wallet_manager - .recover_wallet(&self.client, name, &mnemonic) + .recover_wallet(name, &mnemonic) .await .map_err(|error| { ErrorObjectOwned::owned(RPC_WALLET_NOT_LOADED, error.to_string(), None::) From 92b32afb7d53204c741657180ae6bd93374d061e Mon Sep 17 00:00:00 2001 From: Alex Tsokurov Date: Thu, 27 Nov 2025 19:01:23 +0100 Subject: [PATCH 03/10] use genesis block height for recovered wallets --- client/src/config.rs | 12 +++++++++++- client/src/rpc.rs | 8 +++++++- client/src/spaces.rs | 8 +------- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/client/src/config.rs b/client/src/config.rs index 657cf18..f15ed42 100644 --- a/client/src/config.rs +++ b/client/src/config.rs @@ -15,7 +15,7 @@ use rand::{ {thread_rng, Rng}, }; use serde::Deserialize; -use spaces_protocol::bitcoin::Network; +use spaces_protocol::{bitcoin::Network, constants::ChainAnchor}; use crate::{ auth::{auth_token_from_cookie, auth_token_from_creds}, @@ -117,6 +117,16 @@ impl ExtendedNetwork { _ => Err(()), } } + + pub fn genesis(&self) -> ChainAnchor { + match self { + ExtendedNetwork::Testnet => ChainAnchor::TESTNET(), + ExtendedNetwork::Testnet4 => ChainAnchor::TESTNET4(), + ExtendedNetwork::Regtest => ChainAnchor::REGTEST(), + ExtendedNetwork::Mainnet => ChainAnchor::MAINNET(), + _ => panic!("unsupported network"), + } + } } impl Args { diff --git a/client/src/rpc.rs b/client/src/rpc.rs index 736a920..a3be3fa 100644 --- a/client/src/rpc.rs +++ b/client/src/rpc.rs @@ -556,8 +556,14 @@ impl WalletManager { let tmp = bdk::Wallet::create(external, internal) .network(network) .create_wallet_no_persist()?; + + let start_block_height = match start_block_height { + Some(height) => height, + None => self.network.genesis().height, + }; + let export = - WalletExport::export_wallet(&tmp, &name, start_block_height.unwrap_or_default()).map_err(|e| anyhow!(e))?; + WalletExport::export_wallet(&tmp, &name, start_block_height).map_err(|e| anyhow!(e))?; Ok(export) } diff --git a/client/src/spaces.rs b/client/src/spaces.rs index ed0cfee..92b046d 100644 --- a/client/src/spaces.rs +++ b/client/src/spaces.rs @@ -257,12 +257,6 @@ impl Spaced { } pub fn genesis(network: ExtendedNetwork) -> ChainAnchor { - match network { - ExtendedNetwork::Testnet => ChainAnchor::TESTNET(), - ExtendedNetwork::Testnet4 => ChainAnchor::TESTNET4(), - ExtendedNetwork::Regtest => ChainAnchor::REGTEST(), - ExtendedNetwork::Mainnet => ChainAnchor::MAINNET(), - _ => panic!("unsupported network"), - } + network.genesis() } } From ab51cd157cce095e7f37e324d06dfbd72c40472f Mon Sep 17 00:00:00 2001 From: horologger Date: Sat, 13 Dec 2025 12:38:17 -0500 Subject: [PATCH 04/10] Fix panic when querying revoked spaces Fix data inconsistency in RevokeReason::Expired handling that caused panics when querying spaces that were revoked due to expiration. Root cause: Expired revocations only removed Outpoint->Spaceout mapping but left Space->Outpoint mapping, creating inconsistent state. Changes: - Remove Space->Outpoint mapping in Expired revocation handler - Handle inconsistencies gracefully in get_space_info by returning None and cleaning up orphaned Space->Outpoint mappings instead of panicking --- client/src/client.rs | 7 ++++++- client/src/store.rs | 17 +++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/client/src/client.rs b/client/src/client.rs index b056343..f1996ac 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -279,7 +279,12 @@ impl Client { // Space => Outpoint mapping will be removed // since this type of revocation only happens when an // expired space is being re-opened for auction. - // No bids here so only remove Outpoint -> Spaceout + // Remove both Space -> Outpoint and Outpoint -> Spaceout mappings + if let Some(space) = update.output.spaceout.space.as_ref() { + let base_hash = Sha256::hash(space.name.as_ref()); + let space_key = SpaceKey::from(base_hash); + state.remove(space_key); + } let hash = OutpointKey::from_outpoint::(update.output.outpoint()); state.remove(hash); diff --git a/client/src/store.rs b/client/src/store.rs index e87dc3d..95a5f63 100644 --- a/client/src/store.rs +++ b/client/src/store.rs @@ -218,10 +218,19 @@ impl ChainState for LiveSnapshot { if let Some(outpoint) = outpoint { let spaceout = self.get_spaceout(&outpoint)?; - return Ok(Some(FullSpaceOut { - txid: outpoint.txid, - spaceout: spaceout.expect("should exist if outpoint exists"), - })); + // Handle data inconsistency gracefully: if outpoint exists but spaceout doesn't, + // this indicates the space was revoked but the space->outpoint mapping wasn't cleaned up. + // Clean up the inconsistent mapping and return None instead of panicking. + if let Some(spaceout) = spaceout { + return Ok(Some(FullSpaceOut { + txid: outpoint.txid, + spaceout, + })); + } else { + // Clean up the inconsistent space->outpoint mapping + self.remove(*space_hash); + return Ok(None); + } } Ok(None) } From 5831c5010cf8fb3c67b812a0b76fffb582c4d3bd Mon Sep 17 00:00:00 2001 From: horologger Date: Sat, 13 Dec 2025 12:48:22 -0500 Subject: [PATCH 05/10] Fix panic in open subcommand when spaceout is missing Fix data inconsistency handling in prepare_open that caused panics when opening spaces that were revoked due to expiration. Root cause: When an outpoint exists but spaceout doesn't (due to inconsistent state from Expired revocations), the code would panic with 'spaceout exists' instead of handling it gracefully. Changes: - Replace expect() with match statement to handle None case - Treat missing spaceout as new space (space was revoked, so it's effectively not registered anymore) --- protocol/src/script.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/protocol/src/script.rs b/protocol/src/script.rs index b2f77b8..95a53e0 100644 --- a/protocol/src/script.rs +++ b/protocol/src/script.rs @@ -148,10 +148,18 @@ impl SpaceScript { let existing = src.get_space_outpoint(&spacehash)?; match existing { None => OpenHistory::NewSpace(name.to_owned()), - Some(outpoint) => OpenHistory::ExistingSpace(FullSpaceOut { - txid: outpoint.txid, - spaceout: src.get_spaceout(&outpoint)?.expect("spaceout exists"), - }), + Some(outpoint) => { + // Handle data inconsistency: if spaceout doesn't exist, treat as new space + // This can happen if the space was revoked but the space->outpoint mapping + // wasn't cleaned up properly + match src.get_spaceout(&outpoint)? { + Some(spaceout) => OpenHistory::ExistingSpace(FullSpaceOut { + txid: outpoint.txid, + spaceout, + }), + None => OpenHistory::NewSpace(name.to_owned()), + } + } } }; let open = Ok(kind); From b3c6b55c463845d01926d5c87bf17bcd63a606e6 Mon Sep 17 00:00:00 2001 From: Buffrr Date: Sat, 13 Dec 2025 20:08:47 +0100 Subject: [PATCH 06/10] Bump version --- Cargo.lock | 6 +++--- client/Cargo.toml | 2 +- protocol/Cargo.toml | 2 +- wallet/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 44d0ef8..fce6a06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2332,7 +2332,7 @@ dependencies = [ [[package]] name = "spaces_client" -version = "0.0.7" +version = "0.0.8" dependencies = [ "anyhow", "assert_cmd", @@ -2366,7 +2366,7 @@ dependencies = [ [[package]] name = "spaces_protocol" -version = "0.0.7" +version = "0.0.8" dependencies = [ "bincode", "bitcoin", @@ -2408,7 +2408,7 @@ dependencies = [ [[package]] name = "spaces_wallet" -version = "0.0.7" +version = "0.0.8" dependencies = [ "anyhow", "bdk_wallet", diff --git a/client/Cargo.toml b/client/Cargo.toml index dc13ed5..ac0e48b 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spaces_client" -version = "0.0.7" +version = "0.0.8" edition = "2021" diff --git a/protocol/Cargo.toml b/protocol/Cargo.toml index 3832091..5d30094 100644 --- a/protocol/Cargo.toml +++ b/protocol/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spaces_protocol" -version = "0.0.7" +version = "0.0.8" edition = "2021" [dependencies] diff --git a/wallet/Cargo.toml b/wallet/Cargo.toml index 779239b..d1ff2b8 100644 --- a/wallet/Cargo.toml +++ b/wallet/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spaces_wallet" -version = "0.0.7" +version = "0.0.8" edition = "2021" [dependencies] From b50b5ca04f15a3244be2fe13be4fd2371a6f4f52 Mon Sep 17 00:00:00 2001 From: Buffrr Date: Sat, 13 Dec 2025 20:15:43 +0100 Subject: [PATCH 07/10] Fix macos gh actions --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7be1853..78a4fe2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,7 +17,7 @@ jobs: target: aarch64-unknown-linux-gnu - os: macos-latest target: aarch64-apple-darwin - - os: macos-13 + - os: macos-15-intel target: x86_64-apple-darwin steps: From e53e4d46f6750e75306809a4637a6e7db89bb9a1 Mon Sep 17 00:00:00 2001 From: Buffrr Date: Sat, 13 Dec 2025 20:28:55 +0100 Subject: [PATCH 08/10] Fix rust lifetimes lint --- protocol/src/lib.rs | 2 +- protocol/src/slabel.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index a8f6c63..7bf679d 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -350,7 +350,7 @@ impl FullSpaceOut { pub fn refund_signing_info( &self, - ) -> Option<(Transaction, Prevouts, schnorr::Signature)> { + ) -> Option<(Transaction, Prevouts<'_, TxOut>, schnorr::Signature)> { if self.spaceout.space.is_none() { return None; } diff --git a/protocol/src/slabel.rs b/protocol/src/slabel.rs index 4349309..28265d2 100644 --- a/protocol/src/slabel.rs +++ b/protocol/src/slabel.rs @@ -248,7 +248,7 @@ impl Display for SLabelRef<'_> { } impl SLabel { - pub fn as_name_ref(&self) -> SLabelRef { + pub fn as_name_ref(&self) -> SLabelRef<'_> { SLabelRef(&self.0) } From c852e3db35eca671e7835117c48e046fc00c9e87 Mon Sep 17 00:00:00 2001 From: Buffrr Date: Sat, 13 Dec 2025 21:14:16 +0100 Subject: [PATCH 09/10] Fix lint errors --- Cargo.lock | 8 ++++---- Cargo.toml | 5 +++++ client/Cargo.toml | 4 ++-- client/src/bin/space-cli.rs | 25 ------------------------- client/src/store.rs | 4 ++-- protocol/Cargo.toml | 4 ++-- veritas/Cargo.toml | 4 ++-- veritas/src/lib.rs | 2 +- wallet/Cargo.toml | 4 ++-- wallet/src/builder.rs | 3 +-- wallet/src/lib.rs | 8 ++++---- 11 files changed, 25 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fce6a06..37382e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2332,7 +2332,7 @@ dependencies = [ [[package]] name = "spaces_client" -version = "0.0.8" +version = "0.0.9" dependencies = [ "anyhow", "assert_cmd", @@ -2366,7 +2366,7 @@ dependencies = [ [[package]] name = "spaces_protocol" -version = "0.0.8" +version = "0.0.9" dependencies = [ "bincode", "bitcoin", @@ -2390,7 +2390,7 @@ dependencies = [ [[package]] name = "spaces_veritas" -version = "0.0.7" +version = "0.0.9" dependencies = [ "base64 0.22.1", "bincode", @@ -2408,7 +2408,7 @@ dependencies = [ [[package]] name = "spaces_wallet" -version = "0.0.8" +version = "0.0.9" dependencies = [ "anyhow", "bdk_wallet", diff --git a/Cargo.toml b/Cargo.toml index fc35b08..a35b186 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,3 +2,8 @@ resolver = "2" members = [ "client", "protocol", "veritas", "testutil", "wallet"] + + +[workspace.package] +version = "0.0.9" +edition = "2021" \ No newline at end of file diff --git a/client/Cargo.toml b/client/Cargo.toml index ac0e48b..0b96093 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "spaces_client" -version = "0.0.8" -edition = "2021" +version.workspace = true +edition.workspace = true [[bin]] diff --git a/client/src/bin/space-cli.rs b/client/src/bin/space-cli.rs index 3e89fe6..0118960 100644 --- a/client/src/bin/space-cli.rs +++ b/client/src/bin/space-cli.rs @@ -18,11 +18,9 @@ use jsonrpsee::{ core::{client::Error, ClientError}, http_client::HttpClient, }; -use serde::{Deserialize, Serialize}; use spaces_client::{ auth::{auth_token_from_cookie, auth_token_from_creds, http_client_with_auth}, config::{default_cookie_path, default_spaces_rpc_port, ExtendedNetwork}, - deserialize_base64, format::{ print_error_rpc_response, print_list_bidouts, print_list_spaces_response, print_list_transactions, print_list_unspent, print_list_wallets, print_server_info, @@ -32,7 +30,6 @@ use spaces_client::{ BidParams, ExecuteParams, OpenParams, RegisterParams, RpcClient, RpcWalletRequest, RpcWalletTxBuilder, SendCoinsParams, TransferSpacesParams, }, - serialize_base64, wallets::{AddressKind, WalletResponse}, }; use spaces_protocol::bitcoin::{Amount, FeeRate, OutPoint, Txid}; @@ -369,28 +366,6 @@ struct SpaceCli { client: HttpClient, } -#[derive(Serialize, Deserialize)] -struct SignedDnsUpdate { - serial: u32, - space: String, - #[serde( - serialize_with = "serialize_base64", - deserialize_with = "deserialize_base64" - )] - packet: Vec, - signature: Signature, - #[serde(skip_serializing_if = "Option::is_none")] - proof: Option, -} - -#[derive(Serialize, Deserialize)] -struct Base64Bytes( - #[serde( - serialize_with = "serialize_base64", - deserialize_with = "deserialize_base64" - )] - Vec, -); impl SpaceCli { async fn configure() -> anyhow::Result<(Self, Args)> { diff --git a/client/src/store.rs b/client/src/store.rs index 95a5f63..a43b683 100644 --- a/client/src/store.rs +++ b/client/src/store.rs @@ -89,11 +89,11 @@ impl Store { Ok(Database::new(Box::new(FileBackend::new(file)?), config)?) } - pub fn iter(&self) -> SnapshotIterator { + pub fn iter(&self) -> SnapshotIterator<'_, Sha256Hasher> { return self.0.iter(); } - pub fn write(&self) -> Result { + pub fn write(&self) -> Result> { Ok(self.0.begin_write()?) } diff --git a/protocol/Cargo.toml b/protocol/Cargo.toml index 5d30094..60d7712 100644 --- a/protocol/Cargo.toml +++ b/protocol/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "spaces_protocol" -version = "0.0.8" -edition = "2021" +version.workspace = true +edition.workspace = true [dependencies] bitcoin = { version = "0.32.2", features = ["base64", "serde"], default-features = false } diff --git a/veritas/Cargo.toml b/veritas/Cargo.toml index 5092c8f..e19ac08 100644 --- a/veritas/Cargo.toml +++ b/veritas/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "spaces_veritas" -version = "0.0.7" -edition = "2021" +version.workspace = true +edition.workspace = true [lib] crate-type = ["cdylib", "rlib"] diff --git a/veritas/src/lib.rs b/veritas/src/lib.rs index 221a6f3..f530923 100644 --- a/veritas/src/lib.rs +++ b/veritas/src/lib.rs @@ -103,7 +103,7 @@ impl Veritas { } impl Proof { - pub fn iter(&self) -> ProofIter { + pub fn iter(&self) -> ProofIter<'_> { ProofIter { inner: self.inner.iter(), } diff --git a/wallet/Cargo.toml b/wallet/Cargo.toml index d1ff2b8..1854f52 100644 --- a/wallet/Cargo.toml +++ b/wallet/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "spaces_wallet" -version = "0.0.8" -edition = "2021" +version.workspace = true +edition.workspace = true [dependencies] spaces_protocol = { path = "../protocol", features = ["std"], version = "*" } diff --git a/wallet/src/builder.rs b/wallet/src/builder.rs index 5f94516..f41a3e0 100644 --- a/wallet/src/builder.rs +++ b/wallet/src/builder.rs @@ -405,7 +405,6 @@ impl Builder { if !coin_transfers.is_empty() { for coin in coin_transfers { builder.add_send(coin)?; - vout += 1; } } @@ -720,7 +719,7 @@ impl Builder { wallet: &mut SpacesWallet, unspendables: Vec, confirmed_only: bool, - ) -> anyhow::Result { + ) -> anyhow::Result> { let fee_rate = self .fee_rate .as_ref() diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index 82ea6b2..0ebf947 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -256,7 +256,7 @@ impl SpacesWallet { }) } - pub fn get_tx(&mut self, txid: Txid) -> Option { + pub fn get_tx(&mut self, txid: Txid) -> Option> { self.internal.get_tx(txid) } @@ -281,7 +281,7 @@ impl SpacesWallet { }) } - pub fn transactions(&self) -> impl Iterator + '_ { + pub fn transactions(&self) -> impl Iterator> + '_ { self.internal .transactions() .filter(|tx| !is_revert_tx(tx) && self.internal.spk_index().is_tx_relevant(&tx.tx_node)) @@ -299,7 +299,7 @@ impl SpacesWallet { &mut self, unspendables: Vec, confirmed_only: bool, - ) -> anyhow::Result> { + ) -> anyhow::Result> { self.create_builder(unspendables, None, confirmed_only) } @@ -530,7 +530,7 @@ impl SpacesWallet { /// /// This is used to monitor bid txs in the mempool /// to check if they have been replaced. - pub fn unconfirmed_bids(&mut self) -> anyhow::Result> { + pub fn unconfirmed_bids(&mut self) -> anyhow::Result, OutPoint)>> { let txids: Vec<_> = { let unconfirmed: Vec<_> = self .transactions() From 789f78c1996ab62631b10bea66c581022fef0bed Mon Sep 17 00:00:00 2001 From: Alex Tsokurov Date: Thu, 18 Dec 2025 20:16:36 +0100 Subject: [PATCH 10/10] Fix listspaces performance --- client/src/wallets.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/client/src/wallets.rs b/client/src/wallets.rs index fda04a4..e17391c 100644 --- a/client/src/wallets.rs +++ b/client/src/wallets.rs @@ -820,12 +820,6 @@ impl RpcWallet { let mut pending = vec![]; let mut outbid = vec![]; for (txid, event) in recent_events { - let tx = wallet.get_tx(txid); - if tx.as_ref().is_some_and(|tx| !tx.chain_position.is_confirmed()) { - pending.push(SLabel::from_str(event.space.as_ref().unwrap()).expect("valid space name")); - continue; - } - if unspent.iter().any(|out| { out.space .as_ref() @@ -833,6 +827,13 @@ impl RpcWallet { }) { continue; } + + let tx = wallet.get_tx(txid); + if tx.as_ref().is_some_and(|tx| !tx.chain_position.is_confirmed()) { + pending.push(SLabel::from_str(event.space.as_ref().unwrap()).expect("valid space name")); + continue; + } + let name = SLabel::from_str(event.space.as_ref().unwrap()).expect("valid space name"); let spacehash = SpaceKey::from(Sha256::hash(name.as_ref())); let space = state.get_space_info(&spacehash)?;