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

# the lacuna protocol

*A deliberately small, auditable system.*

Underneath the simple experience are just three parts: your device, a set of smart contracts, and an optional relayer.

## System architecture

Your **device** holds the keys, builds notes, and generates proofs locally. The **smart contracts** — the shielded pool and an on-chain verifier — hold deposits, track commitments and nullifiers, and check every proof. An optional **relayer** submits gasless withdrawals on your behalf. The pool learns only that a valid proof was presented; it never sees the secrets behind it.

*Fig. 5 — The three components and how they interact. Secrets and proving stay on the device; the chain verifies, it does not learn.*

## Non-custodial keys & on-device proving

Lacuna is self-custodial in the strongest sense: your private keys and note secrets are generated and stored on your device — behind the operating system's secure storage and a PIN or biometric gate — and the zero-knowledge proofs that authorise your transactions are produced locally. No server holds your keys, there is no account to register, and only you can move your funds.

{% hint style="info" %}
**Why this matters.** Self-custody is not a promise to behave well. It is an architecture in which no one else *can* act on your behalf, because no one else ever holds what would be needed to do so.
{% endhint %}

## Shield — deposit

To shield, you lock assets in the pool and register a commitment, which is inserted into the pool's accumulator alongside everyone else's. From that moment, your balance is a private claim rather than a public number.

## Private transfer

A private transfer moves value between commitments inside the pool. It consumes your input note — publishing its nullifier — and creates new commitments for the recipient and any change, all proven in zero knowledge.

## Unshield & partial withdrawals

Unshielding releases funds to any public address. Partial withdrawals are supported: you take out what you need, and the remainder returns to the pool as a fresh commitment, still private.

## Double-spend prevention & membership

Every commitment lives in a Merkle accumulator whose root the contract tracks. A spend proves its note belongs to the set committed by that root — without revealing which note — and publishes a nullifier the contract has never seen. Together these guarantee that funds can be spent once, and only by their owner.

## Notes, balances & transaction types

Lacuna follows a note-based model. Your shielded balance is not a single number but a set of notes — individual commitments, each holding an amount only you can spend. Spending behaves like cash: to send 30 from a note worth 50, you consume the 50, create a 30 note for the recipient, and a 20 change note that returns to you. Because both outputs are fresh commitments, neither the amounts nor their link to the original is visible.

Every Lacuna operation reduces to the same shape — some input notes consumed, with their nullifiers published, and some output notes created — accompanied by a zero-knowledge proof that the inputs and outputs balance and that the spender owns the inputs. Shielding adds value from outside the pool; unshielding removes it; transfers and swaps move it between owners and assets within the pool. One proving circuit serves them all, and in every case the chain learns only that the operation was valid.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.lacunalabs.io/the-lacuna-protocol.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
