6 min read

Building a Bitcoin-Powered Donation System for Satoshi Radio: The Journey and Tech Behind It

I experiment with Bitcoin's many components a lot, and when I learned about Bart's idea to start receiving podcast donations using his own Raspberry Pi, I reached out to him to see if I could help out. Together we created the world's first Bitcoin-only podcast donation system.
Building a Bitcoin-Powered Donation System for Satoshi Radio: The Journey and Tech Behind It

Satoshi Radio is a weekly podcast about Bitcoin & Cryptocurrencies from The Netherlands. In Dutch, they discuss recent news, new technologies, and other events around Bitcoin as a whole.

At the beginning of 2020, the podcast host, Bart, decided to set up his first node. The reason to do this was simple: to have skin in the game. Since Bart is not a programmer, he used the all-in-one software MyNode. MyNode is node software that runs on a Raspberry Pi and includes extra tools like BTCPay Server, Mempool explorers, and Lightning wallets. After the node was synced, the community started the idea to raise donations using BTCPay Server. I helped set up the initial minimum viable product: a donation button that could be reached via the website. 

The MVP was a success, so Bart and I sat together to discuss the next steps. The first ideas that came to mind were an aesthetically pleasing donation button on the website, a Telegram donation bot, and a database including all relevant donation information. The question became if we should create this ourselves or make use of third-party services. In their rapid growth last year, the question arose how they could connect with their community while also creating a steady stream of income more efficiently.

Donations often consist of multiple smaller amounts from all over the world. Numerous companies exist, acting as payment gateways, each providing multiple features and possibilities specifically tailored to podcasts. However, being a podcast about Bitcoin, it would make sense to receive donations in Bitcoin.

Satoshi Radio is an advocate of “being your own bank.” All it takes is a Raspberry Pi computer to bootstrap yourself to the network. No middleman, no companies in between. You're participating directly as a peer in the massive peer-to-peer network of Bitcoin nodes.

Bitcoin enables merchants to set up their self-owned payment terminal without complex models run by organizations, taking a cut from your cash flow. Since Bitcoin is borderless and trustless, one could receive Bitcoin from the other side of the world in mere moments.

Since I'm actively involved in all things related to Bitcoin, I experiment with its many components. I learned about Bart's idea to start receiving donations using his own Raspberry Pi, and I reached out to him to see if I could help out. We wanted to create a tightly integrated system. Together we created the world's first Bitcoin-only donation system.

This post is an effort to detail which components we set up and how they technically interact. 

The Bitcoin Lightning network

The lightning network is a second-layer technology applied to Bitcoin that uses micropayment channels to scale its blockchain to conduct transactions more efficiently. Just recently, a member from Satoshi Radio's community transferred proximately € 9000,00 over the Lightning network. It took about one minute, was confirmed virtually instantaneously, and only cost 0.12% (~€10,00). 

With most of Satoshi Radio's listeners running their own nodes and actively participating in the Bitcoin Network themselves, they are also directly hooked into the Lightning Network. For the ones that rather not, there are also custody solutions available.

BTCPay Server

From the website: “BTCPay Server is a self-hosted, open-source cryptocurrency payment processor. It's secure, private, censorship-resistant, and free.”

BTCPay Server comes as a collection of Docker containers (little pieces of isolated, running software) that handle all things related to payment processing:

  • The Bitcoin Deamon connects directly into the base layer of the Bitcoin Network, validating transactions, redistributing them into the peer-to-peer network, and also sending transactions of its own;
  • The Lightning Deamon (LND) is for hooking into the second layer solution, The Lightning Network. It's connected to the peer-to-peer network, receiving and sending payments to other connected Lightning nodes. LND uses the Bitcoin daemon to construct payment channels and ultimately settle their balances by closing them;
  • A block explorer (NBXplorer) for indexing the network's transactions, allowing for quick access to certain information like an address's balance;
  • A database server (PostgreSQL) for storing information related to the merchant, like store data, information about the paying entity, and invoices.

BTCPay Server comes with a lot more optional add-ons, but they fall outside of the scope of this post.

