# How to Trigger the Emergency Wipe Feature in BitChat

> Learn how to trigger BitChat's emergency wipe feature to instantly erase all local data keys and identity. Discover the triple-tap logo method or panic wipe button in settings.

- Repository: [permissionlesstech/bitchat](https://github.com/permissionlesstech/bitchat)
- Tags: how-to-guide
- Published: 2026-08-08

---

**BitChat's emergency wipe (panic wipe) can be triggered either by triple-tapping the "bitchat/" logo in the app header or by tapping the panic wipe button in Settings, both of which invoke `AppChromeModel.panicClearAllData()` to permanently erase all local data, keys, and identity.**

BitChat is a privacy-focused messaging application developed by the open-source **permissionlesstech/bitchat** repository. The **emergency wipe feature** provides an instantaneous method to destroy all local cryptographic material, conversation history, and identity metadata. This mechanism ensures users can purge sensitive data immediately when facing device compromise or seizure scenarios.

## Two Ways to Trigger the Emergency Wipe

BitChat offers dual entry points to accommodate both stealth and explicit access patterns.

### Triple-Tap the Logo (Hidden Gesture)

The primary stealth trigger resides in [`bitchat/Views/ContentHeaderView.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Views/ContentHeaderView.swift) (lines 53-55). The logo Text view registers a triple-tap gesture that immediately delegates to the panic wipe system.

```swift
// Inside ContentHeaderView.swift
Text(verbatim: "bitchat/")
    .onTapGesture(count: 3) {
        // Triple‑tap initiates the panic wipe
        appChromeModel.panicClearAllData()
    }

```

This **hidden gesture** allows users to initiate a wipe discreetly without navigating through menus, which is critical during high-risk scenarios where screen visibility may be compromised.

### Panic Wipe Button in Settings

For users who prefer explicit controls, [`AppInfoView.swift`](https://github.com/permissionlesstech/bitchat/blob/main/AppInfoView.swift) exposes a destructive button labeled "panic wipe" within the Settings screen. This button invokes `appChromeModel.panicClearAllData()`, guaranteeing identical behavior to the triple-tap method while providing a discoverable, traditional UI element.

## The Execution Chain: From UI to Data Destruction

When either trigger activates, the wipe request flows through a strict delegation hierarchy to ensure proper cleanup sequencing.

### AppChromeModel Bridge Layer

In [`bitchat/App/AppChromeModel.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/App/AppChromeModel.swift) (lines 14-18), the `panicClearAllData()` method serves as the bridge between UI actions and the underlying data layer. This method executes three critical steps:

1. **Optional pre-wipe preparation** via a `prepareForPanic` closure set by the UI
2. **UI-level hook execution** through `onPanicWipe()` to clear share-extension data
3. **Delegation to the view-model** via `chatViewModel.panicClearAllData()`

### ChatViewModel Implementation

The actual erasure logic lives in [`bitchat/ViewModels/ChatViewModel.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/ViewModels/ChatViewModel.swift) (lines 48-55) within the `panicClearAllData(restartServices: Bool = true)` method. Marked with `@MainActor` and `@discardableResult`, this method performs surgical cleanup:

```swift
// Inside ChatViewModel.swift
@MainActor
@discardableResult
func panicClearAllData(restartServices: Bool = true) -> Bool {
    panicRecoveryBlocked = true
    isPanicResetting = true
    defer { isPanicResetting = false }

    // Stop services before any data is removed
    panicNetworkLifecycle.stop()

    // Begin a durable recovery intent
    let recoveryIntent = panicRecoveryOperations.begin()

    // Suspend mesh transport, reset media pipelines, etc.
    if let panicTransport = meshService as? PanicResettingTransport {
        panicTransport.suspendForPanicReset()
    } else {
        meshService.emergencyDisconnectAll()
    }

    // … (many cleanup steps – see full source for details) …

    // Optionally restart services after the wipe
    if restartServices {
        panicNetworkLifecycle.restart()
    }
    return true
}

```

The method stops network and location services immediately, begins a durable recovery intent, suspends the mesh transport, cancels media preparation, clears conversation stores, deletes all Keychain data, removes identity-related UserDefaults, wipes location state, resets nicknames, clears peer-identity stores, and removes Nostr-related state.

## Programmatic Triggering for Development

Developers can invoke the emergency wipe directly for testing purposes by accessing the `AppChromeModel` from any SwiftUI view:

```swift
import SwiftUI

struct DebugPanel: View {
    @EnvironmentObject private var appChromeModel: AppChromeModel

    var body: some View {
        Button("🚨 Emergency wipe") {
            // Explicitly trigger the wipe
            appChromeModel.panicClearAllData()
        }
        .foregroundColor(.red)
    }
}

```

This enables automated testing of recovery mechanisms and verification that the `panicRecoveryBlocked` and `isPanicResetting` flags properly prevent race conditions.

## Critical Implementation Safeguards

The wipe process includes multiple safety mechanisms to ensure reliable execution. The `panicRecoveryBlocked` and `isPanicResetting` boolean flags guard against concurrent wipe attempts while the operation proceeds. A `defer` block guarantees that `isPanicResetting` returns to `false` even if an error occurs during the wipe sequence, preventing the application from entering a permanently locked state.

## Key Source Files

- **[`bitchat/Views/ContentHeaderView.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Views/ContentHeaderView.swift)** – Hosts the triple-tap gesture recognizer on the logo
- **[`bitchat/Views/AppInfoView.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Views/AppInfoView.swift)** – Contains the explicit panic wipe button in Settings
- **[`bitchat/App/AppChromeModel.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/App/AppChromeModel.swift)** – Bridges UI actions to the view-model (lines 14-18)
- **[`bitchat/ViewModels/ChatViewModel.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/ViewModels/ChatViewModel.swift)** – Implements the comprehensive data erasure logic (lines 48-55)

## Summary

- **Triple-tap the "bitchat/" logo** to trigger a stealth emergency wipe via [`ContentHeaderView.swift`](https://github.com/permissionlesstech/bitchat/blob/main/ContentHeaderView.swift)
- **Use the Settings button** for explicit, discoverable activation through [`AppInfoView.swift`](https://github.com/permissionlesstech/bitchat/blob/main/AppInfoView.swift)
- **AppChromeModel** acts as the bridge, executing `prepareForPanic` and `onPanicWipe` hooks before delegating to the view-model
- **ChatViewModel.panicClearAllData()** performs the actual destruction, stopping services first, then clearing all cryptographic identity and conversation data
- **Race condition protection** is enforced via `panicRecoveryBlocked` and `isPanicResetting` flags within a `@MainActor` context

## Frequently Asked Questions

### What is the difference between the triple-tap and settings button triggers?

Both methods invoke identical wipe logic through `appChromeModel.panicClearAllData()`. The triple-tap gesture provides a stealth option for discreet activation during compromise scenarios, while the settings button offers a traditional, discoverable UI element. Both paths resolve to the same `ChatViewModel.panicClearAllData()` implementation.

### Does the emergency wipe delete data from the network or just locally?

The emergency wipe operates exclusively on local device data. It clears conversation stores, deletes Keychain entries, removes identity-related UserDefaults, and wipes peer-identity caches, but cannot retract messages already delivered to other users. However, destroying the local cryptographic keys effectively severs the identity, preventing decryption of future messages.

### Can developers trigger the emergency wipe programmatically for testing?

Yes, developers can invoke the wipe by calling `appChromeModel.panicClearAllData()` on any SwiftUI view that accesses the environment object. This enables testing of recovery flows and verification that the `restartServices` parameter properly controls whether network services restart after the wipe completes.

### What mechanisms prevent accidental triggering of the emergency wipe?

The triple-tap gesture requires exactly three consecutive taps on the specific logo text, significantly reducing accidental activation. Internally, `ChatViewModel` protects the wipe routine with `panicRecoveryBlocked` and `isPanicResetting` flags that prevent concurrent execution and race conditions. A `defer` block ensures `isPanicResetting` resets to false even if the wipe encounters errors.