14 Guides

Undo from X

How a tweet can bring a sender to a one-tap undo, why the bot cannot touch funds, and what it would and would not reveal.

#The idea

Panic is fastest on a phone. A sender who realises they sent a link to the wrong person should not have to find the app, find the link, and remember the id. They should be able to reply on X and get a button.

@UseOopsend undo https://oopsend.app/c/0xA11c…E4f1/48213

The bot replies with a link to an undo page. The sender opens it, connects their wallet, and signs one transaction: undo(id).

#Flow

  1. The sender tweets or replies with @UseOopsend undo <link>. The secret in the #fragment is not needed and discouraged: undo never uses it. If the tweet contains a secret, the bot strips it from its reply and warns the sender that the link is exposed.
  2. The bot reads mentions, parses the link, and extracts the sender address and the id.
  3. The bot computes linkKey and reads links(linkKey) from the chain to see whether the link is still open.
  4. The bot replies with a URL such as https://<app>/undo?sender=0xA11c…&id=48213.
  5. The sender opens the page, connects a wallet, and the page calls undo(id). It only enables the button if the connected wallet equals the link's sender.
  6. The bot may reply once more when it sees LinkUndone for that key.

#Why the bot cannot steal or grief

  • It holds no keys. undo requires msg.sender == sender, because the contract looks the link up under the caller's address. The bot has nothing to sign with, and nobody else can undo your link.
  • A stranger tweeting undo on your link gets a page only you can use. The page shows the link's state, but the transaction only succeeds from the sender's own wallet.
  • The undo page is stateless. It reads the chain and builds a call. It stores nothing about you.
  • Undo is not a secret operation. The id and the sender are already public on chain in LinkCreated, so the bot is not revealing anything an observer could not read.

#Privacy

  • A reply that says "1.5 ETH, expires in 6 days" would publish that a link of that size exists between this sender and an unknown recipient. The sender address and the amount are already visible on chain, but linking them to an X account is new information. The bot should reply with no amounts unless the account has been linked to the wallet by a signed message.
  • The bot should never repeat a full link. It should link to the undo page with the sender and the id only.
  • It should ignore links whose sender has no relation to the author of the tweet, or at least not add detail.

#Abuse controls

  • A per-author reply limit and a global rate limit.
  • Ignore mentions older than a short window.
  • No reply for links that are already closed, other than a short "already closed" note.

#Why not a one-click action inside the tweet

Some chains let a wallet extension render a transaction directly in the feed. On this chain Oopsend does not rely on that: the bot only replies with a link, and the transaction happens on a page where the wallet shows the usual confirmation. That is less magical and has fewer moving parts.

#If you do not use X

The same undo is available from the app's "My links" list, which rebuilds your links from chain events. See Integrate to do it in your own tool: it is undo(id) from the sender's wallet.

#Status

Undo from X is a design. The contract function it relies on, undo, is built and tested. The bot and the undo page are not running.