The donation application, an overview

Technical overview of the available donations flows.

The application is custom-written software, set up using PHP and Symfony. It exposes several HTTPS endpoints that are called by BTCPay Server when events happen. Communication between the application and BTCPay Server is secured by using client & server SSL certificates.

When a donation is received, several processes start to move;

  • Its value in EUR is determined using the CoinRanking API;
  • The podcast hosts, Bart, Peter & Bert, are notified of the incoming donation;
  • The public Telegram channel is notified of the incoming donation;
  • Information about the donation is stored in a PostgreSQL database. This includes origin, the amount in euro & satoshis at the time of donating.

Registration is done so the system can generate a tax report of all donation-related income.

The Telegram community

Here's how a donation(in Dutch) looks in the public community channel

The community is where it's at. At the time of writing, there are 2.270 members in Satoshi Radio's chat. There's always something happening here, whether it's a friendly chat, serious discussion about Bitcoin, or miscellaneous life-related topics. I used to follow closely during the bear market of 2018/2019, but it's so high-volume now I usually cherry-pick only certain discussions.

As soon as a payment comes through, the application posts a prominent message for everyone to see. Bart quite suitably chose Igor Bogdanoff's “Pamp it” meme as the bot's profile picture. 

The message holds just three basic things: The name, how much was donated, and a custom greeting or message. Typically, donations contain questions that spark interesting discussions amongst members. Ultimately, when the donation gets read aloud on the show, the hosts go in-depth on the subject. Of course, we show the Satoshi value of the donation first; Sats the standard.

The donation bot

The application continuously polls the Telegram API to check if there are new messages. It does so using this iteration function:

protected function loop($lastUpdateId = null): void
{
    // [...] irrelevant code

    $updates = $this->api->getUpdates($updatesMethod);

    foreach ($updates as $update) {
        try {
            switch ('private' === $update->message->chat->type) {
                case 'private':
                    $account = $this->createOrFetchAccountForTelegramUser($update);
                    $event = new TelegramPrivateMessageUpdateEvent($update, $account);

                    break;

                default:
                    continue 2;
            }

            $this->dispatcher->dispatch($event);
        } catch (Throwable $exception) {
            // [...] error handling
        }

        $lastUpdateId = $update->updateId + 1;
    }

    $lastUpdate->setValue($lastUpdateId);
    $this->entityManager->persist($lastUpdate);
    $this->entityManager->flush();

    // restart the bot loop after an hour to prevent memory leaks
    if (time() > ($this->start + 3600)) {
        $this->logger->info('bot poll cycle! (1 uur cutoff)');

        return;
    }

    $this->loop($lastUpdateId);
}

I put together a framework within the application for consuming various telegram commands, each triggering different behavior.

The Satoshi Radio website

Though there's a vibrant community using Telegram, initially, we launched donations only on the website. Visitors can input their name, the amount they wish to donate, and a friendly message to the community and the hosts.

Building upon the earlier created framework

class DonationPaidEvent extends Event
{
    protected Donation $donation;

    public function __construct(Donation $donation)
    {
        $this->donation = $donation;
    }

    public function getDonation(): Donation
    {
        return $this->donation;
    }
}

The application is built using numerous events, triggers, and listeners. When we want to expand on some behavior, all it takes is hooking into an already available event source and create our feature. We recently added a feature to print receipts to be read aloud in the show as soon as a donation comes in—a really cool way of connecting the digital with the physical.

Conclusion

It's been just over a year since I created the first iteration of the donation system. Since then, the system has processed over 1.000 donations, totaling nearly 0,25 BTC, worth almost $12.000 against today's prices. It's been rock-solid all this time and has significantly increased the strength of Satoshi Radio's community while boosting the podcast's income stream.

As it turns out, cutting out the middleman and utilizing Bitcoin's full potential opens up a lot of (cashflow) potential for creative people. All components and software used are free and open-source; it only took some software glue to connect the already readily available components.

I had a lot of fun creating this project. If you need me to help out with your next idea, view my services or contact me!