Files
client/app-stacks

Zapstore App Stacks — Privacy Review

A systematic privacy and security review of apps in the Zapstore catalog. Each app is cloned from its source repository, scanned for tracking SDKs, permissions, and privacy practices, then assigned a verdict. Approved apps are organized into curated stacks for publication to the Zapstore relay.

Project Structure

.
├── README.md              # This file
├── .gitignore
├── plans/                 # Planning documents and methodology
│   ├── app-review-methodology.md
│   ├── proposed-categories.md
│   └── review-todo.md
├── scripts/               # Python scripts for review and publishing
│   ├── review_apps.py     # Main review script (SSH-based)
│   ├── generate_stacks.py # Map apps to categories, generate stack events
│   ├── publish_stack.py   # Sign and publish stacks to relay
│   └── ...
├── data/                  # Review results and app data (JSON)
│   ├── review_results_final.json  # All 280 apps with verdicts
│   ├── apps_data.json             # Zapstore catalog data
│   └── ...
├── reports/               # Human-readable reports (Markdown)
│   ├── review_report_by_category.md  # Full category-by-category report
│   ├── final_report.md               # Top 2 apps per category
│   └── ...
└── stacks/                # Generated Nostr stack events (kind 30267)
    ├── all_stacks.json    # All 20 stacks in one file
    └── ...

Review Results

Verdict Count Meaning
APPROVED 175 No tracking SDKs, minimal/justified permissions, open source
⚠️ FLAGGED 36 Contains tracking SDKs or excessive permissions
⏭️ SKIPPED 41 Could not clone repository (no mirror, no GitHub URL)
UNCLEAR 28 Needs human investigation (app not in catalog, auth required)

20 Curated App Stacks

These stacks are ready to publish to the Zapstore relay as kind-30267 events.

1. Bitcoin & Lightning Wallets

Self-custodial Bitcoin and Lightning wallet apps.

  • ZEUS, Nunchuk, Cake Wallet, Alby Go, Blitz Wallet, BlueWallet, Electrum, Oubli, MercaSats, Lightning Reaction

2. Nostr Clients

Nostr-native social and communication clients.

  • Amethyst, Amber, Wisp, Dark Wisp, White Noise, Nospeak, Nostrord, Shosho, TravelTelly, Nmail, Divine, YakiHonne, Nests, Nostria, Zapstore Alpha, PearCal, PearCircle, Ditto, Flotilla

3. Secure Messaging

End-to-end encrypted messaging and email apps.

  • SimpleX, Conversations, Delta Chat, aTalk, Element, Element X, Thunderbird, FairEmail, Tuta, Quiet, SpamBlocker, Deku SMS

4. VPN & Privacy Tools

VPN clients, firewalls, and network privacy tools.

  • Orbot, Mullvad VPN, Tailscale, AmneziaVPN, Proton VPN, Rethink, PCAPdroid, WG Tunnel, ByeDPI, NeoStumbler, SD Maid, InviZible Pro, Private DNS Quick Setting

5. Password Managers & Auth

Password managers, 2FA authenticators, and identity tools.

  • Bitwarden, KeePassDX, Aegis, Authnkey, Ente Auth, Keep, AliasVault, PassVault, LibreFind

6. Maps & Navigation

Offline maps, navigation, and location tools.

  • Organic Maps, OsmAnd~, StreetComplete, CoMaps, OwnTracks, OSMTracker

7. Media Players & Streaming

Video and music players, streaming clients.

  • VLC, NewPipe, PipePipe, Auxio, Musify, Metrolist, FreeTube, Zaptrax, Zappix, mpvEx, KurobaEx

8. Productivity & Notes

Note-taking, task management, and productivity tools.

  • Flux, Notesnook, Quillpad, Saber, DAVx⁵, Super Productivity, Trilium Notes, SilentNotes, Manent, Meiso, Florid, Plektos, Urn, Screen Time, Grit, Numo, timeto.me, Converter NOW

9. File Management & Cloud Sync

Cloud storage, file sync, and file management tools.

  • Nextcloud, Syncthing-Fork, Seafile, File transfer, primitive ftpd, Paperless Mobile, GitSync, wormhole, SFTP Documents Provider, OSS Document Scanner

10. Browsers

Privacy-focused web browsers.

  • DuckDuckGo, Cromite

11. Social Media

Federated and alternative social media clients.

  • Mastodon, Nekogram, Infinity+, NewsBlur, Claw, Polymarket Viewer

12. Finance & Budgeting

Personal finance, expense tracking, and budgeting.

  • Flow, Pennywise AI Tracker, Dev Stocks Widget, Seeker, PearGuard, Mostro, Shopt

13. Health & Fitness

Health tracking, diet, and fitness apps.

  • Daily Dozen, Screen Time, Astronia

14. Education & Reference

Learning, dictionary, and reference tools.

  • freeCodeCamp, freeDictionary, Ciyue, Keyman, NeverTooManyBooks, Calibre Web Companion, Repertoire, ListenBrainz, CPU Info, microMathematics Plus, Mental Math

15. Photography & Image Tools

Camera, photo editing, scanning, and gallery apps.

  • Image Toolbox, FairScan, PhotoPrism, PicGuard, Gallery apps, YTDLnis, ElCaju, Espy, PDF Wallet

16. Utilities & Tools

System utilities, converters, and general-purpose tools.

  • Binary Eye, CPU Info, Converter NOW, Catima, BT Remote, Lawnicons, Peristyle, BinEd, MMRL, Canta, Amarok, ServerBox, wX, Mako, Rush, HeliBoard, DeskClock, Redomi, Scrobble, Feeder, SMS2Email, Inure, Unciv

17. Games

Open source games across genres.

  • Shattered Pixel Dungeon, Wesnoth, Feudal Tactics, Burger Party, ChipDefense, Roboyard, Breakout 71, Damas Clash, Unciv

18. Communication (Non-Nostr)

Voice/video calls, remote desktop, and messaging.

  • Telegram, RustDesk, Sideband, Meshtastic

19. Development Tools

Code editors, Git clients, and developer tools.

  • Acode, GitSync, BinEd, freeCodeCamp, GitHub Store, Kai 9000

20. Calendar & Scheduling

Calendar apps, scheduling, and time management.

  • Calendar by Form*, PearCal, timeto.me, Sidestep

Review Methodology

Each app is reviewed using a structured process:

  1. Clone from local Gitea mirror (or GitHub fallback)
  2. Scan AndroidManifest.xml for requested permissions
  3. Check build.gradle* for actual dependency declarations (distinguishing implementation vs playImplementation vs compileOnly)
  4. Verify API calls — search for actual SDK method invocations (not just dependency names)
  5. Check manifest metadata that disables analytics
  6. Check build flavors (Google Play vs F-Droid)
  7. Determine verdict: APPROVED or ⚠️ FLAGGED

See plans/app-review-methodology.md for full details.

Publishing

Stack events (kind 30267) are published to wss://relay.zapstore.dev using the publish_stack.py script, which signs via qrexec (Qubes OS nostr_signer).

Nostr Kinds Reference

The following Nostr event kinds are relevant to this project:

Kind Name Usage Status
32267 Software Application The app listing event published by developers. Identified by d tag (Android package name) and publisher pubkey. Referenced in stacks via a tags as 32267:<pubkey>:<identifier>. Core data source
30267 App curation set Curated collections of apps (stacks). We publish privacy-approved stacks as kind 30267 events with a tags referencing each approved app. Used for output
30078 App-specific data Generic parameterized replaceable event. Already used by Zapstore for device state, bookmarks, etc. Candidate for storing per-app review results from LLM agents. Planned for reviews
3063 Software Asset APK metadata including hash, size, version code, platform. Used to track current version info for reviewed apps. Used for version tracking
30063 Release artifact set Group of artifacts for a software release. Links to kind 3063 assets and kind 32267 app events. Reference
1986 Relay reviews Existing review kind, but scoped to Nostr relays rather than software apps. Not applicable

