Monetize the Command Line with Bitcoin

Posted by John Granata, Ronak Mehta

Monetize the Command Line with Bitcoin

Overview

This tutorial illustrates how to build an entirely new class of applications: command line tools that use a little bit of bitcoin to pay a remote server for computation.

We illustrate the class of applications by showing you how to build a simple, bitcoin-payable command line tool called geocode-client. The tool takes in an address string like "1600 Pennsylvania Avenue" as an argument. Behind the scenes, it then pays a bit of mined bitcoin to a geocode API server hosted using 21 to map this string to a latitude and longitude.

Why is this interesting? It essentially lays the groundwork for a new kind of Linux distribution, one that bundles dozens or hundreds of these tools and that is thereby dependent on the presence of bitcoin as the next fundamental system resource alongside RAM and disk space. It also means that the developers who build these new bitcoin-payable command line apps could now actually monetize every single invocation of their tools, should they become popular.

But let's jump into the example and then return to these points.

Prerequisites

Install 21

You will need the following items:

  • Either a 21 Bitcoin Computer or 21
  • The latest version of the 21 software, obtained by running 21 update

If you've got all the prerequisites, you are ready to go. Let's get started!

Step 1: Install the dependency

You will also need to install the Google Maps python library. Do this with:

sudo pip3 install googlemaps

Step 2: Create a Google Developer account and obtain a key for the Google Maps-Geocode API

Go to the Google Developers Console and create an account. Click on Dashboard on the left-hand side of the window and select Enable and manage APIs. From the Google Maps APIs category select Google Maps Geocoding API. Select the Enable API button on top and then click on the Credentials option on the left-hand side. Click on Add credentials drop down button and select API key. A pop-up window with different key options will show up. Select Server key. In the new window enter the name of your project that this key will be stored under and click on the Create button. Take note of your API key once it is created.

NOTE: Google requires a user to enter billing information in order for the API key to work. You will need to add your billing information in order to use the API key you just created above. Google will not charge your card if you set up the free account.

In the Google Developers Console window click on the Products & Services menu option that is represented as 3 horizontal white dashes. Select Billing from the options shown in the drop-down menu and enter your billing information.

You are now ready to use your Google Geocode API key. Let's set up a bitcoin-payable micropayments server that our CLI tool will call in order to access the Google Maps-Geocode REST API.

Step 3: Create a server that maps addresses to latitude/longitude

Open up a new terminal window. If you use a 21 Bitcoin Computer, ssh into it:

## Only necessary if you use a 21 Bitcoin Computer
ssh twenty@IP_ADDRESS

Create a folder for your project:

mkdir geocode-server && cd geocode-server

Set an environment variable that defines your newly created Google Maps-Geocode API key:

export GOOGLE_MAPS_API_KEY=<enter your API key here>

Now create a file named geocode-server.py and add the following code:

import os
import json
import googlemaps
from flask import Flask, request

# import from the 21 Developer Library
from two1.wallet import Wallet
from two1.bitserv.flask import Payment

# set up server side wallet
app = Flask(__name__)
wallet = Wallet()
payment = Payment(app, wallet)

# create a developer account on Google and obtain a API key for the maps-geocode app
gmaps = googlemaps.Client(key=os.environ.get('GOOGLE_MAPS_API_KEY'))


# create a 402 end-point that accepts a user's input address and returns the lat/long
@app.route('/geocode')
@payment.required(3000)
def geo():
    """Map input address given as a string to (latitude, longitude)."""

    # Define a dict variable to store latitude & longitude
    coords = {}

    # Get user's input address
    address = request.args.get('address')

    # Send a request to Google's Map-Geocode REST API using your API credentials defined above
    geocode_result = gmaps.geocode(address)

    # Check to see if the result is valid
    if geocode_result.__len__() == 0:
        return "The input address is invalid."
    else:
        # Obtain Lat & Long from result
        coords['latitude'] = geocode_result[0]['geometry']['location']['lat']
        coords['longitude'] = geocode_result[0]['geometry']['location']['lng']

        # Return co-ordinates back to the user
        return json.dumps(coords)

if __name__ == '__main__':
    app.run(host='::', debug=True)

Start the server with:

python3 geocode-server.py

Step 4: Wrap the server into a bitcoin-payable command line tool

Open up a another new terminal window. If you use a 21 Bitcoin Computer, ssh into it:

## Only necessary if you use a 21 Bitcoin Computer
ssh twenty@IP_ADDRESS

Create a folder to house the client project:

mkdir geocode-client && cd geocode-client

Install the Click python package for creating command line interfaces:

sudo pip3 install click

Now create a file named geocode_client.py in this directory and open it in an editor. Add the following code:

import json
import click

# import from the 21 Developer Library
from two1.wallet import Wallet
from two1.bitrequests import BitTransferRequests

# set up bitrequest client for BitTransfer requests
wallet = Wallet()
requests = BitTransferRequests(wallet)

# server address
server_url = 'http://[::1]:5000/'


@click.command()
@click.argument('address')
def cli(address):
    """Call the geocode api hosted on the micropayments server"""

    sel_url = server_url+'geocode?address={}'
    response = requests.get(url=sel_url.format(address))
    if response.text == "The input address is invalid.":
        click.echo(response.text)
    else:
        coords = json.loads(response.text)
        click.echo(coords)

Save this file and close it. Create a file called setup.py and open it in your text editor. Add the following code:

from setuptools import setup

setup(
    name='geocode-client',
    version='0.1',
    py_modules=['geocode-client'],
    install_requires=[
        'Click',
    ],
    entry_points='''
        [console_scripts]
        geocode-client=geocode_client:cli
    ''',
)

Save and close the file. Run the following command:

sudo pip3 install --editable .

Now you can try out your bitcoin-payable CLI tool!

geocode-client "<Address to search>"

As an example:

geocode-client "1600 Pennsylvania Avenue"
{"lat": 39.754053, "lng": -75.563814}

Next Steps

This is a simple application, but the concept is much bigger. We think of this as a much more fine-grained way to do Software-as-a-Service (SAAS). The success of SAAS web applications over the last decade for everything from analytics to sales to data analysis to human resources has been indisputable, but each new web service requires a credit card signup and isn't necessarily interoperable.

We think the concept of command-line SAAS with bitcoin changes all that.

As a developer, once you have a universal way to pay for each command line invocation, you can (a) sign up for new SAAS services by invoking a single command and (b) quickly string them together by piping the JSON output of one SAAS service into another.

As an entrepreneur, the reason we think of this as "fine-grained" SAAS is that you no longer need to set up a full web app to start getting SAAS customers. You just need a bitcoin-payable API that exposes a single function and a corresponding command line client. Now anyone with bitcoin can easily try your API out and integrate it into their toolchain.

We think the long-term implications of this for independent software development and the Unix ecosystem could be profound. Developers can now release free command line tools that have a bitcoin-billable server-side component. They can choose to set up whatever kind of billing policy they want, whether simple pay-per-use or more complex freemium models (eg making the tools free for the first few invocations and then charging for subsequent uses).

Over time, this leads to a new kind of Bitcoin-focused Linux distribution: one that has a group of tools with some server side component that require some bitcoin on the machine to operate. As a first version of this, as you build new tools of this kind make sure to post them in our Slack community. After review, we'll be bundling user-submitted command line SAAS tools in the next 21 update, to make them accessible to all the 21 Bitcoin Developers.


How to send your Bitcoin to the Blockchain

Just as a reminder, you can send bitcoin mined or earned in your 21.co balance to the blockchain at any time by running 21 flush . A transaction will be created within 10 minutes, and you can view the transaction id with 21 log. Once the transaction has been confirmed, you can check the balance in your bitcoin wallet from the command line with wallet balance, and you can send bitcoin from your wallet to another address with wallet sendto $BITCOIN_ADDRESS --satoshis $SATOSHI_AMOUNT --use-unconfirmed. The --satoshis flag allows you to specify the amount in satoshis; without it the sendto amount is in BTC, but this behavior is deprecated and will be removed soon. The --use-unconfirmed flag ensures that you can send even if you have unconfirmed transactions in your wallet.


Ready to sell your endpoint? Go to slack.21.co

Ready to try out your bitcoin-payable server in the wild? Or simply want to browse and purchase from other bitcoin-enabled servers? Head over to the 21 Developer Community at slack.21.co to join the bitcoin machine-payable marketplace hosted on the 21 peer-to-peer network.