Status widget/plugins/dApps as a way to iterate faster

Expanding on this idea.

Let’s go down the bot architecture. A main difference to telegram is that the bot is local (at least at first).

One can install a bot by adding it as a special contact. The bot would be linked to a specific piece of code.

Many security assumptions, but we should see it as a browser extension. Once the bot is installed, you have code running locally for this bot.

At first, interaction can be only one-to-one and local. Meaning no messages sent over Waku, and potentially no direct internet access. Or only very restricted access to enable some use case while keeping it secure.

Later, a bot could be added to a group chat. This means that users would need to install the bot locally and the bot would get access to some messages in the chat, and send messages over the wire.

A bit difference from Farcaster Frames is that while some data can fetched from a remote server, the code and logic should be installed locally once.

API

The bot code should be able to access an API to call for specific actions. This should be defined similarly to the Chrome extension API (not saying same API, but definitely need some inspiration).

For example

display(text: string, buttons: { text: string, action: Action }[])

Plain text message is displayed in the chat as a message coming from the bot.
There can be action buttons under the text, similar to Farcaster frames. The possible actions are:

  • {type: 'execute', text: "tap here to execute some code", function: function_name(args) }: run a specific function define in the bot code (ie, wizard flow, to interact with the bot)
  • { type: 'wallet', text: "send token to friend", action: wallet_action }: a specific wallet action, that redirects to the wallet (ie, to send some token to a user)

alarms

Similar to Google Extensions API to schedule code

register(handle: string)

Register this bot to parse messages sent over the wire.
This authorize the bot to read messages in the group chat they are invited to. if the messages are tagged with handle.

It also means that any message sent by the bot in a group chat, has to be tagged with handle.

If a bot has register handle in the group chat, and a message comes with it, then the message may be hidden to the user and just processed by the bot, who may display something different by processing the inbound message.

It also means that if no bot is registered in the chat, then the raw message could be displayed, prompting the user that it may be interesting to “invite” a bot in this chat to handle the message.

In addition, this or a different api should allow the bot to read local messages that are a replied to its own or where it is tagged.

It also means backward compatibility (these are just regular messages, but the person tag is a bot)

sendMessage

A message is sent in the group chat, this message is sent over Waku and tagged with handle to let local bot instances of recipients process the message.

More examples

Consume RSS feed

Consume a remote RSS feed to display in the chat room.

// Function called after user has installed the bot
init() {
 // Display a message with one button to schedule the feed.
  display(
  // status api is exposed via `status` object
    status.display("Do you want to start receivings news about x?",
      {type: "execute", text: "Subscribe to feed", function: scheduleRss })
}

// schedule RSS feed retrieve
scheduleRss() {
  status.alarms.create('fetchSubscription', {delayInMinutes: 1, periodInMinutes: 60 })
}

// React to the alarm
status.alarms.onAlarm.addListener((alarm) => 
{
  if (alarm.name === "fetchSubscription") {
   const response = await fetch ("http://myrssfeed")
   const json = await response.json()
   const lastEntry = json.entries.pop()
   // Display to the user the last entry of the feed
   display(lastEntry.body)
  }
})

Request money to friend

Alice and Bob have a 1:1 chat. They both install the “money” bot to the chat.

Here is the bot code

// Bot setup
init() {
  // Register to listen to messages

  status.register("money")
  status.register.onMessage("message" => {
    // Alice can send in chat "@money request 10SNT"
    // Or a message sent over the wire tagged for the bot is received (json format)
    const [action, data] = parseMessage(message)
    if (action === "localRequest") {
      display("Confirm requesting friend for ${data.amount}",
        [{ type: "execute", text: "Yes", function: request(data.amount)},
         { type: "execute", text: "No", function: abortRequest}])
    } else if (action === "remoteRequest") {
       const [recipient, amount] = action.data
       display ("${recipient} requested ${amount}",
         [{ type: "wallet", text: "Send", action: "eth:0.5eth:0x..."},
         { type: "execute", text: "No", function: rejectRequest}])    
    } 
  })
}

request(amount) {
  // Sends a message over the wire to be received by recipient's bot
  status.sendMessage("@${handle} {type: "request", amount: amount, recipient: 0x... //chat key}")
}

Additional Notes

I hope this provide a more concrete example on how the widget idea could be executed.

Permissions to access specific API should also be asked/given when installing an app.

A first approach would be to not open the “bots” to other developers, but only have bots installed by the Status app. Removing from first scope the ability to install/uninstall a bot etc and trimming the scope as much as possible for a PoC and one first example so that only part of the API can be implemented at first, and focus on local bots first, where no messages over the wire are sent.

The UX is just a proposal. Buttons are interesting, especially for wallet action. But it may be easier to just send commands by tagging or replying to the bot (or only have buttons for wallet actions, and the rest being handled via text commands).

Of course, the bot code is just an example and incomplete.

Links

2 Likes