ephemeral

ephemeral · Build

Powered by ephemeral Privacy you can plug in.

The pieces we built for EPH, free for any project: buy into a stealth address, pay many holders without a public map, check withdrawals before they leak, count points per token, and measure what still links. Each with its real status and three steps to plug it in.

Pick by problem

What are you shipping?

Your problemStart with
Users buy your token, and the receipt should not sit in their main wallet.StealthBuy
You pay holders the same reward each epoch, and your ledger shows who got what.StealthPayout v1
Your rewards differ per holder (holding time, volume, previous owners).StealthPayout v2
You run a wallet or claim page, and users undo their privacy when they withdraw.Withdrawal policy
You run points, and people farm them by splitting wallets or parking tokens in vaults.Phases accounting
You want numbers on how traceable stealth payments are today.Leak scanner

Primitives

Six pieces, one repo

All in github.com/siriusthemaster/ephemeral, each in its own folder with tests you can run. Rated Stage 0 in the Lab? StealthPayout is the fix path to Stage 1.

StealthBuy

  • Unaudited
  • Test runs on mainnet 8 Oct

Buy a token on Uniswap v4 straight into a fresh ERC-5564 stealth address, with gas for the receiver in the same transaction.

Status
About 150 lines, no owner, no fee. Two test deployments of an earlier version ran on mainnet against a canary token; no production deployment yet.
Tests
21 Solidity tests, 4 end-to-end scenarios on anvil.
Leaves
The buyer is still the sender. It cleans the receiving side, not the paying side.

Integrate in 3 steps

  1. The receiver shares an ERC-5564 meta-address (ERC-6538 registry or a pay link).
  2. Your app derives a new stealth address for every buy and calls buy(key, stealth, hookData) with ETH to swap plus a gas tip (max 0.01 ETH).
  3. The receiver's wallet finds it through the canonical Announcer and spends with the bundled gas. Never resend a prepared buy: it reverts.

router/ on GitHubDocs

StealthPayout v1 · equal batches

  • Toy
  • Unaudited
  • Not deployed

Pay one reward epoch to every holder in one transaction: the same amount each, each to a fresh stealth address. The ledger logs epoch totals, never a per-holder debit.

Status
Public design with tests, written to answer Claus Lab's question. No owner, no admin, no fee.
Tests
16 Solidity, 13 TypeScript (plans, proofs, an observer brute force that finds zero links).
Cost
About 44,500 gas per recipient; 195 recipients fit in one transaction.

Integrate in 3 steps

  1. Holders register a meta-address (ERC-6538 registry or your app). Your snapshot maps NFT or account to owner to meta-address.
  2. Each epoch: planEpoch, send settleCalldata(plan) with plan.value. Publish the leaves, never the receipts.
  3. Holders' wallets scan with findMyPayouts, spend each payment on its own, and prove one to a verifier with proveEntitlement.

payouts/ on GitHubPAYOUTS.md

StealthPayout v2 · denomination notes

  • Toy
  • Unaudited
  • Not deployed

Pay unequal debts without naming who got what: round down with a carry, split into standard notes, one equal-amount group per denomination, each note to its own stealth address.

Status
Same contract as v1 (settleNotes). The total is checked on chain against the declared ledger payout.
Numbers
200-holder test world: a note is attributed correctly 1.3% of the time at the median holder, 14.8% for the largest. Median payment delay 0.05 epoch.
Tests
8 Solidity, 19 TypeScript (rule, proofs, 30-epoch carry, per-holder metrics).

Integrate in 3 steps

  1. Publish the rule: base unit, minimum crowd, and each epoch's ledger lines (owner, debt).
  2. Each epoch: planNotesEpoch, then for each part of splitParts(plan, 300) send settleNotesCalldata. Anyone can check it with auditNotesEpoch.
  3. Holders run findMyNotes and spend each note separately; merging notes rebuilds the debt the ledger shows.

payouts/ on GitHubv2 design

Withdrawal policy H1 to H5

  • Unaudited
  • Used by the ephemeral client

The checks a wallet runs before anything leaves a stealth address, from a scan of 25,688 of them: block the habits that link payments back to their owner, warn on the rest.

Blocks
Withdrawing to the wallet that created your keys (H1); token payments with no ETH for gas (H5).
Warns
Back to the payer (H2), reused destinations (H3), withdrawing within the hour. H4: the fee is always the network standard, so it carries no fingerprint.
Tests
22, pure TypeScript, no network in the guards. History incomplete counts as a warning, never "unused".

Integrate in 3 steps

  1. Load past sends with loadWithdrawalHistory (explorer plus a node check). Pass sentCount, the on-chain nonce of every address you load, keys in any case. It is required: a missing entry counts as incomplete history. Pass historyComplete honestly.
  2. Before each withdrawal call withdrawChecks with the destination, payer, your stealth addresses and used destinations.
  3. Refuse when blocking(), show warnings(). Never offer the key wallet as a destination, and ship no sweep-all button.

withdrawal-policy/ on GitHubDocs

Phases accounting

  • Reference code
  • Unaudited

Points that cannot be farmed by splitting: holding age and launch-hour status travel with each token, pro rata, so a split can tie or lose, never win.

Status
The accounting our indexer runs for EPH Season 1 (draft, final at launch). Reviewed in public by Claus Lab, v2 to v3.2.
Handles
Vaults, staking, lending and exchanges as shared contracts; Safes count only with an attestation from every owner.
Tests
15, including random chains of thousands of tiny transfers and a stated limit for custodians.

Integrate in 3 steps

  1. Feed every transfer of your token to buy, sell or move, with the day.
  2. Class each address with classify (and attestationValid for multisigs) so shared contracts reset age.
  3. At each snapshot read unbrokenBoost and firstLightTokens per wallet and plug them into your points formula.

phases/ on GitHubSeason 1 rules

Leak scanner

  • Research tool
  • Aggregate output only

Reruns the Kovács and Seres (2023) heuristics on today's ERC-5564 and Umbra data, checks itself against their 48.51%, and adds H5, gas funding.

Output
Counts only. No address, cluster or link is published; raw chain data stays on the machine that ran it.
Needs
Node 20+ and an RPC that serves large log ranges. A full mainnet scan costs a few dollars.
Tests
17, including an end-to-end scan against a fake node.

Integrate in 3 steps

  1. Put your RPC key in .env, then npm install && npm test.
  2. npm run scan -- --sample 500 for a quick look, npm run scan for the full history.
  3. Reuse analyze() on your own payments and withdrawals, and publish counts, never addresses.

research/ on GitHubLeak study

Pilots

Pilots, as they stand

Exactly where each one stands. No logos, no partnerships beyond what is written here.

  • Sketch, pilot discussed

Clay

Private receipts for CLAY Figure payouts on Solana: each opted-in Figure's share goes to a fresh one-time address, with a committed Merkle root and a receipt the holder shows to one verifier. A design sketch adapted from StealthPayout; no Solana code exists yet.

SOLANA_SKETCH.md

  • Public review partner

Claus

Claus Lab (@contractclaus) reviews our code in the open. Its questions became StealthPayout v1 and v2, the StealthBuy use record, Phases v3 to v3.2 and the withdrawal history checks. We rate Claus in the Lab like anyone else.

Review logClaus in the Lab

  • Open

Your project here

Pay holders, run points or ship a wallet? Post on X with one line on what you pay out, to whom and on which chain.

@ephemeral_eth integrate

Builders can also write to devs@ephemeral.money.

How we work

Plain terms