See references/registry-of-kinds/schema.yaml for the full kinds registry and references/nips/51.md for list/set definitions.

Kind 30078 Event Data Model

We use kind 30078 (App-specific data) events for two purposes: app definitions and app reviews. The frontend queries the Nostr relay directly for these events on page load, rather than reading a static file.

App Definition Events

Each app in the catalog is defined by a kind 30078 event with #t: app-definition. These are published when an app is added via the PHP backend.

{
  "kind": 30078,
  "content": "{\"name\":\"Amethyst\",\"identifier\":\"com.vitorpamplona.amethyst\",\"repository\":\"https://github.com/vitorpamplona/amethyst\",\"description\":\"...\"}",
  "tags": [
    ["d", "app-com.vitorpamplona.amethyst"],
    ["t", "app-definition"],
    ["t", "nostr-clients"],           // ← category tag
    ["name", "Amethyst"],
    ["repository", "https://github.com/vitorpamplona/amethyst"],
    ["gitea", "com.vitorpamplona.amethyst"],
    ["url", "https://cdn.zapstore.dev/..."],
    ["f", "android-arm64-v8a"],
    ["published_at", "1729302793"]
  ]
}

App Review Events

Each model's review of an app is stored as a kind 30078 event with #t: app-review. The review is pinned to a specific version via SHA256 hash.

{
  "kind": 30078,
  "content": "{\"verdict\":\"APPROVED\",\"level\":1,\"summary\":\"...\",\"findings\":{...}}",
  "tags": [
    // Unique ID: model + app identifier + version
    ["d", "review-deepseek/deepseek-v4-flash-com.vitorpamplona.amethyst-v1.2.3"],

    // Reference to the app definition event
    ["a", "30078:<pubkey>:app-com.vitorpamplona.amethyst", "wss://relay.zapstore.dev"],

    // The SPECIFIC asset/APK that was reviewed (kind 3063 event)
    ["e", "<kind_3063_event_id>", "wss://relay.zapstore.dev"],

    // Version info for querying
    ["version", "1.2.3"],
    ["version_code", "1234"],

    // SHA256 hash of the reviewed APK — cryptographic pin
    ["x", "a1b2c3d4e5f6..."],

    // Review metadata
    ["model", "deepseek/deepseek-v4-flash"],
    ["model_name", "DeepSeek Flash 4"],
    ["verdict", "APPROVED"],
    ["level", "1"],
    ["p", "<agent_pubkey>"],
    ["t", "app-review"]
  ]
}

Tag Reference

Tag Event Type Purpose
d Both Unique identifier (app-{identifier} or review-{model}-{identifier}-v{version})
t Both app-definition or app-review — also carries category for app definitions
name App definition Human-readable app name
repository App definition Source code URL
gitea App definition Gitea mirror identifier
url App definition APK download URL
f App definition Platform (e.g. android-arm64-v8a)
a → kind 30078 App review Reference to the app definition event
e → kind 3063 App review The specific APK asset that was reviewed
x App review SHA256 hash — cryptographic pin of the reviewed binary
version / version_code App review Version info
model App review LLM model string (e.g. deepseek/deepseek-v4-flash)
verdict App review Review verdict
level App review Privacy level (1-4)
p App review Agent pubkey who performed the review

Page Load Flow

Page opens
  → Queries relay for kind 30078, #t: app-definition
  → Groups apps by #t category tags → builds categories
  → Queries relay for kind 30078, #t: app-review
  → Matches reviews to apps via a tags
  → Renders categories + apps + per-model review status

Version Pinning Flow

App v1.2.3 defined (kind 30078, #t: app-definition)
  └── APK asset (kind 3063, SHA256: abc...)
        └── Review (kind 30078, #t: app-review, pinned via x tag)

App v1.2.4 published (kind 3063, SHA256: def...)
  └── NEW review needed — old review's SHA256 doesn't match

If a bad actor modifies the app in v1.2.4, the review for v1.2.3 (with its SHA256 abc...) does not carry over. A new review must be performed on the new binary.