openacid
live0G Galileo · Sepolia ENS
A·C·I·D
import { saga, invariant, idempotent, receipted } from '@openacid/acid'; // kill -9 me. I won't double-spend. const rebalance = receipted({ storage, signer }, invariant({ pre: walletBalanceOK, post: noOrphanAllowances, }, idempotent({ key: (a) => `rebalance:${a.target}`, onChainAware: { chain, waitForFinality: 1 }, }, saga({ steps: [ { id: 'approve', do: (c) => approve(USDC, router, c.amount) }, { id: 'swap', do: (c) => router.exactInput(c.args) }, ], compensations: { approve: (c) => approve(USDC, router, 0n) }, }) ))); await rebalance({ target: 0.6 });
A
Atomicity
saga()
Multi-step actions commit fully or roll back via compensations.
C
Consistency
invariant()
Pre/post predicates enforced at action boundaries.
I
Isolation
idempotent()
In-flight tracking and dedup. No interleaving, no double-spend.
D
Durability
receipted()
Signed chained receipts in 0G Storage. Crash-recoverable.
proof · kill -9
Proof ~ not a promise
kill -9 the agent.
It restarts.
It does not double‑spend.
Every step inside receipted() is signed, persisted to 0G Storage, and mirrored to openacid.eth. On restart, the wrapper reconciles via chain query and skips anything already mined.
$ cast call openacid.eth "text(...,'receipt.latest')"
// no library install · any ENS resolver
crash-safeidempotent117 vitest · 8 forgesigned log
live demo
$ node agent.js
Not a job queue.
Not a retry library.
Not a workflow engine.
Not an observability tool.
The library you keep meaning to write
Stop losing money to duplicate transactions.
$npm i @openacid/acid