archive about

All about Farcaster Signers

Approving, revoking, and using them to re-sign messages.

Most users know "Signers" as "this thing you have to pay for when you connect a new app". One of the first articles in Purple Sumbarine, was about Farcaster Signers, but my understanding has evolved since then, and we also have new tools and advances since then.

In order to understand signers, you have to keep in mind that all interactions with hubs take place by sending hubs a "message" that has a specific structure. So, when you cast, like, or recast, the app you are using sends a message to a hub saying "@vrypan.eth casted Hello World", or "@vrypan.eth liked this cast".

Messages look something like this under the hood:

As you can see such messages have two parts.

(What you see in the signer filed is not the actual signer, but the public key of the signer.)

Why we need signers

In a centralized network such as twitter or facebook, you usually have a username and a password. You use your credentials to connect to a server, and then the server knows that you are who your credentials say you are. There is no other way to post something to the service, and the centralized server is the absolute authority of what was posted by whom.

Farcaster is an open, p2p network. Anyone with some technical knowledge can create a program that sends messages to the Farcaster network. The only way to verify the authenticity of these messages, is by their digital signature.

Each Farcaster user has their own keypair, a private and a public key. If you signed up using Warpcast, your recovery phrase can be used to generate this pair. This keypair also corresponds to an ethereum address, what is often called in Farcaster the custody wallet.

So, you could actually sign your messages using your private key. But users rarely create these messages on their computer using a program they wrote. They connect to a service or app, like buidler and after authenticating with it, it posts on their behalf. The problem is you don't want to give them your private key. This would be the equivalent of giving a gmail integration your username and password (and to some extent, not even being able to change the password).

Here is where Farcaster Signers come to play: Instead of giving an app your private key, the app creates a new random key, and asks you to approve it. You approve it using your private key and you register your approval onchain (gas cost!). From this point on, any hub that receives a message signed by this Signer, can check the blockchain to verify that you have approved the signer and accept it as authentic.

Warpcast and meta-transactions

When you make a call to a smart contract, the caller has to pay the gas for its execution. This is why adding or revoking a signer (onchain transactions) have a cost.

Normally, your Farcaster custody wallet would need to have some OP ETH to perform these transactions.

But wait. There's a workaround: KeyGateway, the smart contract used to approve Signers, allows meta-transactions. You can think of meta-transactions like this:

Warpcast takes advantage of this feature to hide the added complexity of using a blockchain: It will ask the user to pay them $1, and then they use a meta-transaction and they pay for the gas.

This is roughly the equivalent of them saying "Just sign this paper, give me $1, and I'll take care of the rest."

The actual gas cost for adding and removing signers is usually well bellow $1. Warpcast now allows users to also pay using Warps, an in-app credit system: You can buy 500 Wraps for $5, and approving a signer will usually cost around 40-50 Warps (depending on gas cost at the time of the transaction).

(Warps are an interesting experiment that deserve a separate article.)

Revoking a signer

Obviously, a user must be able to revoke a signer, and they can do so using their private key and posting the revokation onchain to let everyone know that the signer is no longer authorized to act on their behalf. This was the whole point of not giving away our private key in the first place.

But, when a signer is revoked, hubs see messages that are no longer signed by a valid signer. Most people's first thought is OK, but these are old messages signed when the signer was valid. But you have to keep in mind that Farcaster is an open, p2p network. Hubs are added and removed all the time. You could spin up your hub right now (it's actually quite easy) and your hub would receive messages from other hubs it discovers in order to get its history (aka state) up to date. How can your newly created hub know when a message was signed?

This is why hubs have a simple way of "thinking": not a valid signer, not a valid message. And, as a result, when you revoke a Signer, all messages signed using it, are pruned by hubs!

This looks bad. The truth is there is a simple solution that no app (to my knowledge) has implemented (yet). Remember the message example we used earlier? What if you signed the same message with a different signer?

Signing the message with new signer will create a new signature, but the message data and the message hash will stay the same: Same user (fid), same content, same timestamp.

So, an app could:

  1. Download all your messages (your Farcaster history)
  2. When you remove a signer, and some messages are pruned, re-sign these messages (from your download) with a new signer.
  3. Post the re-signed messages to a hub.

Using fario

You can perform the above steps using https://github.com/vrypan/fario if you are comfortable working in the command line. You will have to:

Backup your data using fario-out --all.

Use fario-grep to select the records signed by the signer you want to remove.

Remove the signer using fario-signers remove and create a new signer using fario-signers add

Re-sign the messages using fario-signers sign

Upload the re-signed messages using fario-in

Final thoughts

Signers are an elegant approach to delegating permissions. It allows users to easily let an app act on their behalf, but at any point in time, they can revoke this permission.

The lack of a simple, user-friendly app that allows users to revoke a signer without deleting all activity performed using it, is definitely a pain-point looking for solutions: Right now, using a signer means that you are stuck with it, since revoking access will delete any casts, likes, recasts and follows you have performed using it. (Unless you are one of the few users who understand the technical details of Signers, and have the skills to use something like fario or put together a script by yourself.)

Looking forward to try the first apps that will give a user-friendly solution to this!