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

# LedgerKeep

LedgerKeep keeps Soroban contract state from expiring.

Every piece of data a Soroban contract stores has a time-to-live measured in ledgers. When it runs out, the data is archived: persistent entries can be restored, but at a cost, and a contract's instance and code become unusable until someone restores them. There is no way for a contract to watch its own data approach expiry, because a contract cannot read its own time-to-live while it runs.

Today every protocol handles this alone, with a script someone remembers to run. There is no shared tooling, because there is no standard way for a contract to say which of its stored keys are the ones that matter.

LedgerKeep is that standard, plus the tooling that uses it.

## The two halves

**On-chain** — a Rust crate a contract adopts with one macro, a permissionless registry where contracts publish the keys they want maintained, and a rent vault that pays whoever performs the maintenance. This is [`ledgerkeep-core`](https://github.com/ledgerkeep/ledgerkeep-core).

**Off-chain** — a command-line keeper that reads a contract's time-to-live over RPC, reports how close each entry is to expiry, and extends the ones running low. This is [`ledgerkeep-cli`](https://github.com/ledgerkeep/ledgerkeep-cli).

The split is not arbitrary. A contract can extend its own time-to-live and record that it did, but it cannot observe time-to-live at runtime. Observation has to happen off-chain. So the contracts do the extending and the recording; the CLI does the watching.

## How it fits together

A contract adopts the standard. It declares — at compile time — which of its stored keys are critical, and it publishes that list to the registry so tooling can find it. A keeper reads the registry, scans each registered contract's time-to-live over RPC, and calls the contract's permissionless `extend_all` when an entry runs low. The contract extends its keys and records who maintained it and when. The keeper then claims a tip from that contract's rent vault, which confirms the work happened by reading the record the contract left.

## What to read next

* New to Soroban's storage model? Start with [State archival and TTL](/ledgerkeep/concepts.md).
* Want the shape of the system? [Architecture](/ledgerkeep/architecture.md).
* Building a protocol and want it maintained? [Adopting the standard](/ledgerkeep/adopting.md).
* Running a keeper? [The CLI](/ledgerkeep/cli-guide.md) and [Running a keeper](/ledgerkeep/running-a-keeper.md).
* Evaluating the design? [Protocol mechanics](/ledgerkeep/protocol-mechanics.md), [Economic model](/ledgerkeep/economic-model.md), and [Security](/ledgerkeep/security.md).

## Status

Deployed to Stellar testnet. The contracts are unaudited. Do not use them on mainnet with real funds without your own review.


---

# 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, and the optional `goal` query parameter:

```
GET https://dillon-2.gitbook.io/ledgerkeep/readme.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
