> For the complete documentation index, see [llms.txt](https://argon-4.gitbook.io/argon-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://argon-4.gitbook.io/argon-docs/suresign/deal-desk-protocol.md).

# Deal Desk protocol

How the Deal Desk works underneath: the Kasia messaging protocol, the Desk identity, sealed cards, verification against the covenant, and what the kernel refuses.

The Deal Desk is the room where more than one person finishes a money arrangement: an escrow, an inheritance vault, later a multisig. Underneath it is a small protocol layered on Kaspa transactions and owned entirely by SureSign. This page describes it for readers who want to know exactly what is sent, sealed, verified, and refused. For how to use it, see [Using Enclave → Deal Desk](/argon-docs/using-enclave/deal-desk.md).

## Transport: Kasia

Messages travel inside Kaspa transactions using the **Kasia** protocol, an open encrypted-messaging convention on Kaspa. A message is a payment (0.2 KAS) to the recipient's address whose payload is `ciph_msg:1:` followed by a sealed envelope. SureSign writes the Kasia root and reads both `ciph_msg:1:` (Kasia) and `kchat:1:` (KaChat), so an Enclave user can converse with users of those wallets as well as other Enclave users.

The reference cipher is reimplemented in the kernel with fail-closed parsing and verified against fixtures produced by the upstream crate (K-Kluster Kasia, commit `acd3cf65`):

| Step           | Construction                                                              |
| -------------- | ------------------------------------------------------------------------- |
| Recipient key  | The x-only public key in the recipient's Kaspa address                    |
| Ephemeral key  | Fresh secp256k1 key per message                                           |
| Shared secret  | ECDH, x-coordinate only                                                   |
| Key derivation | HKDF-SHA256, no salt, empty info, 32 bytes                                |
| Encryption     | ChaCha20-Poly1305 (IETF, 12-byte nonce), no additional data               |
| Envelope       | `nonce ‖ ephemeral public key (33 bytes) ‖ ciphertext ‖ tag`, hex-encoded |

Only the recipient's key can open a message. The fact that two addresses exchanged transactions is public, like every Kaspa transaction; the contents are not. Group traffic is recognized and refused; Enclave fans a room out as one sealed copy per party.

## Identity: the Desk address

Each account has one Desk address at `m/44'/111111'/{account}'/3/0`, a Schnorr key that is both the messaging identity and the wallet's **covenant role key**. When you create an escrow or a vault, your role defaults to your Desk key; when you receive a deal card, the kernel looks for your Desk key among the program's roles to know which moves are yours. One key, one identity, no separate registration.

## The float

Desk messages spend from a separate pool of coins, the **float**, funded from the wallet with **Fund the Desk** (later **Add float**). Desk lanes spend only Desk coins and return change only to the Desk, so messaging never touches the Notes behind your balance, and the float is excluded from Available. **Move to wallet** returns Desk coins to the account's next change address, derived by the kernel.

## Messages

| Kind          | Wire form                                                               | Purpose                                                                                                                                                                                |
| ------------- | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Handshake** | `ciph_msg:1:handshake:` + sealed alias and public key                   | Introduces two Desks. A stranger's handshake becomes a *request*; accepting sends the reciprocal handshake. Refused to an already-connected contact and rate-limited to a pending one. |
| **Comm**      | `ciph_msg:1:comm:<alias>:<base64>`                                      | A sealed message. Plain text, or a **deal card**.                                                                                                                                      |
| **Deal card** | `enclave.deal.v1` JSON inside a comm: `{type, dealId, seq, kind, body}` | `invite` (the deal's terms), `note`, `status` (what a wallet just broadcast), `action` (a request for a party to take a path). Anything else is inert text.                            |

Every message is a SureSign plan with a review. A room post is a package: one review, one authorization, and the sealed bytes fixed at plan time so the review hash binds exactly what is broadcast. If a recipient does not yet hold the room's deal card, the kernel sends the card as its own sealed copy ahead of the message, so a request never arrives without the deal it refers to.

## Verification: the card is not the truth, the chain is

A deal card claims a program: a template, constructor parameters, and the lock address they produce. The receiving kernel **re-derives the lock** from the template and parameters on the current network and accepts the card only if the claimed address equals the recomputed one. A card that fails demotes to plain text with a warning. Status and action cards are likewise checked against the room they claim (template family, lock, role, transaction id shape) and rewritten in the kernel's own words.

A card is never a button. The most an incoming card can do is open the Escrow or Vaults page, where any move is its own ReviewPlan derived from the chain, not from the message. A string that looks like an identifier never becomes a spend.

## Stage: where the deal stands

The room's headline (*Your move*, *Waiting on the seller*, *Settled*) is derived by the kernel from the chain: the live balance at each lock the deal can move through, the network's DAA score, and the wallet's own journal of what it broadcast. Status cards from other parties are history, not authority. The stage yields the ordered steps of the deal's path, each marked done, open now, opening at a DAA the card names, or later, together with which role owns it and whether it is optional. Every open step of yours is a button that plans a fresh covenant spend; nothing in the room signs.

## Ordering and holding

Incoming records are replayed in chain order (accepted before mempool, then by block time), not arrival order. A message from a party with no completed handshake, or for a room that has not opened yet, is **held** and retried until its prerequisite arrives, so a card that lands before its handshake survives and a stranger cannot open a room or fill a thread by asking. Blocked senders are dropped at ingest.

## State and privacy

Contacts, aliases, rooms, decrypted events, and held records live in a state blob sealed under a key derived from the vault and persisted only as ciphertext; it is cleared from memory on lock. Each open surface (popup, sidebar, Studio) holds its own kernel and merges state written by the others rather than overwriting it, so two open windows converge instead of losing an invitation.

The background worker watches the Desk address and every contact's address on the node and stores only public records (transaction id, payload hex, sender). It never decrypts; the kernel decides what a record means.

## What is refused

* Handshakes to connected contacts, and repeat handshakes inside the resend window.
* Group messages and unknown message kinds (decoded as opaque text at most).
* Deal cards whose lock does not re-derive from their stated terms.
* Any move whose leg has no live Note, whose constructor is unknown, or whose role key is not this wallet's.
* Any attempt to turn message content into a transaction without a ReviewPlan.
