Building a Paid NIP-90 Text Generation DVM

Practical guide to building a paid NIP-90 DVM with Go, LNbits, and Groq.

Building a Paid NIP-90 Text Generation DVM

A practical guide to building a NIP-90 Data Vending Machine that actually charges for its work.

The Problem

Most DVMs on the network respond to kind 5050 requests for free. They process the request, generate a response, and deliver it without ever asking for payment. If you want to earn sats, you need a payment gate.

Architecture

The flow: Subscribe to kind 5050 → Create Lightning invoice → Publish payment-required status with bolt11 → Poll for payment → Generate text → Deliver via kind 6050.

Key Code

Pricing from bid tag (Go):

priceSats := 21 // default
for _, tag := range ev.Tags {
    if tag[0] == "bid" && len(tag) > 1 {
        var bid int
        fmt.Sscanf(tag[1], "%d", &bid)
        if bid > 0 {
            priceSats = bid / 1000 // msats to sats
            if priceSats < 10 { priceSats = 10 }
        }
    }
}

Deduplication (prevents triple-response from multi-relay SubMany):

var processed sync.Map
if _, loaded := processed.LoadOrStore(ev.ID, true); loaded {
    return
}

Market Reality

After deploying to 3 relays (damus, nos.lol, primal):

  • 5+ kind 5050 requests per day from real users
  • 0 paid requests — requesters send events without bid tags
  • Other DVMs respond for free, so users have no incentive to pay

Classic marketplace problem: paid services competing against free ones.

Stack

Go + go-nostr + LNbits + Groq (Llama 3.3 70B). Total cost: $0/month.

Source: github.com/joelklabo/dvm-textgen


No comments yet.