Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ struct StorageExplorerView: View {
modelRow("TXOs", icon: "bitcoinsign.circle", type: PersistentTxo.self) {
TxoStorageListView(network: network)
}
modelRow("Locked Outpoints", icon: "lock", type: PersistentLockedOutpoint.self) {
LockedOutpointStorageListView(network: network)
}
modelRow("Pending Inputs", icon: "hourglass", type: PersistentPendingInput.self) {
PendingInputStorageListView(network: network)
}
Expand Down Expand Up @@ -296,6 +299,7 @@ struct StorageExplorerView: View {
directCount(PersistentTokenBalance.self, predicate: #Predicate { $0.networkRaw == raw })
directCount(PersistentPlatformAddressesSyncState.self, predicate: #Predicate { $0.networkRaw == raw })
directCount(PersistentWallet.self, predicate: #Predicate { $0.networkRaw == raw })
directCount(PersistentLockedOutpoint.self, predicate: #Predicate { $0.networkRaw == raw })
directCount(PersistentWalletManagerMetadata.self, predicate: #Predicate { $0.networkRaw == raw })

// Models that derive their network through a relationship —
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1757,6 +1757,42 @@ struct TxoStorageListView: View {
}
}

// MARK: - PersistentLockedOutpoint

/// Locks can exist before their TXO or wallet row, so scope them by their
/// own network column rather than requiring either relationship to exist.
struct LockedOutpointStorageListView: View {
let network: Network
@Query private var records: [PersistentLockedOutpoint]

private var scopedRecords: [PersistentLockedOutpoint] {
records.filter { $0.networkRaw == network.rawValue }
}

var body: some View {
let visible = scopedRecords
List(visible) { record in
NavigationLink(destination: LockedOutpointStorageDetailView(record: record)) {
VStack(alignment: .leading, spacing: 4) {
Text(record.outpoint.map { String(format: "%02x", $0) }.joined())
.font(.system(.caption, design: .monospaced))
.lineLimit(1).truncationMode(.middle)
Text("Wallet: \(record.walletId.map { String(format: "%02x", $0) }.joined())")
.font(.system(.caption2, design: .monospaced))
.foregroundColor(.secondary)
.lineLimit(1).truncationMode(.middle)
}
}
}
.navigationTitle("Locked Outpoints (\(visible.count))")
.overlay {
if visible.isEmpty {
ContentUnavailableView("No Locked Outpoints", systemImage: "lock")
}
}
}
}

// MARK: - PersistentPendingInput

/// Diagnostic list of every `PersistentPendingInput` row — one per
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2180,6 +2180,29 @@ struct TxoStorageDetailView: View {
}
}

// MARK: - PersistentLockedOutpoint

struct LockedOutpointStorageDetailView: View {
let record: PersistentLockedOutpoint

var body: some View {
Form {
Section("Identity") {
FieldRow(label: "Network", value: Network(rawValue: record.networkRaw)?.displayName ?? "raw \(record.networkRaw)")
FieldRow(label: "Wallet ID", value: hexString(record.walletId))
FieldRow(label: "Outpoint (wire)", value: hexString(record.outpoint))
}
Section {
Text("This output is excluded from coin selection, either as masternode collateral or because it was locked manually. The lock can remain even when its transaction output is not stored locally.")
.font(.caption2)
.foregroundColor(.secondary)
}
}
.navigationTitle("Locked Outpoint")
.navigationBarTitleDisplayMode(.inline)
}
}

// MARK: - PersistentPendingInput

struct PendingInputStorageDetailView: View {
Expand Down
Loading