# Micropayments in Action

Canonical: https://docs.projectbabbage.com/docs/quickstarts/micropayments-in-action

Walkthrough of how to leverage BSV’s unique micropayment capabilities, covering real-world applications, key BRC standards, and best practices to help developers integrate fast, low-cost payments into their services or products.

Below is an example tutorial that walks you through integrating **@bsv/auth-express-middleware** and **@bsv/payment-express-middleware** in an Express application for micropayments, and then shows how to call that API from a client using the **AuthFetch** client. In this sample use-case, you’ll create a simple “premium” API endpoint that costs a small fee in satoshis. The server will automatically enforce authentication and micropayment collection, and you can then view and manage those payments with the [Wallet UI admin panel](https://wui.bapp.dev).

> **First-run note:** This is a real payment-middleware tutorial. It requires a server wallet root key, wallet storage, and funded wallets. If you want the no-spend 402 flow first, run the maintained starter at [use.bsv.tools](https://use.bsv.tools/) before using this page.

---

## 1. Overview

### What You’ll Build
- **Server (Express)**:
  - *Auth middleware* ensures only authenticated users can even invoke your endpoint.
  - *Payment middleware* charges the user a small micropayment (in satoshis) whenever they call your endpoint.
  - A *backend wallet* (using `@bsv/wallet-toolbox`) collects and manages these micropayments automatically.

- **Client**:
  - *User’s wallet* is installed locally (e.g., the [BSV Desktop](https://desktop.bsvb.tech/) or another BRC-100–compatible wallet).
  - *AuthFetch library* automatically handles authentication (BRC-103 handshake) and responds to `402 Payment Required` from the server, paying the required satoshis if the user agrees.

### What You’ll Need
- Node.js environment
- An existing BSV private key for your server or create one (64 hex chars, 256-bit). This is the server’s “wallet root key.”
- Access to the [Babbage wallet storage service](https://storage.babbage.systems/) or your own self-hosted storage.
- A local BSV wallet on the client side, such as the [BSV Desktop](https://desktop.bsvb.tech/).
- Some BSV in your server’s wallet (and in your user’s wallet) to handle small fees.

---

## 2. Setting Up the Server

Below is a simple Express server named `server.ts`. It uses:

- `createAuthMiddleware` from **@bsv/auth-express-middleware**
- `createPaymentMiddleware` from **@bsv/payment-express-middleware**
- A server-side wallet from **@bsv/wallet-toolbox** to both authenticate routes and receive micropayments.

### 2.1 Install Dependencies

```bash
npm install express body-parser dotenv
npm install @bsv/auth-express-middleware @bsv/payment-express-middleware
npm install @bsv/wallet-toolbox
```

### 2.2 Server Code (server.ts)

```ts
import express, { Request, Response, NextFunction } from 'express'
import bodyParser from 'body-parser'
import { Setup } from '@bsv/wallet-toolbox'
import { createAuthMiddleware } from '@bsv/auth-express-middleware'
import { createPaymentMiddleware } from '@bsv/payment-express-middleware'

// Optionally load environment variables from a .env file
import dotenv from 'dotenv'
dotenv.config()

// Your environment variables:
const {
  SERVER_PRIVATE_KEY = 'YOUR_64_CHAR_HEX_PRIVATE_KEY',
  WALLET_STORAGE_URL = 'https://storage.babbage.systems',
  BSV_NETWORK = 'main',
  HTTP_PORT = 8080
} = process.env

async function main() {
  // 1) Create the Express app
  const app = express()
  // 2) Use body-parser to parse JSON request bodies
  app.use(bodyParser.json({ limit: '1mb' }))

  // 3) Create a server wallet (the “payee” server) using @bsv/wallet-toolbox
  const wallet = await Setup.createWalletClientNoEnv({
    chain: BSV_NETWORK as 'main' | 'test',
    rootKeyHex: SERVER_PRIVATE_KEY,
    storageUrl: WALLET_STORAGE_URL
  })

  // 4) Auth Middleware: If "allowUnauthenticated" is false, server requires authentication for all routes.
  app.use(
    createAuthMiddleware({
      wallet,
      allowUnauthenticated: false,  // require BRC-103-based mutual auth
      logger: console,              // optional logging
      logLevel: 'info'
    })
  )

  // 5) Payment Middleware: Automatically responds with 402 Payment Required if user doesn't include micropayment
  app.use(
    createPaymentMiddleware({
      wallet,
      calculateRequestPrice: async (req: Request) => {
        // Basic example: a flat 5 satoshi charge:
        return 5
      }
    })
  )

  // 6) Example route: A “premium” endpoint that costs 5 satoshis per request
  app.get('/api/premium', (req: Request, res: Response) => {
    // By the time code reaches here:
    // - The user is authenticated
    // - The micropayment for 5 satoshis is validated & confirmed (server has the transaction)
    return res.json({
      status: 'success',
      message: 'Hello from your premium endpoint!',
      yourCostInSats: 5
    })
  })

  // 7) Start listening
  app.listen(HTTP_PORT, () => {
    console.log(`Micropayment API listening on port ${HTTP_PORT}`)
  })
}

main().catch(err => {
  console.error('Failed to start server:', err)
})
```

### 2.3 Explanation

1. **Wallet Setup**:
   You create a server wallet by providing:
   - a root key (`SERVER_PRIVATE_KEY`)
   - a chain (e.g. `main` or `test`)
   - a storage URL (`WALLET_STORAGE_URL`)

2. **Auth Middleware** (`createAuthMiddleware`)
   This enforces that only BRC-103–authenticated users (using mutual auth) can access your endpoints.

3. **Payment Middleware** (`createPaymentMiddleware`)
   Checks each incoming request:
   - Decides how many satoshis are required (via `calculateRequestPrice`).
   - If the user didn’t provide a valid micropayment in the request, it sends back `402 Payment Required`.
   - If they *did* pay, the server’s wallet processes the transaction.

4. **Endpoint**:
   You expose a route `GET /api/premium`. Anyone hitting that route must (1) authenticate and (2) pay 5 sats. Success means you respond with the resource or data they paid for.

---

## 3. Using AuthFetch on the Client Side

Users must have a local wallet installed, but your front-end can automate requests with the combination of `WalletClient` + `AuthFetch`. When the server says “402 Payment Required,” `AuthFetch` automatically builds a payment transaction using the user’s local wallet and re-sends the request.

### 3.1 Install the @bsv/sdk

On your front-end or client environment:

```bash
npm install @bsv/sdk
```

### 3.2 Client Side Example (auth-fetch-demo.js)

Below is a small snippet illustrating how to call the protected endpoint using `AuthFetch`.

```js
import { AuthFetch, WalletClient } from '@bsv/sdk'

async function callPremiumEndpoint() {
  try {
    // 1) Connect to the local BRC-100 wallet using automatic substrate detection
    const wallet = new WalletClient('auto')

    // 2) Create an AuthFetch instance
    const client = new AuthFetch(wallet)

    // 3) Attempt our Premium GET request
    const response = await client.fetch('http://localhost:8080/api/premium', {
      method: 'GET'
    })

    // 4) Parse server result
    const result = await response.json()
    console.log('Server result:', result)
  } catch (error) {
    console.error('Failed to call premium endpoint:', error)
  }
}

callPremiumEndpoint()
```

#### How It Works
1. `AuthFetch` tries the request. The server sees no micropayment yet, responds with `402 Payment Required`.
2. `AuthFetch` notices the `402` and automatically constructs a BSV transaction paying the required satoshis to the server’s derived address.
3. `AuthFetch` re-sends the request with the `x-bsv-payment` header plus the transaction.
4. The server verifies the micropayment, sees user is authenticated, and grants access to `/api/premium`.

No boilerplate of building the transaction directly is needed on the front end—`AuthFetch` + `WalletClient` do it all for you.

---

## 4. Viewing & Managing Payments in the Admin Panel (WUI)

Your server wallet from `@bsv/wallet-toolbox` is accessible in (at least) two ways:

1. **API**:
   - You can perform advanced operations: query the wallet, list actions, sign transactions, etc.

2. **Web UI**:
   - **[https://wui.bapp.dev](https://wui.bapp.dev)**
   - Or [run it from source](https://github.com/bsv-blockchain/wui) yourself
   - Choose “Add New,” supply your server’s root key and correct storage URL.
   - The admin panel will load your wallet data, let you see all micropayments received, show any unspent outputs, etc.

By monitoring the wallet with the WUI, you can confirm you’re indeed collecting those 5-satoshi fees from each client request.

> **Tip**: In a real-world scenario, you’ll often want to keep your wallet’s root key secure. You can optionally split it or require multiple factors. For demonstration and development, though, simply import the root key into the WUI for quick management.

---

## 5. Tangible Example: “Paid Weather Data” Endpoint

Below is a more fleshed-out (though simplified) example scenario:

1. **Goal**: Provide a “/weatherStats” endpoint that returns special data behind a micropaywall.
2. **Selling**: Users pay 1 sat to get your exclusive weather data.
3. **Authenticating**: They must also be BRC-103–authenticated (no account/password needed, just their wallet).

**Server (snippet)**

```ts
import express, { Request, Response } from 'express'
import bodyParser from 'body-parser'
import { Setup } from '@bsv/wallet-toolbox'
import { createAuthMiddleware } from '@bsv/auth-express-middleware'
import { createPaymentMiddleware } from '@bsv/payment-express-middleware'

async function startServer() {
  const app = express()
  app.use(bodyParser.json())

  const wallet = await Setup.createWalletClientNoEnv({
    chain: 'main',
    rootKeyHex: process.env.SERVER_PRIVATE_KEY,
    storageUrl: 'https://storage.babbage.systems'
  })

  app.use(createAuthMiddleware({ wallet, allowUnauthenticated: false }))
  app.use(createPaymentMiddleware({
    wallet,
    calculateRequestPrice: async () => 1 // Just 1 sat per request!
  }))

  app.get('/weatherStats', async (req: Request, res: Response) => {
    // The user is authenticated and has paid 1 sat
    // This is the part where you get creative: plug in your IoT home weather station here!
    // req.auth describes the identity of the user
    // req.payment is the payment they sent
    const weatherData = {
      temperature: '15 C',
      conditions: 'Clear skies',
      region: 'Downtown Mars' // Hypothetical data
    }
    res.json(weatherData)
  })

  const port = 8080
  app.listen(port, () => {
    console.log(`Paid Weather API listening on port ${port}`)
  })
}
startServer().catch(console.error)
```

**Client (snippet)**

```js
import { AuthFetch, WalletClient } from '@bsv/sdk'

async function getWeatherData() {
  const wallet = new WalletClient('auto')
  const client = new AuthFetch(wallet)

  try {
    const resp = await client.fetch('http://localhost:8080/weatherStats')
    if (!resp.ok) {
      throw new Error(`Server error: ${resp.status}`)
    }
    const data = await resp.json()
    console.log('Weather data:', data)
  } catch (err) {
    console.error('Could not fetch weather data:', err)
  }
}

getWeatherData()
```

Whenever `fetch('http://localhost:8080/weatherStats')` is called, the server demands 1 sat. `AuthFetch` *automatically* builds the payment transaction with the user’s wallet. The user is prompted to confirm or must have auto-approval settings. Finally, the server sees the paid & authenticated request, returns the weather data, and you can confirm in the WUI that you earned 1 sat!

---

## 6. Next Steps

- **Expand Payment Logic**: Add dynamic fees, e.g. per request size or user type.
- **Certificate-Based Access**: Use `certificatesToRequest` in `createAuthMiddleware` to require a user certificate (like “cool user only”).
- **Explore BRC-105**: This is the specification behind BRC-105 HTTP micropayments (the 402 Payment Required flow).
- **Enhance Security**: Use [multi-factor setups](https://bsv-blockchain.github.io/ts-sdk/#class-keyshares) for your server wallet root key.
- **Deploy**: Put your Express server with micropayments on a server for the world to use.

---

## 7. Conclusion

With just a few lines of code:
1. You’ve enforced user authentication (BRC-103).
2. You’ve monetized each request with a micropayment (BRC-105).
3. You’ve made the developer experience *easy* on both sides, thanks to `AuthFetch` + `WalletClient` on front-end, and a simple Express chain of `AuthMiddleware -> PaymentMiddleware` hooking in your server’s wallet.

All micropayments are automatically deposited in your server’s wallet, which you can view and manage in the [Wallet UI admin panel](https://wui.bapp.dev) by importing your root key. That’s all it takes to stand up an authenticated, pay-per-call API on BSV—giving you a foundation for building more advanced use-cases and profitable services. Enjoy building!
