Seal
createEthCapsule(beneficiary, unlockAt, revocable, title, message). Asset and fee travel in the same transaction. One signature.
LEGACY
Seal ETH, tokens or NFTs for any wallet, with a message, until a timestamp you choose. No custodian, no admin key, no early exit.
LEGACY keeps the asset, the beneficiary, the unlock time and the message as four fields in one storage struct. The website is just a window on the contract, and it can disappear without breaking a single capsule.
createEthCapsule(beneficiary, unlockAt, revocable, title, message). Asset and fee travel in the same transaction. One signature.
block.timestamp < unlockAt reverts with TooEarly(). The contract holds. Nobody can shorten the lock, not even the owner.
claim(id) checks the beneficiary, checks the timestamp, flips the flag, moves the asset, emits CapsuleClaimed. The beneficiary signs once.
The message reveals on the public gift card, with the receipt and the transaction hash. Messages are public calldata, never secrets.
No minting, no NFT required. The app reads the connected wallet, lists ETH, every ERC-20 balance including tokenized stocks on Robinhood Chain, and any NFT, and you pick what to seal. Three entry points, one storage struct, one claim path.
Asset and creation fee travel in one transaction. Direct transfers to the contract revert, so the only way in is createEthCapsule.
Any ERC-20, including tokenized stocks issued on Robinhood Chain. Approve, then create. Fee-on-transfer tokens are balance-accounted at entry.
For collectibles and deeds only. The NFT is received through a guarded onERC721Received that accepts the expected token, sender and id.
Owner powers stop at the creation fee, capped at 0.01 ETH, the fee recipient and ownership transfer. No proxy, no upgrade path, no library imports.
The whole security model fits in one function. Beneficiary check, timestamp check, state update, transfer, event. Reentrancy guard on top.
function claim(uint256 id) external nonReentrant { Capsule storage c = _open(id); if (msg.sender != c.beneficiary) revert Unauthorized(); if (block.timestamp < c.unlockAt) revert TooEarly(); c.claimed = true; _transferAsset(c, c.beneficiary); emit CapsuleClaimed(id, c.beneficiary);}
The app links the create, claim, cancel and beneficiary-update transactions, and every capsule has a public receipt page and a gift card.
| Action | Function | Who | Check | Status | Receipt |
|---|---|---|---|---|---|
| seal | createEthCapsule | creator | fee + unlockAt > now | wallet signed | CapsuleCreated |
| wait | claim | anyone | block.timestamp < unlockAt | reverts TooEarly | no state change |
| claim | claim | beneficiary | sender + timestamp | wallet signed | CapsuleClaimed |
| cancel | cancel | creator | revocable == true | wallet signed | CapsuleCancelled |
| reassign | updateBeneficiary | creator | revocable == true | wallet signed | BeneficiaryUpdated |
A V2 capsule holds one to four conditions that must all pass inside claim(): TIME, PRICE from an AggregatorV3 oracle with a staleness window, ERC20_BALANCE, ERC721_OWNER. ETH and ERC-20 capsules can roll a percentage forward into a child capsule with a new lock.
Chainlink-style latestRoundData, rejected when stale or when decimals exceed 36.
Released only if the beneficiary still holds the governance token at claim time.
A share rolls into a new capsule with its own unlockAt. Vesting without a vesting contract.
Every capsule addressed to the connected wallet, with a live countdown, a claim button that activates at unlock, and a calendar export.
LEGACY / 008Lock today. Reveal tomorrow. Live forever. Start with a tiny, short-duration ETH capsule, confirm the early claim reverts, then use meaningful funds.
Contract 0xaeaa…a3f1 · Robinhood Chain · fee 0.001 ETH · not audited yet