Skip to content
OFFICIAL CA0xdafaa1ed0b9f5746a0cfa2be80371cf06a986977

Documentation

Python agents

PyPI: upochPython 3.10+LangChain 1.x

pip install upoch: verifiable checkpoints, recovery and rollback for any Python agent, and a one-line callback for LangChain and LangGraph.

Setup

Once, in your own terminal. You need Node.js 24 or later as well, because the upoch command holds the keys and does the signing:

terminal
npm install -g @upoch/guard
upoch setup                      # keys, funding, registration

upoch setup creates two keys on your machine: the owner, which registers the agent, and the executor, the agent's key, which can only submit checkpoints. It waits while you send the owner a little ETH on Robinhood Chain (0.001 ETH is plenty), then registers the agent. Then:

terminal
pip install "upoch[langchain]"     # or just: pip install upoch

LangChain and LangGraph

Every consequential tool call (swaps, transfers, bridges, staking, lending, trades, mints, launches and approvals) is checkpointed before and after it runs. The pre-tool checkpoint is committed before the tool runs, with invoke and ainvoke.

agent.py
from upoch.langchain import UpochCallbackHandler, upoch_tools

upoch = UpochCallbackHandler()

# Automatic checkpoints around consequential tool calls:
agent.invoke(inputs, config={"callbacks": [upoch]})

# Optional: let the model restore, checkpoint and roll back itself.
tools = [*your_tools, *upoch_tools(handler=upoch)]

The tools are the same as in the JavaScript plugin: upoch_restore, upoch_checkpoint, upoch_rollback (by default to the checkpoint right before the last swap or transfer), upoch_history and upoch_complete. Options: watch, state and strict.

Any Python agent

agent.py
from upoch import Guard

with Guard() as guard:
    restored = guard.restore()        # where the last run stopped, verified against the chain
    state = restored.get("state") or {"step": 0}

    guard.record_action("swap-1", "swap", "planned")
    guard.checkpoint(state, note="before swap", kind="before_action")
    tx = do_the_swap()
    guard.record_action("swap-1", "swap", "confirmed", transaction_hash=tx)
    guard.checkpoint({**state, "step": 1}, kind="after_action")

    guard.rollback(0, reason="the swap was the wrong size")   # back to the checkpoint before it

Each method returns the result as a dict; refusals raise upoch.UpochError. A rollback restores the agent's state; it cannot reverse transactions that already happened on-chain. The actions that ran after the restored checkpoint are listed, and every later restore returns them too, so a restarted agent does not repeat them.

How it works

Guard starts the upoch MCP server and talks to it over stdio. That process encrypts each checkpoint on your machine, stores it on IPFS, commits its fingerprint to the Upoch contract and reads it back to verify it. Every checkpoint opens in the Time-Travel Debugger.

Safety

  • Each checkpoint is one transaction from the executor key, with a daily limit (100 by default, maxCheckpointsPerDay in ~/.upoch/config.json).
  • State that looks like private keys, seed phrases or API tokens is refused before anything is stored: checkpoints are permanent.
  • Keys stay on your machine in ~/.upoch/secrets.json, unencrypted (owner-only permissions on macOS and Linux), and never pass through Python. Back it up, and keep only small amounts on these keys.
  • The Upoch contracts have not been audited.