Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/covenant-gov/pacto-app/llms.txt

Use this file to discover all available pages before exploring further.

Pacto is a Tauri v2 desktop application that combines a SvelteKit/Svelte static SPA frontend with a Rust backend crate. The two halves communicate through Tauri’s typed invoke/event bridge. The Rust backend owns all cryptographic operations — Nostr key handling, MLS group state, EVM signing — while the frontend manages UI rendering, Svelte stores, and read-plane EVM queries via viem. Outbound traffic flows to two distinct external networks: Nostr relays for messaging and EVM/Aztec RPCs for on-chain governance.

System overview

Layer responsibilities

LayerRoleKey files
FrontendUI, state, user flowssrc/routes/+page.svelte, src/stores/, src/components/, src/lib/
Tauri bridgeTyped frontend ⇄ backend RPC and eventssrc-tauri/src/lib.rs (invoke_handler + AppHandle::emit)
Rust backendCrypto, Nostr/MLS relay logic, EVM signing, SQLite, mediasrc-tauri/src/lib.rs, src-tauri/src/{nostr,mls,chat,message,rumor,db,account_manager,evm}/
NetworkNostr relays for messaging; RPCs for chain reads and sendsTRUSTED_RELAYS, ALCHEMY_RPC_KEY, user RPC prefs

Data flows

1. Messaging flow

Nostr events travel in two parallel paths depending on the conversation type. Direct messages use NIP-59 Gift Wraps (kind 1059) and inner rumor kinds such as 14 (text), 15 (file), 7 (reaction), and 30078 (typing). MLS group messages travel as kind 444 on the wire, while MLS welcome invites arrive wrapped inside a Gift Wrap as kind 443. Both paths ultimately land in the same unified Chat / Message model in SQLite.

2. EVM wallet flow

Key derivation, reads, and writes are split across layers intentionally. The same BIP-39 seed derives both Nostr keys and EVM addresses. Reads such as balances, contract observation, and receipt polling happen in the frontend via viem. Writes — WalletBar sends, treasury deployments, and governance transactions — happen in Rust using Alloy. Signer purpose also matters: squad keys can act on treasury and governance, while advanced keys are restricted to the Advanced panel.

3. Storage flow

Each Nostr account is fully isolated under its own npub directory. The app SQLite database (vector.db) holds chat metadata, events, profiles, and squad infrastructure pointers. The MLS engine database (vector-mls.db) is owned by the MDK engine and stores cryptographic group state. Frontend per-account state is scoped via localStorage keys built with persistenceKey(prefix).

Key directories

DirectoryPurpose
src/Svelte frontend source
src/routes/Single-page static SPA shell
src/stores/Svelte writable/derived stores
src/lib/Typed Tauri wrappers, domain logic, helpers
src/components/Svelte UI components grouped by domain
src-tauri/src/Rust backend crate
src-tauri/src/evm/Wallet, key derivation, RPC, contract bindings, governance
src-tauri/src/evm/contracts/alloy::sol! bindings for pacto-gov, sponsor, Safe, ERC-20, Hats
static/Static assets (twemoji SVGs, etc.)
docs/Authoritative tracked architecture and operational docs
.cursor/rules/Editor-enforced project policies
.github/workflows/Cross-platform release CI

Security and trust model

Pacto requires no KYC; all identity is cryptographic, expressed as an npub/nsec keypair. The EVM private key is decrypted in Rust only for approved signing operations and is never exposed to the frontend. Message content and secrets are stored encrypted at rest in SQLite; profile data and indexing metadata remain plaintext so they can be searched and indexed efficiently. A PIN-derived ENCRYPTION_KEY (Argon2) is used to encrypt the events.content column — if the key is missing or wrong, the UI displays [Decryption failed] rather than failing silently. There is no independent third-party security audit yet; see docs/audits/README.md.

Cross-cutting conventions

  • Greenfield: No public alpha has shipped yet. Prefer clean, minimal paths over legacy-compatibility shims.
  • Brief inline comments: Source comments should explain behavior, not architecture. Point to docs/ for structural explanations.
  • No tracker IDs, spec section markers, or checklist breadcrumbs in source files.
  • Public protocol addresses belong in the tracked JSON file src/lib/evm/pacto-protocol-addresses.json, not .env.

Explore further

Nostr Transport

How Pacto uses kinds 1059, 443, and 444 for DMs and MLS group messaging.

MLS Engine

MDK engine integration, storage layers, threading model, and eviction handling.

Storage

Per-npub SQLite isolation, schema, message encryption, and logout behavior.

Direct Messages

DM architecture, Gift Wrap flow, and NIP-59 rumor kinds.

Build docs developers (and LLMs) love