Skip to content

ophelios-studio/kintsugi

Repository files navigation

Kintsugi

Atomic, sweeper-proof wallet rescue using EIP-7702.

Kintsugi rescues assets from a compromised EVM wallet in a single atomic transaction. The victim signs an EIP-7702 authorization plus an EIP-712 batch authorization off-chain. A clean rescuer wallet submits one Type-4 (SetCode) transaction that delegates the victim's EOA to the audited Rescue contract and runs the entire batch in the same block. The victim never holds ETH, so a sweeper bot watching the victim's balance has no opening.

Status: pre-alpha. Mainnet and Sepolia. Solidity contracts, TypeScript core library, interactive CLI.

How it solves the rescue problem

The classical Flashbots-bundle approach to rescuing compromised wallets needs the victim to receive a funding transaction first. Against an active sweeper bot that funding always wins. Worse, the Flashbots relay rejects bundles whose victim transactions need more balance than the victim's pre-bundle state, so inter-transaction funding bundles do not even simulate.

EIP-7702 (mainnet since Pectra, May 2025) lets the rescuer pay for everything in one Type-4 transaction. The victim's balance never rises above zero during the rescue; whatever a sweeper is watching for, it is not there. See docs/ARCHITECTURE.md for the full reasoning.

Repo layout

contracts/                  Solidity (Rescue + NonceTracker + mocks)
test/                       Hardhat 3 + viem unit tests (34 covering every code path)
scripts/                    Deploy, deploy-test-assets, sweeper simulation
packages/core/              @ophelios/kintsugi-core, headless TypeScript library
packages/cli/               @ophelios/kintsugi-cli, interactive CLI
docs/                       Architecture, security, usage notes

Quick start

git clone https://github.com/ophelios-studio/kintsugi
cd kintsugi
npm install

# Run the contract test suite
npx hardhat test

# Build everything (core, ui, cli)
npm run build:all

# Make `kintsugi` a global command on this machine
cd packages/core && npm link
cd ../cli && npm link @ophelios/kintsugi-core && npm link
kintsugi --help

To run an actual rescue:

kintsugi rescue            # interactive terminal flow
kintsugi ui                # polished web UI on localhost

An Alchemy API key is required for asset discovery (ERC-20, NFT, and ENS). The free tier works. Get one at dashboard.alchemy.com/signup.

# Quick read-only inventory of a wallet
kintsugi status <address> --alchemy-api-key <key>

See docs/USAGE.md for the full walkthrough.

Asset coverage

  • ERC-20: any token with a standard transfer function.
  • ERC-721: any standard NFT.
  • ERC-1155: standard multi-token.
  • ENS: unwrapped .eth 2LDs (reclaim + transfer in the same batch), wrapped names (NameWrapper transfer), unwrapped subdomains (registry setOwner). Optional helpers for setResolver and clearReverseRecord.
  • Custom calls: any contract function the victim must call before transferring an asset (unstake, withdraw, claim, exit, revoke).

Tests

npx hardhat test

34 unit tests covering every code path in Rescue.sol and NonceTracker.sol, plus a structural sweeper-bypass test that asserts the victim's ETH balance is zero at every observable point in the rescue lifecycle, even though every asset transfer succeeds.

Deployments

Mainnet (self-audited, no third-party audit, see AUDIT.md)

Sepolia (live demo)

The integration test test/integration/sepolia-sweeper-bypass.test.ts runs a real sweeper bot against both rescue strategies on Sepolia and proves the difference end to end.

Demo result from the most recent run:

Scenario Outcome
Traditional rescue (rescuer funds victim, then signs from victim) Sweeper bot drained the funding tx in tx 0x8a851fb5.... Assets stuck.
Kintsugi rescue (Type-4, sweeper still active) Atomic rescue mined in tx 0xa39d79f3.... Sweeper got 0 ETH, 0 drains. Assets at safe.

Releasing

All four package.json files share the same version. Bump them together.

Only two packages are published to npm:

npm run build:all
cd packages/core && npm publish --access public && cd ../..
cd packages/cli  && npm publish --access public && cd ../..

@ophelios/kintsugi-ui is not published — its dist/ is copied into the CLI during build (cp -r ../ui/dist dist/web), so end users get the UI bundled inside @ophelios/kintsugi-cli.

Differentiation

This is the first open-source CLI for EIP-7702 wallet rescue. Closed-source services (Antidrain, DrainerLESS) charge a percentage of recovered assets and do not have a CLI. Existing OSS efforts have under 50 stars combined and do not handle ENS or asset discovery. See docs/ARCHITECTURE.md and docs/SECURITY.md for the design choices that follow from those gaps.

License

MIT.

About

Atomic, sweeper-proof wallet rescue using EIP-7702

Resources

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors