hackathon

Building a Tipping Platform with Bitnob API

Precious Ndubueze
5 min read
Building a Tipping Platform with Bitnob API

What Does DCA Mean To You? To me, DCA means saving towards a goal through gradual but consistent accumulation.

Quick SummaryIn our modern world, being able to reward people you admire, friends or family has been seen as a major improvement in Fintech.With the introduction of the lightning network, being able to send bitcoin with great speed has improved transfers and transactions with bitcoin. Bitnob just announced its integration of the lightning network to provide fast bitcoin transactions for its users and African businesses.In this tutorial, we will build a tipping platform that allows you to tip business users on the lightning network and we will be building on the Bitnob API.This tutorial has a hosted frontend and API. While testing, use the following emails; precious@bitnob.com and bernard@bitnob.comWhat is the Bitnob API?The Bitnob API is a business API built to help businesses provide Bitcoin access to their customers.It comes with these features:

• Lightning

• Bitcoin backed Loans (NobCredit)

• Onchain TransactionsWe will be building with some actions of the Lightning and Onchain feature. Check out the docs to read more.Getting StartedTo get started with the tutorial, register as a business on the sandbox version. This will give you access to the API keys you need for integration.Set up your business information. You can skipAfter this step, visit setting under account to get your API key.You’re good to go!DevelopmentTo build our API, We will be working with the following dependencies:

• Python 3.6+

• FastAPI

• Bitnob API

• Bitnob python SDKScaffold ProjectWe will create a new directory to house our application$ mkdir tipping-platform\n$ cd tipping-platformTo start building, the first step is to create and activate a virtual environment for our project:$ python3 -m venv venv\n$ source venv/bin/activateThe next step is to install Bitnob and FastAPI$ pip install bitnob fastapi[all] dotenvThe bitnob package is a python SDK that comes with pre-built actions that allow businesses to interact better with the Bitnob API. They are also available SDKs for several languages.Setting Up Entry FileEvery application has an entry file from which every functionality is exposed. create a new file, main.py and set up FastAPI.$ touch main.py#main.py\n\nfrom fastapi import FastAPI\napp = FastAPI()\n\n@app.get(\"/\")\nasync def root():  \n\treturn {\"message\": \"Tipping Platform\"}run $ uvicorn main:app --reloadSet Up Env KeysWe have to set the env keys to run our SDK and bitnob API successfully. The BITNOB_PRODUCTION is set to False when running on sandbox and True when running on production. While the BITNOB_API_KEY is your API key from the dashboard.For app, add the following to your .env file, at the root of your application.BITNOB_API_KEY=sk.bc987.XXXXXXXXXXXXXXXXXXXXX\nBITNOB_PRODUCTION=FalseRunning our app without adding the BITNOB_API_KEY will throw a BitnobBadKeyError() error. Not setting BITNOB_PRODUCTION to False or not setting at all, makes it run on Production mode.Tipping ClassWe will be creating a Tipping class that performs all actions of our tipping platform.$ mkdir src\n$ touch __init__.py\n$ touch src/tip.pyWe are to create a source folder for our application src, this will house our Tipping class, schemas and routers.The next step is to create a file tip.py for the Tipping class.For our API we will be using the Customer, Lightning and Onchain functions from the bitnob packagefrom dotenv import load_dotenv\nfrom bitnob import Customer, Lightning, Onchain\n\nload_dotenv()\n\ncustomer = Customer()\nlightning = Lightning()\nonchain = Onchain()load_dotenv() imports our env keys into the environment.For our Tipping class we need the following actions;

• Get a user

• Tip User, this consists of two sub-actions; create Lightning invoice for a user ands create BTC Address for userclass Tipping:\n  def __init__(self):\n  \tpass\n\n  def get_user(self, email):\n    user = customer.get_customer_by_email(email=email)\n    return user\n\n  def create_lightning_invoice_for_user(self, email, sats):\n    payload = {\n    \"description\": \"money stops nonsense on sunday\",\n    \"tokens\": sats,\n    \"private\": False,\n    \"is_including_private_channels\": False,\n    \"is_fallback_included\": False,\n    \"customerEmail\": email\n    }\n    data = lightning.create_invoice(body=payload)\n    return data\n\n  def generate_btc_address_for_user(self, email, label):\n    payload = {\n    \"label\": label,\n    \"customerEmail\": email,\n    }\n    data = onchain.generate_address(body=payload)\n    return data\n\n  def tip_user(self, sats, email, label):\n    invoice = self.create_lightning_invoice_for_user(email=email,\n    sats=sats)\n    address = self.generate_btc_address_for_user(email, label)\n    data = {\n    \"address\": address[\"data\"][\"address\"],\n    \"invoice\": invoice[\"data\"][\"request\"],\n    }\n    return data\n    The get_user() function uses the email to call the customer .get_customer_by_email() function, it returns an error that the user isn’t found or the data of the user.create_lightning_invoice_for_user() and generate_btc_address_for_user() creates a lightning invoice and BTC address for the user respectively. The invoice works with the sats passed but the address from the BTC can take in any amount.Finally, the tip_user() takes the data returned and gets the address from generate_btc_address_for_user() and request from the create_lightning_invoice_for_user().Schema and RoutingSchemaOur schema is needed for our get_user and create_tip endpoint. The pydantic schemas check the data being passed to the endpoint and ensures it has the passed keys and correct format.$ touch src/schema.py#schema.py\n\nfrom pydantic import BaseModel\nfrom typing import Optional\n\nclass Tip(BaseModel):\n  email: str\n  description: Optional[str] = None\n  sats: float\n  label: str\n\nclass User(BaseModel):\n  email: strThe Optional class sets the description key to unrequired, so it doesn’t throw an error when not passed.RoutingAt this point, we will connect our functions to endpoints$ touch src/routes.py#src/routes.py\n\nfrom fastapi import APIRouter\nfrom .tip import Tipping\nfrom .schema import *\n\nrouter = APIRouter()\ntip = Tipping()\n\n@router.post(\"/create_tip/\")\nasync def create_tip(tip_data: Tip):\n  return tip.tip_user(sats=tip_data.sats, email=tip_data.email,\n  label=tip_data.label)\n\n@router.post(\"/get_user/\")\nasync def get_user(user: User):\n\treturn tip.get_user(user.email)The next step is to add the router to the app in main.py#main.py\n\nfrom src.routes import router\n\n@app.get(\"/\")\nasync def root():\n  return {\"message\": \"Tipping Platform\"}\n\napp.include_router(router)Tipping UserWe are done with building our API, we will be testing our application by trying the API on its docs. Get the app running;$ uvicorn main:app --reloadvisit http://127.0.0.1:8000/docsThis will return an address and lightning invoice for the user;ConclusionNow users on your business can be tipped just using their email. And using the lightning network it gets to them in seconds!There are lots of possibilities that can be built the Bitnob API for businesses.