Lots of us know and love the bitcointip robot on reddit. It’s planning on getting a boost with client-side plugins that will scan and report tip events across all of reddit, solving one of the project’s biggest scaling problems. But the idea is perhaps big enough that we don’t need to stop at “just reddit.” Bitcointip is one of the world’s most powerful bitcoin evangelization systems. It should encompass the whole web. And it can.

I call it “Universal Tip.”

The syntax

+utip $5 /u/rainfly_x @kaepora for creating cryptocat.

If anyone’s browser plugin sees that text among the other contents of a web page, it will report that text (and the current window.location) to a utip gateway (more on those in a minute). In a few minutes, Rainfly_X (me) will get a notification asking if I approve the payment. Clicking “Yes” will transfer $5 worth of bitcoins to @kaepora’s utip account.

Things worth noting about this example

  • We’re able to specify prices in any currency with prefix symbol or postfix name.
  • I’m sending via an identity associated with reddit. @kaepora is on Twitter. And this tip could have been posted anywhere on the web.
  • There is a memo section that feels like natural speech.

Specialized commands

While version 1 does not standardize any commands other than plain tipping, it leaves this open for forward-compatible extension, like this:

+utip.dice ...

The regex for this starting section is \+utip[\.a-zA-Z0-9]*.

Price specifications

The price is defined in a regex as ([^ \da-zA-Z]\d+)|(\d+ [a-zA-Z]+). For laymen, it means “Either a symbol and a number, with no space between them; or a number and a space and a currency name (made of letters).”

The standard set of prefix symbols and postfix names is up for debate.

  • All major bitcoin symbols, as well as dollar, pound, euro and yen should be supported, at minimum, IMHO.
  • The currency name can be any standardized USD-style currency code, including BTC, or one of a few standardized BTC divisions, such as mBTC, credit, or milli.


The regex for these is very simple: [^ ]+. Any contiguous string of non-space characters. This allows almost infinite freedom. However, I expect a few standard conventions for some major sites/use cases.

  • /u/assbutt - Reddit user “assbutt”
  • @assbutt - Twitter user “assbutt”
  • ass@butt.com - User identified by email
  • d36857ca0d00be73dd5d2a5fabce731f60b4143aad77aef4eec32b3034df2750 - Bitcoin address

As you can see, identity in no way infers utip provider. With bitcointip, this is simple, because there’s only one provider, bitcointip. With utip, any provider can manage the account for any identity, as long as you can prove ownership to it (policy will vary from one provider to another). But we’ll get more into that later.

For every standard tip, there are two identities: to and from. This is not necessarily true for extension features.


This signals the end of the tip, and gives it a unique property so that it will only be processed once by your provider, no matter how many people report it. Every memo starts with the string “for “. The next character (the memo start char) determines what the termination character will be - there are no escapes.

  • If the memo start char is ', the termination char is '.
  • If the memo start char is ", the termination char is ".
  • If the memo start char is #, the termination char is #.
  • If the memo start char is {, the termination char is }.
  • If the memo start char is (, the termination char is ).
  • If the memo start char is [, the termination char is ].
  • Otherwise, the termination char is ..

This means that for simple memos, you can just use normal speech. For memos with a ‘.’ in them, you can use any of the alternatives.

The regex for this is for ('[^']*'|"[^"]*"|#[^#]*#|\{[^\}]*\}|\([^\)]*\)|\[[^\]]*\]|[^.]*.)

It’s possible that there will be a maximum-length memo to help deal with malformed tips, in which case, those asterisks will need to be replaced with {0,255} or something similar.

As a whole

Basic tips could just be a space-separated combination of the above regexes. But that really boxes things in for future extensions. We want to strike a balance between those needs, and being able to parse tips in a simple and efficient way now. So the general-case tip regex is a bit simpler. It’s the header (+utip, +utip.optional.extensions), a variable-length list of space-separated arguments, and a memo.

\+utip([\.a-zA-Z0-9])* ([^ ] +)* for ('[^']*'|"[^"]*"|#[^#]*#|\{[^\}]*\}|\([^\)]*\)|\[[^\]]*\]|[^.]*.)

Which can then be further parsed by providers, and safely passed along unmangled until then.

Provider and relay infrastructure

Providers are companies or services that you can set up a utip account with. They’ll maintain a wallet on your behalf that you can deposit to or withdraw from. The APIs for that are outside the scope of the utip format.

Any provider can provide accounts for any identity. Because this means that provider information can’t be derived from identity string, we use an IRC-based infrastructure to report tips to providers. This also commonizes tip reporting, such that new Service X doesn’t need to worry about a lack of tip reporting - they will benefit from the users of Services A, B, C, and more.


It’s not really feasible, or something that makes sense, for browser extensions to be joining IRC channels. What makes actual sense is to have relay devices that bridge between HTTP and IRC. While the exact mechanics of different relay devices may be different, the workflow is always the same:

  • Browser extension discovers a tip string X at URL Y
  • Extension reports this as string Z ( X + “ ” + Y) via a quick AJAX request to a relay server.
  • Server checks whether it’s seen that Z before.
  • If not, it broadcasts it to a known IRC channel.

Relays may or may not “confirm” tips (by loading the indicated page and confirming the presence of the tip string), in order to filter out false tips (in the sense of, tips that do not exist on the given page).

Secondary relay

Secondary relays are IRC-to-IRC, in the same sense that primary relays are HTTP-to-IRC. This is for another layer of filtration and cross-polination between IRC channels.

A secondary relay stores pairs of Z-string and timestamp. When it sees a Z-string on one side, it broadcasts it on the other side, as long as it’s well-formed and any stored information about it is expired. This helps prevent flooding channels with redundant data. Redis is a perfect technology for this rate-limiting.

Secondary relays help keep individual channels somewhat deduped, and are mostly useful for cross-polination of public channels, and relaying deduped data into private channels for provider servers.

Provider IRC servers

These watch IRC channels for tips, and respond to them with whatever automation makes sense for that provider. For example, texting the account holder, “Do you want to send a 50 BTC tip from @thepope for that wonderful night last night?” These are the gateway into the provider system, at which point transactions are confirmed with the users.

How does the provider know what address to send to?

Solved problem. Webs of trust have been handling this problem for public key infrastructure for years. This can even be semi-automated by signing authorities, though true P2P behavior is superior.

The technical details of that web of trust are up for debate, I freely admit that I don’t know which protocols are preferred.

Signing authorities

Third-party utilities that allow you to mechanically verify your identstring->address relationship. For example, a TwitAuth bot where you put your @twittername and bitcoin address into the TwitAuth site, it gives you a random string, and you DM that string to @twitbtcauth from your Twitter account to confirm ownership.

Signing authorities make it easy to get started with utip, but keys are subject to invalidation if the authority is discovered to have a bug (and may not be universally trusted either). So it’s always important to get your friends to sign your ident relationship.

You said something about automatic payments?

Automatic payments are the bane of bitcoin right now. But they don’t have to be. One of the funny side-effects of utip is that it supports autopayment workflows. Let’s give an example.

  • I want to keep my webhosting paid, so I give them my utip identstring.
  • Every month, they submit a link like http://genericwebhost.com/utip/2875927482, where the contents are dynamically generated and contain +utip strings.
  • These are picked up by the network like any tipstring, and soon your provider will notify you and ask, “Do you want to send genericwebhost.com a 0.3 BTC payment for April 2013?”
  • You can then approve the transaction.
  • A popular provider feature will be authorizing a regular payment pattern, such as “Automatically approve up to 0.3 BTC/month to genericwebhost.com”. This will quickly become ubiquitous, and allow anyone to approve autopayment of bills with Bitcoin.
  • Another integral feature is notification when your provider account holds less than a certain threshold in value. That way you know when you need to restock your account. There is all kinds of room for fancy features here, like automatically deriving threshold from your autopayment config.

Known issues

  • Tip spam. This is something that providers will have to help mitigate, like email spam.
  • Web of trust infrastructure not determined yet.

Join the discussion!

The post on /r/Bitcoin/.