Bitcoin checkout on Bolt

Bolt builds Vite React apps on Bolt Cloud, with Bolt Database (or a Supabase project you connect) as the database and Supabase Edge Functions as server functions. OpenReceive runs in one server function of your app: it creates each Lightning invoice, the payment goes straight to your wallet, and payment attempts are stored in your app’s database. There is no OpenReceive account, no API key and no background worker.

Optional swaps let customers pay with USDT, USDC, SOL, and ETH. A swap provider you configure converts the payment to BTC over Lightning, and it settles into the same wallet. Available assets and networks depend on the provider.

Use @openreceive/* 0.4.27 or newer.

What we test, and what we don’t:

Before you start

Add checkout to your Bolt app

  1. Click the database icon at the top of your project, then Secrets. Create a secret named NWC_URI with your wallet code, then, for swaps, LSC_URI_PRIMARY with your swap provider code. Secrets reach your server functions and never the browser (Bolt: Secrets). On a team plan, only the project’s owner, co-owners and team admins can add them.
  2. Send Bolt this prompt:
Add Bitcoin Lightning checkout to this app with OpenReceive. Fetch https://openreceive.org/agent-directions/bolt/full.md and follow it exactly: it has the migrations, the server function and the checkout page. NWC_URI and LSC_URI_PRIMARY are already saved as this project's secrets, so do not ask me for them. Use @openreceive packages 0.4.27 or newer.
  1. Bolt writes two migrations and a server function named openreceive. The first migration is OpenReceive’s: its two tables, locked away from your app’s browser key, and the functions that write them. The second is yours: openreceive_on_paid, which marks an order paid, and a trigger that takes each order’s price from your products, so the browser cannot choose it.
  2. Bolt ends with “Setup is finished” and tells you where to place an order.

Bitcoin only, with no swap provider? Then in the prompt, replace NWC_URI and LSC_URI_PRIMARY are already saved with I want Bitcoin only, with no swaps. NWC_URI is already saved.

Not saved the secrets yet? Leave out the sentence about secrets. Bolt then asks you to add each one in Secrets, one at a time. Do not paste a code into the chat: Bolt has nowhere safe to keep it.

Check it

In the preview, sign in and place an order. Its checkout shows the payment methods. Pick Bitcoin to see a Lightning invoice. Each swap has a minimum amount set by the provider, so on a small order some coins are greyed out and show their minimum.

If the checkout cannot load:

Pay a small order from your wallet to see it settle: the checkout shows the payment as received, and openreceive_on_paid marks the order paid.

How it runs on Bolt

Each request starts the function’s payment code afresh, connects to your wallet and checks the buyer with Supabase Auth: about a second. The first request after Bolt deploys the function also downloads its packages.

Keep it intact: project knowledge

Bolt follows your project’s knowledge on every prompt: the gear icon → All project settings → Knowledge. Add this to it, so later edits keep the payment setup safe:

## Payments (OpenReceive)

- The payment routes are the server function supabase/functions/openreceive.
  Fulfillment is the SQL function public.openreceive_on_paid. Order prices
  come from the products table through a trigger, never from the page.
- NWC_URI and LSC_URI_PRIMARY are secrets. Never put them in .env, code or a
  VITE_ variable.
- Never add CORS headers to the openreceive function, never grant anon or
  authenticated anything on openreceive_* tables or functions, and never edit
  OpenReceive's migration.
- Full directions: https://openreceive.org/agent-directions/bolt/full.md

Next