Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
31387c8
feat: add federation gateway monitoring and API
bansalayush247 Mar 14, 2026
a5199c9
fix: resolve CI lint and clippy failures
bansalayush247 Mar 14, 2026
be43300
feat(api): add endpoints for fetching federation gateways
bansalayush247 Mar 28, 2026
e49d772
feat: implement GatewayWarningPage component for enhanced gateway sta…
bansalayush247 Apr 20, 2026
d55ac09
fix: adapt gateways to current master
bansalayush247 Sep 4, 2026
b7b922c
feat: integrate guardian software versions into master
bansalayush247 Sep 6, 2026
8491488
feat: compare federation UTXOs with guardian wallet claims
bansalayush247 Jun 27, 2026
a71e4c2
chore: update nixpkgs flake input
bansalayush247 Jun 27, 2026
8fc7392
feat: enhance guardian UTXO claims with on-chain resolution details
bansalayush247 Jul 2, 2026
5aa71a4
fix: update transaction query to use LEFT JOIN for improved data retr…
bansalayush247 Jul 27, 2026
19f4cd1
nix fix
bansalayush247 Sep 11, 2026
0cfb1e8
Refactor wallet UTXO handling and reconciliation
bansalayush247 Sep 12, 2026
ed2cd32
feat(utxos): compare guardian wallet claims
bansalayush247 Sep 12, 2026
4b94d38
feat(utxos): merge upstream master
bansalayush247 Sep 12, 2026
41159ce
Merge remote-tracking branch 'origin/master' into feature/federation-…
bansalayush247 Sep 16, 2026
e54f548
Refactor UTXO handling and add Bitcoin verification caching
bansalayush247 Sep 19, 2026
f0eab01
Update dependencies and refactor UTXO handling
bansalayush247 Sep 23, 2026
e3afba5
Merge branch 'master' into feature/federation-utxo-claims
bansalayush247 Sep 23, 2026
26e146f
delete: remove wallet_recipient.sql as it is no longer needed
bansalayush247 Oct 5, 2026
3c88e89
feat: enhance UTXO management and guardian claims handling
bansalayush247 Oct 5, 2026
146b04e
Refactor UTXO handling and on-chain verification
bansalayush247 Oct 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ fedimint_observer.db
.direnv
.pg_dev
/db_backups
.pg_dev17
/delete_old_cluster.sh
110 changes: 110 additions & 0 deletions fmo_api_types/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::BTreeMap;

use bitcoin::address::NetworkUnchecked;
use chrono::{DateTime, Utc};
use fedimint_core::config::FederationId;
Expand Down Expand Up @@ -41,6 +43,114 @@ pub struct FederationUtxo {
pub amount: Amount,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FederationUtxosResponse {
/// How many guardians must agree before an output counts as held or not
/// held: `n - f`, the same threshold the federation itself acts on
pub threshold: usize,
pub guardians: Vec<GuardianUtxoReport>,
/// One row per output, most severe status first, then largest amount first
pub utxos: Vec<UtxoComparisonRow>,
}

/// How a guardian took part in the comparison
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GuardianUtxoReport {
pub guardian_id: u16,
pub status: GuardianUtxoClaimStatus,
/// Session count the guardian reported alongside its wallet summary
pub session_count: Option<u64>,
pub error: Option<String>,
/// Outputs a threshold of guardians agrees the federation holds, but this
/// guardian does not list
pub missing_outputs: u32,
/// Outputs this guardian lists, but a threshold of guardians agrees the
/// federation does not hold
pub extra_outputs: u32,
/// Outputs this guardian lists with another amount than a threshold of
/// guardians agrees on
pub wrong_amounts: u32,
}

/// An output as seen by the observer, the guardians and, where needed, the
/// blockchain
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UtxoComparisonRow {
pub out_point: bitcoin::OutPoint,
pub amount: Amount,
/// Only known for outputs in the observer's history
pub address: Option<bitcoin::Address<NetworkUnchecked>>,
/// State each guardian that took part in the comparison lists the output in
pub guardian_states: BTreeMap<u16, GuardianClaimedUtxoState>,
pub status: UtxoComparisonStatus,
pub disagreement: Option<GuardianUtxoDisagreementKind>,
pub detail: Option<String>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum UtxoComparisonStatus {
Mismatch,
/// Not confirmed yet: in flight, observer lag, or no guardian responded
Pending,
Verified,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GuardianUtxoClaim {
pub guardian_id: u16,
pub status: GuardianUtxoClaimStatus,
/// Session count the guardian reported alongside its wallet summary
pub session_count: Option<u64>,
pub utxos: Vec<GuardianClaimedUtxo>,
pub error: Option<String>,
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum GuardianUtxoClaimStatus {
Unavailable,
Ok,
/// Answered, but behind the federation's session count, so its wallet
/// summary is stale and left out of the comparison
Lagging,
Error,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GuardianClaimedUtxo {
pub out_point: bitcoin::OutPoint,
pub amount: Amount,
pub state: GuardianClaimedUtxoState,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum GuardianClaimedUtxoState {
Spendable,
UnsignedPegOut,
UnsignedChange,
UnconfirmedPegOut,
UnconfirmedChange,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum GuardianUtxoDisagreementKind {
/// The observer's amount differs from the one a threshold of guardians
/// agrees on, or guardians cannot agree on an amount
EvidenceMismatch,
/// Guardians cannot reach a threshold on whether the federation holds the
/// output, or only a minority lists an output the rest agree is not held
InventoryDifference,
/// A threshold of guardians agrees, but the observer's history differs,
/// usually because it lags behind consensus or a peg-out is still pending
ObserverDifference,
/// The blockchain contradicts what the observer or guardians report: the
/// output is already spent, does not exist, or holds a different amount
OnChainConflict,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GuardianHealth {
pub avg_uptime: f32,
Expand Down
Loading
Loading