Coil Web Monetization on mobile - no browser extension needed
Tags: micropayments, coil, webmonetization, oauth
Published: 2021-03-05 14:52:29

This post explains how you can use Coil's OAuth login API to stream payments from [Coil](https://coil.com/) users without them having to use a browser extension. Coil has proposed and implemented a new standard to monetise content online without depending on advertising, called [Web Monetization](https://webmonetization.org). The service is built on the [Interledger Protocol](https://interledger.org). They are doing an amazing job at squaring a circle to make a better web for everyone. They have a service for Coil subscribers who pay to a personal balance, which is then distributed to content owners via Coil browser extensions, mobile apps and apps connecting to the Coil API.

If you want to see what you'll learn in this article, try out our implementation in [the Kendraio Player](https://app.kendra.io/player/all) and [see our screencast](https://youtu.be/T2yXWJKIgOQ).

{% youtube T2yXWJKIgOQ %}


Setting up OAuth and login process
==================================

Several steps are needed to set up OAuth. To get started, email Coil, fill in the [web form](https://coil.com/oauth_register) on their site, make a one-off API request to get a key, and implement your own backend (to securely access Coil with a secret key) as well as your frontend to present a button and deal with various redirects as part of the OAuth authentication.

Thanks to funding from Grant for the Web, we were able to add Web Monetisation support to our low-code tool, Kendraio App, which enables users to make data-driven apps with custom workflows. [Kendraio](https://www.kendra.io) is a non-profit organisation and all our code is [open-source](https://github.com/kendraio/kendraio-app), so you may benefit if you're implementing your own Coil [login](https://github.com/kendraio/kendraio-app/blob/develop/src/app/blocks/web-money/web-money.component.ts)  [integration](https://github.com/kendraio/coil-api-proxy).

Maybe you have some content you want to monetise with Coil or maybe you have already monetised and want to provide users with access to content they've already paid for with Coil. Either way, if you're interested in making this content available and monetisable without your users needing to depend on a particular browser or browser extension, then you may find this technical guide useful. 

Step 1 - Request access and provide resources
=============================================

As outlined by [Coil themselves on their docs](https://help.coil.com/docs/dev/oauth-api), the first step is to make a Coil account.

After making an account, email the Coil developers with your use-case so they can approve your use of their API. Once approved, you'll need to register your app or website by providing them with a link to your logo, privacy policy, terms of service, and a list of URLs your users may be redirected to after logging in with Coil.

A word of warning: As there does not appear to be an easy way to change the list of URLs later, ensure you have a development URL or two set aside. This might be a staging URL and a localhost URL. Without this, testing the login flow could be a lot more clunky, so it's worth having a good think about what URLs you will need ahead of time.

Once you've sent the form, you should be emailed a registration access token that you can use once to get a secret key. This key is needed to connect your users to their Coil accounts and the Coil API for each subsequent login.

I used the Insomnia web client to make this POST request to their API at <https://coil.com/oauth/reg> and it returned a pretty printed JSON response containing the OAuth secret key and other info. Another option is to use a curl command directly or from Postman. Be careful to store the key securely, as you only get it once and it is used for potentially sensitive activity, such as moving money around and accessing user account info.

Step 2 - Create Backend API
===========================

Now that you have the key, it can be used by a login backend. The backend must use the key to verify you are who you say you are, to complete OAuth login attempts for your users.

We used Vercel, a serverless (think Lambda) platform, to make our backend API. Vercel has a way of securely storing environment variables that must be manually selected. Other backend solutions have different options for secrets managers.

After the user visits a Coil login URL and has been redirected back to your site with the OAuth access code parameter, your backend API will need an endpoint that accepts the OAuth access code and returns a Bilateral Transfer Protocol token.

 This is done by using the users OAuth code, and the secret OAuth key to request an OAuth session token from Coil's API. Once you have it, the session token is used to request the BTP token, which finally is returned to the browser. This must be done in a backend to prevent exposure of the secret OAuth key from Coil.

You can [see our backend API implementation here](https://github.com/kendraio/coil-api-proxy/blob/main/pages/api/login.js), and [our frontend button that calls it is here](https://github.com/kendraio/kendraio-app/pull/160/files#diff-4ab6f1f490848ff5026a4b6fe621fa09bcbf9abb1ad007c0ff270d029568a8b2R76).

Step 3 - Integrate frontend 
============================

A unique ID is needed for each OAuth session, and a UUID generator is a good way to create one. Our frontend does this and combines it together with other URL parameters to generate a login button link to Coil.

After the user clicks the link and approves your app's access to Coil, the user should be redirected back to the URL specified by you, with a token parameter. You'll need to send this token to your backend, and get a BTP token back for the user.

Step 4 - PROFIT!
================

Once we have a BTP token for a user, it's possible to start streaming payments using the Web Monetization protocol! Thankfully, [Coil provides a script](https://help.coil.com/docs/dev/oauth-web-monetization-script) that can speak this protocol and stream money! Now that the user is finally authenticated and in possession of a BTP token, we can provide the Coil script with the token. The script, like the browser extension, checks the webpage for a payment pointer meta tag. With an active BTP token, as soon as the Coil script finds the meta tag, the payment stream should start.

Initial setup cheat sheet
-------------------------

1. Manually make a Coil account for the organisation

2. Email <devs@coil.com> with your use case 
 - E.g. OAuth login is needed to support users without the browser extension)

3. Fill out the OAuth registration form
  -  At <https://coil.com/oauth_register> provide Coil with your logo, privacy policy, TOS, what URIs Coil is allowed to redirect to (don't forget production, dev and localhost URLs!) Then wait for the REGISTRATION_ACCESS_TOKEN to be emailed to you

4.  OAuth registration API
 -   Use the REGISTRATION_ACCESS_TOKEN to register with the OIDC provider to get your client_id and client_secret by manually make a POST request to <https://coil.com/oauth/reg> (with a lot of the same info as the prior registration step)

Login flow cheat sheet
----------------------

1.  We generate a random session ID

2.  We assemble an OAuth login URL by adding a few parameters to <https://coil.com/oauth/auth>: client_id, session ID and a callback URL (e.g. hosted at localhost for testing, or your domain)

3.  User presses a login button  and visits the generated login URL

4.  User returns at the callback URL, with an OAuth access code parameter from Coil (and session ID) added

5.  POST the access code to our secure backend. Our own API then talks to Coil's API to:
 -   get an OAuth token from https://coil.com/oauth/token using the user's access code and our secret key (from our secrets store)
 -   use the OAuth token to get the Bilateral Transfer Protocol token for the user via <https://api.coil.com/user/btp>
  -   return the BTP token to the browser for the next step

6.  A Coil Web Monetization client is run via a script and is provided with the BTP token

7.  When a metatag with a payment pointer is detected, the payment stream can start (and works much like the Coil extension)

Kendraio Player block integration
=================================

Kendraio App, a low-code dashboard creator, helps build interfaces using Flows that connect to APIs with minimal code needed. We created a player workflow in the app and integrated a Coil login within Kendraio Player. We have a [simplified player workflow example](https://app.kendra.io/player/basic) of how to use the audio player block and a "Web Money" block. It uses JSON data provided by a mapping block:

```js
{
  "display_artist": "Patient Pacifist",
  "display_title": "Divided",
  "url": "https://dsp1-track-uploads.s3.amazonaws.com/auth0|5fa9852a2576900076396b60/b49cd51b-6f0a-4c7a-9c69-b83b753ee867",
  "paymentPointer": "$ilp.uphold.com/QhJqdGMmjZM4"
}
```

Then, below, we have a block that configures the audio player with JSON:

```js
{
   "type": "player",
   "onPlay": [
       {
           "type": "web-money"
       }
   ],
   "onPause": [
       {
           "type": "web-money",
           "enabled": false
       }
   ]
}
```

See [here for an introduction to Kendraio](https://app.kendra.io).

Don't forget to check out our [latest bounty](https://github.com/kendraio/kendraio-app/issues/169)!

That's enough for now!


*Kendraio App is a project by [Kendraio](https://www.kendra.io), the interoperability advocacy initiative. Kendraio App is an open-source dashboard application currently focused on music/media creators, copyright and related rights owners. The app was developed to investigate how the transformative benefits of interoperability can improve existing processes — and to demonstrate how they can impact business, personal and public life.
[Subscribe to the Kendraio newsletter here](https://www.kendra.io/user/register).*