openreceive 0.4.21 → 0.4.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/lib/openreceive/version.rb +1 -1
- data/skills/integrate-openreceive/references/btcpay.md +1 -1
- data/skills/integrate-openreceive/references/django.md +55 -26
- data/skills/integrate-openreceive/references/fastapi.md +59 -31
- data/skills/integrate-openreceive/references/fastify.md +63 -33
- data/skills/integrate-openreceive/references/laravel.md +63 -30
- data/skills/integrate-openreceive/references/next.md +51 -27
- data/skills/integrate-openreceive/references/node.md +61 -31
- data/skills/integrate-openreceive/references/php.md +51 -27
- data/skills/integrate-openreceive/references/rails.md +51 -26
- data/skills/integrate-openreceive/references/woocommerce.md +20 -14
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4ab3f684223bbce9a03d09d44e0ec67529cbc2b6616d2b50fb28a42f664e1a9a
|
|
4
|
+
data.tar.gz: 067be079ba6ccc64c251183495e7252837f596be0f244e1eceee557b08491f38
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 913b9d2b647168a3e383199a15078eaa807496ac18fe941e25d7d1bddc0e114f654aaa9cccecdff347fd9eb578043ac397fe6cca484b0088bb7659ac5583aff0
|
|
7
|
+
data.tar.gz: d4a72bb5286fcaaa4c58aeef127c488fcf6921f921ea3676b9115bb3138500954a5c5bcbe5c6b369ed6e5e36f759d985c080db351a83f898edc4e67d7d2a3dd8
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.22 - 2026-10-10
|
|
4
|
+
|
|
5
|
+
Release with the complete 0.4.22 package family. The bundled agent skills'
|
|
6
|
+
directions now end with a message that starts "Setup is finished" and sends
|
|
7
|
+
nothing after it. They write the codes with the file-editing tool, check the
|
|
8
|
+
app sees them with doctor rather than `printenv`, start the server the way
|
|
9
|
+
the project already does, and restart only the app's own server by pid. No
|
|
10
|
+
Ruby runtime changes from 0.4.21.
|
|
11
|
+
|
|
3
12
|
## 0.4.21 - 2026-10-09
|
|
4
13
|
|
|
5
14
|
Release with the complete 0.4.21 package family. The bundled agent skills'
|
data/lib/openreceive/version.rb
CHANGED
|
@@ -17,7 +17,7 @@ curl -fsSL https://openreceive.org/agent-directions/btcpay/full.md
|
|
|
17
17
|
- Never tick the spend-capable override to make a save succeed.
|
|
18
18
|
- Do not suggest rotating or revoking a code because it was pasted here.
|
|
19
19
|
|
|
20
|
-
These directions describe OpenReceive 0.4.
|
|
20
|
+
These directions describe OpenReceive 0.4.22.
|
|
21
21
|
|
|
22
22
|
Connect a BTCPay Server store to a receive-only NWC wallet with the OpenReceive
|
|
23
23
|
plugin, and optionally let payers pay BTCPay invoices with USDT, USDC, ETH or
|
|
@@ -3,7 +3,7 @@ This is the full file; follow it from Step 0.
|
|
|
3
3
|
# OpenReceive agent directions (Django)
|
|
4
4
|
|
|
5
5
|
```sh
|
|
6
|
-
# READ THIS FIRST: this file is
|
|
6
|
+
# READ THIS FIRST: this file is 46 KB and a summary drops required steps. Download it whole:
|
|
7
7
|
curl -fsSL https://openreceive.org/agent-directions/django/full.md
|
|
8
8
|
# Skip the download only if you already have all of it: pasted, read from disk or fetched raw.
|
|
9
9
|
```
|
|
@@ -17,7 +17,7 @@ curl -fsSL https://openreceive.org/agent-directions/django/full.md
|
|
|
17
17
|
- Do not suggest rotating or revoking a code because it was pasted here.
|
|
18
18
|
- Start the quickstart only once the NWC code is saved, and the LSC code is saved or the user said "Bitcoin only".
|
|
19
19
|
|
|
20
|
-
These directions describe OpenReceive 0.4.
|
|
20
|
+
These directions describe OpenReceive 0.4.22.
|
|
21
21
|
|
|
22
22
|
Add OpenReceive to a Django project — the app you are already working in. You
|
|
23
23
|
do not need a copy of the OpenReceive source: the Python package is on PyPI
|
|
@@ -61,11 +61,12 @@ owns orders, users, prices, or fulfillment.
|
|
|
61
61
|
|
|
62
62
|
## Step 0 — ask for the two codes, one question at a time
|
|
63
63
|
|
|
64
|
-
Before anything else,
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
Before anything else, check one file: the project's `.env`, if it exists.
|
|
65
|
+
`grep -E '^(NWC_URI|LSC_URI_PRIMARY)=.' .env | cut -d= -f1` names the codes
|
|
66
|
+
it sets without printing them. Check with that, here and after each write,
|
|
67
|
+
not by reading the file, and never print the values. A code that is already
|
|
68
|
+
set is not asked for again; if both are set, skip to step 5 (making the
|
|
69
|
+
server load the file), then the quickstart.
|
|
69
70
|
|
|
70
71
|
Otherwise your next action is a question to the user. Do not install the package,
|
|
71
72
|
edit the app, write `.env.example`, or search anywhere else before asking
|
|
@@ -96,14 +97,17 @@ you store it. Ask one question per message.
|
|
|
96
97
|
Do not mention `.env`, exports, or "tell me when it's set".
|
|
97
98
|
2. **When they paste it.** If it does not start with `nostr+walletconnect://`,
|
|
98
99
|
ask them to copy the receive-only code again. Otherwise write
|
|
99
|
-
`NWC_URI=<paste>` into the project's `.env
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
100
|
+
`NWC_URI=<paste>` into the project's `.env` with your file-editing tool,
|
|
101
|
+
creating the file if needed. Never write it with a shell command (`echo`,
|
|
102
|
+
`printf`, a heredoc, `python -c`): the command line shows the code. Make
|
|
103
|
+
sure `.gitignore` covers `.env` (and `.dockerignore`, if the app has one).
|
|
104
|
+
Never echo the value, commit it, or put it in client code. Reply only that
|
|
105
|
+
it is saved, then ask the next question.
|
|
106
|
+
3. **Second message — swaps.** If the user asked for stablecoins, USDT, USDC,
|
|
107
|
+
ETH, SOL, altcoins or "crypto" (as in "Bitcoin and stablecoin payments"),
|
|
108
|
+
this message IS the walkthrough below: send it as it is, and do not ask yes
|
|
109
|
+
or no first. Otherwise ask whether payers should also be able to pay with
|
|
110
|
+
USDT, USDC, ETH or SOL, then give the walkthrough. The walkthrough:
|
|
107
111
|
|
|
108
112
|
> Go to https://lightning-swap.com, sign in for API keys, create a key, and
|
|
109
113
|
> copy the whole URI (https://openreceive.org/set_up_swap_provider). Paste
|
|
@@ -113,10 +117,10 @@ you store it. Ask one question per message.
|
|
|
113
117
|
Mention FixedFloat only if they already use it.
|
|
114
118
|
4. **When they paste it.** If it does not start with
|
|
115
119
|
`lightning+swapconnect://`, ask them to copy it again. Otherwise add
|
|
116
|
-
`LSC_URI_PRIMARY=<paste>` to the same `.env
|
|
117
|
-
are now on, so build the refund route back
|
|
118
|
-
part of this integration. If they chose
|
|
119
|
-
`LSC_URI_PRIMARY` unset and skip that route.
|
|
120
|
+
`LSC_URI_PRIMARY=<paste>` to the same `.env` with the file-editing tool,
|
|
121
|
+
never a shell command. Swaps are now on, so build the refund route back
|
|
122
|
+
(the swap non-negotiable below) as part of this integration. If they chose
|
|
123
|
+
Bitcoin only, leave `LSC_URI_PRIMARY` unset and skip that route.
|
|
120
124
|
5. **Make the server load the file — yourself.** Django does not
|
|
121
125
|
read `.env` on its own. If the app already uses `django-environ`, make sure
|
|
122
126
|
it reads this file; otherwise add it and call `environ.Env.read_env()` in
|
|
@@ -160,22 +164,28 @@ failed check and exits nonzero; fix it before going on.
|
|
|
160
164
|
|
|
161
165
|
Give the user that checkout link. The browser check in the quickstart's
|
|
162
166
|
"Render the checkout" section (payment-method icons, wallet logos, a pay
|
|
163
|
-
tutorial) is theirs:
|
|
167
|
+
tutorial) is theirs: name it in one line of your closing message, and do not
|
|
168
|
+
run it yourself.
|
|
164
169
|
|
|
165
170
|
You cannot pay the invoice: the code is receive-only. Do not pay, settle or
|
|
166
171
|
mark an order paid, and do not look for a way to (a wallet control port, a
|
|
167
172
|
test endpoint, another wallet). If the user wants a real settlement test, they
|
|
168
173
|
pay on that link from their own wallet, and `on_paid` marks the order paid.
|
|
169
174
|
|
|
170
|
-
Setup ends here.
|
|
171
|
-
|
|
172
|
-
|
|
175
|
+
Setup ends here. Your last message starts "Setup is finished" and has at most
|
|
176
|
+
five short lines (about 80 characters each): the link, the methods it offers,
|
|
177
|
+
and one line of what to look at. Send nothing after it. Do not list what
|
|
178
|
+
changed, copy out the quickstart's browser checklist, offer more work, or end
|
|
179
|
+
the message on a question.
|
|
173
180
|
|
|
174
181
|
- The link is to a real unpaid order. Keep that order; do not delete it.
|
|
182
|
+
- When this app's orders belong to a session or cookie, the user's browser
|
|
183
|
+
cannot open the order you made. Then the link is the shop's own page:
|
|
184
|
+
"Open <shop url> and click Buy: it opens the checkout." Do not explain order
|
|
185
|
+
ownership or mention your test order.
|
|
175
186
|
- Name the methods it offers: Bitcoin, plus USDT, USDC, ETH and SOL when
|
|
176
|
-
`LSC_URI_PRIMARY` is saved.
|
|
177
|
-
|
|
178
|
-
order's total says so on its own tile.
|
|
187
|
+
`LSC_URI_PRIMARY` is saved. Do not mention minimums, and never say a coin
|
|
188
|
+
will not work or will not be offered.
|
|
179
189
|
|
|
180
190
|
## Non-negotiables
|
|
181
191
|
|
|
@@ -192,6 +202,21 @@ itself, and they hold for every integration.
|
|
|
192
202
|
- Work only in this application. Never read or run anything from another
|
|
193
203
|
project on this machine (its `node_modules`, tools or source), for any
|
|
194
204
|
reason. A browser and Playwright are not part of setup.
|
|
205
|
+
- Restart only this app's server, on the port it already uses: stop the
|
|
206
|
+
process you started, or the one listening on that port, by its pid (or
|
|
207
|
+
restart its Compose service). Never `pkill` or `killall` by name: that
|
|
208
|
+
stops other people's servers too. Start it the way this project already
|
|
209
|
+
does (its README, Procfile, compose file or package script), on its own
|
|
210
|
+
port, not a port you pick.
|
|
211
|
+
- Run commands where the app runs. When a compose file builds it, run its
|
|
212
|
+
package manager, generators, migrations and doctor inside that service
|
|
213
|
+
(`docker compose exec` or `run`), and rebuild the image after adding a
|
|
214
|
+
package. This machine's language version and database path are not the
|
|
215
|
+
app's.
|
|
216
|
+
- To check that the running app sees the codes, run doctor: it reports each
|
|
217
|
+
one as present or missing and never prints a value. Never print the
|
|
218
|
+
environment (`printenv`, `env`, `docker compose config`), even filtered to
|
|
219
|
+
names.
|
|
195
220
|
- The host owns the price. `amount_for` reads it from your own data;
|
|
196
221
|
reject payer-supplied amounts.
|
|
197
222
|
- `authorize` runs on every request, and the `resource` it receives is a
|
|
@@ -200,6 +225,10 @@ itself, and they hold for every integration.
|
|
|
200
225
|
a placeholder that allows everything (`manage.py check` warns
|
|
201
226
|
`openreceive.W002` while it is set) — replace it with this app's real
|
|
202
227
|
ownership check, same as `on_paid`.
|
|
228
|
+
- Fill in `openreceive_host.py` with your file-edit tool: replace each
|
|
229
|
+
placeholder in place (the `authorize = staticmethod(...)` line, the
|
|
230
|
+
`amount_for` body, the `on_paid = staticmethod(...)` line). Never edit it
|
|
231
|
+
by line number from a script.
|
|
203
232
|
- `on_paid` must be idempotent. Its database fulfillment commits once per `reference` — your order
|
|
204
233
|
id, one per thing you fulfill, created before checkout, kept across retries,
|
|
205
234
|
never reused. A fresh id per page load lets one order be paid twice.
|
|
@@ -3,7 +3,7 @@ This is the full file; follow it from Step 0.
|
|
|
3
3
|
# OpenReceive agent directions (FastAPI)
|
|
4
4
|
|
|
5
5
|
```sh
|
|
6
|
-
# READ THIS FIRST: this file is
|
|
6
|
+
# READ THIS FIRST: this file is 39 KB and a summary drops required steps. Download it whole:
|
|
7
7
|
curl -fsSL https://openreceive.org/agent-directions/fastapi/full.md
|
|
8
8
|
# Skip the download only if you already have all of it: pasted, read from disk or fetched raw.
|
|
9
9
|
```
|
|
@@ -17,7 +17,7 @@ curl -fsSL https://openreceive.org/agent-directions/fastapi/full.md
|
|
|
17
17
|
- Do not suggest rotating or revoking a code because it was pasted here.
|
|
18
18
|
- Start the quickstart only once the NWC code is saved, and the LSC code is saved or the user said "Bitcoin only".
|
|
19
19
|
|
|
20
|
-
These directions describe OpenReceive 0.4.
|
|
20
|
+
These directions describe OpenReceive 0.4.22.
|
|
21
21
|
|
|
22
22
|
Add OpenReceive to a FastAPI application — the app you are already working in.
|
|
23
23
|
You do not need a copy of the OpenReceive source: the engine is on PyPI
|
|
@@ -61,11 +61,12 @@ owns orders, users, prices, or fulfillment.
|
|
|
61
61
|
|
|
62
62
|
## Step 0 — ask for the two codes, one question at a time
|
|
63
63
|
|
|
64
|
-
Before anything else,
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
Before anything else, check one file: the project's `.env`, if it exists.
|
|
65
|
+
`grep -E '^(NWC_URI|LSC_URI_PRIMARY)=.' .env | cut -d= -f1` names the codes
|
|
66
|
+
it sets without printing them. Check with that, here and after each write,
|
|
67
|
+
not by reading the file, and never print the values. A code that is already
|
|
68
|
+
set is not asked for again; if both are set, skip to step 5 (making the
|
|
69
|
+
server load the file), then the quickstart.
|
|
69
70
|
|
|
70
71
|
Otherwise your next action is a question to the user. Do not install packages,
|
|
71
72
|
edit the app, write `.env.example`, or search anywhere else before asking
|
|
@@ -96,14 +97,17 @@ you store it. Ask one question per message.
|
|
|
96
97
|
Do not mention `.env`, exports, or "tell me when it's set".
|
|
97
98
|
2. **When they paste it.** If it does not start with `nostr+walletconnect://`,
|
|
98
99
|
ask them to copy the receive-only code again. Otherwise write
|
|
99
|
-
`NWC_URI=<paste>` into the project's `.env
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
100
|
+
`NWC_URI=<paste>` into the project's `.env` with your file-editing tool,
|
|
101
|
+
creating the file if needed. Never write it with a shell command (`echo`,
|
|
102
|
+
`printf`, a heredoc, `python -c`): the command line shows the code. Make
|
|
103
|
+
sure `.gitignore` covers `.env` (and `.dockerignore`, if the app has one).
|
|
104
|
+
Never echo the value, commit it, or put it in client code. Reply only that
|
|
105
|
+
it is saved, then ask the next question.
|
|
106
|
+
3. **Second message — swaps.** If the user asked for stablecoins, USDT, USDC,
|
|
107
|
+
ETH, SOL, altcoins or "crypto" (as in "Bitcoin and stablecoin payments"),
|
|
108
|
+
this message IS the walkthrough below: send it as it is, and do not ask yes
|
|
109
|
+
or no first. Otherwise ask whether payers should also be able to pay with
|
|
110
|
+
USDT, USDC, ETH or SOL, then give the walkthrough. The walkthrough:
|
|
107
111
|
|
|
108
112
|
> Go to https://lightning-swap.com, sign in for API keys, create a key, and
|
|
109
113
|
> copy the whole URI (https://openreceive.org/set_up_swap_provider). Paste
|
|
@@ -113,10 +117,10 @@ you store it. Ask one question per message.
|
|
|
113
117
|
Mention FixedFloat only if they already use it.
|
|
114
118
|
4. **When they paste it.** If it does not start with
|
|
115
119
|
`lightning+swapconnect://`, ask them to copy it again. Otherwise add
|
|
116
|
-
`LSC_URI_PRIMARY=<paste>` to the same `.env
|
|
117
|
-
are now on, so build the refund route back
|
|
118
|
-
part of this integration. If they chose
|
|
119
|
-
`LSC_URI_PRIMARY` unset and skip that route.
|
|
120
|
+
`LSC_URI_PRIMARY=<paste>` to the same `.env` with the file-editing tool,
|
|
121
|
+
never a shell command. Swaps are now on, so build the refund route back
|
|
122
|
+
(the swap non-negotiable below) as part of this integration. If they chose
|
|
123
|
+
Bitcoin only, leave `LSC_URI_PRIMARY` unset and skip that route.
|
|
120
124
|
5. **Make the server load the file — yourself.** OpenReceive reads
|
|
121
125
|
`os.environ`, and a `.env` file on disk is not in it. Start the dev server
|
|
122
126
|
with `uvicorn --env-file .env` (update the app's run script or Procfile, not
|
|
@@ -153,23 +157,28 @@ serves the checkout page for one of its orders. Doctor names any failed check
|
|
|
153
157
|
and exits nonzero; fix it before going on.
|
|
154
158
|
|
|
155
159
|
Give the user that checkout link. The browser check in the quickstart's step 6
|
|
156
|
-
(payment-method icons, wallet logos, a pay tutorial) is theirs:
|
|
157
|
-
|
|
160
|
+
(payment-method icons, wallet logos, a pay tutorial) is theirs: name it in one
|
|
161
|
+
line of your closing message, and do not run it yourself.
|
|
158
162
|
|
|
159
163
|
You cannot pay the invoice: the code is receive-only. Do not pay, settle or
|
|
160
164
|
mark an order paid, and do not look for a way to (a wallet control port, a
|
|
161
165
|
test endpoint, another wallet). If the user wants a real settlement test, they
|
|
162
166
|
pay on that link from their own wallet, and `on_paid` marks the order paid.
|
|
163
167
|
|
|
164
|
-
Setup ends here.
|
|
165
|
-
|
|
166
|
-
|
|
168
|
+
Setup ends here. Your last message starts "Setup is finished" and has at most
|
|
169
|
+
five short lines (about 80 characters each): the link, the methods it offers,
|
|
170
|
+
and one line of what to look at. Send nothing after it. Do not list what
|
|
171
|
+
changed, copy out the quickstart's browser checklist, offer more work, or end
|
|
172
|
+
the message on a question.
|
|
167
173
|
|
|
168
174
|
- The link is to a real unpaid order. Keep that order; do not delete it.
|
|
175
|
+
- When this app's orders belong to a session or cookie, the user's browser
|
|
176
|
+
cannot open the order you made. Then the link is the shop's own page:
|
|
177
|
+
"Open <shop url> and click Buy: it opens the checkout." Do not explain order
|
|
178
|
+
ownership or mention your test order.
|
|
169
179
|
- Name the methods it offers: Bitcoin, plus USDT, USDC, ETH and SOL when
|
|
170
|
-
`LSC_URI_PRIMARY` is saved.
|
|
171
|
-
|
|
172
|
-
order's total says so on its own tile.
|
|
180
|
+
`LSC_URI_PRIMARY` is saved. Do not mention minimums, and never say a coin
|
|
181
|
+
will not work or will not be offered.
|
|
173
182
|
|
|
174
183
|
## Non-negotiables
|
|
175
184
|
|
|
@@ -186,6 +195,21 @@ itself, and they hold for every integration.
|
|
|
186
195
|
- Work only in this application. Never read or run anything from another
|
|
187
196
|
project on this machine (its `node_modules`, tools or source), for any
|
|
188
197
|
reason. A browser and Playwright are not part of setup.
|
|
198
|
+
- Restart only this app's server, on the port it already uses: stop the
|
|
199
|
+
process you started, or the one listening on that port, by its pid (or
|
|
200
|
+
restart its Compose service). Never `pkill` or `killall` by name: that
|
|
201
|
+
stops other people's servers too. Start it the way this project already
|
|
202
|
+
does (its README, Procfile, compose file or package script), on its own
|
|
203
|
+
port, not a port you pick.
|
|
204
|
+
- Run commands where the app runs. When a compose file builds it, run its
|
|
205
|
+
package manager, generators, migrations and doctor inside that service
|
|
206
|
+
(`docker compose exec` or `run`), and rebuild the image after adding a
|
|
207
|
+
package. This machine's language version and database path are not the
|
|
208
|
+
app's.
|
|
209
|
+
- To check that the running app sees the codes, run doctor: it reports each
|
|
210
|
+
one as present or missing and never prints a value. Never print the
|
|
211
|
+
environment (`printenv`, `env`, `docker compose config`), even filtered to
|
|
212
|
+
names.
|
|
189
213
|
- The host owns the price. `amount_for` reads it from your own data; reject
|
|
190
214
|
payer-supplied amounts.
|
|
191
215
|
- `authorize` runs on every request, and the `resource` it receives is a CLAIM
|
|
@@ -519,14 +543,18 @@ host = Host(
|
|
|
519
543
|
),
|
|
520
544
|
)
|
|
521
545
|
|
|
522
|
-
|
|
523
|
-
|
|
546
|
+
# The router carries the options. Build it before the lifespan: through
|
|
547
|
+
# 0.4.21 the lifespan bound first and refused the router's options.
|
|
548
|
+
router = openreceive_router(
|
|
549
|
+
host,
|
|
550
|
+
engine=engine,
|
|
524
551
|
# Recommended for public web shops: `rate_limiting=True` caps invoice
|
|
525
552
|
# creation at 60 per client IP per hour. Leave it off (the default) for
|
|
526
553
|
# point-of-sale deployments, where many payers share the terminal's IP.
|
|
527
|
-
|
|
528
|
-
prefix="/openreceive",
|
|
554
|
+
rate_limiting=True,
|
|
529
555
|
)
|
|
556
|
+
app = FastAPI(lifespan=openreceive_lifespan(host, engine=engine))
|
|
557
|
+
app.include_router(router, prefix="/openreceive")
|
|
530
558
|
```
|
|
531
559
|
|
|
532
560
|
`authorize` receives the Starlette `Request`. Cookies, headers, and whatever
|
|
@@ -3,7 +3,7 @@ This is the full file; follow it from Step 0.
|
|
|
3
3
|
# OpenReceive agent directions (Fastify)
|
|
4
4
|
|
|
5
5
|
```sh
|
|
6
|
-
# READ THIS FIRST: this file is
|
|
6
|
+
# READ THIS FIRST: this file is 38 KB and a summary drops required steps. Download it whole:
|
|
7
7
|
curl -fsSL https://openreceive.org/agent-directions/fastify/full.md
|
|
8
8
|
# Skip the download only if you already have all of it: pasted, read from disk or fetched raw.
|
|
9
9
|
```
|
|
@@ -17,7 +17,7 @@ curl -fsSL https://openreceive.org/agent-directions/fastify/full.md
|
|
|
17
17
|
- Do not suggest rotating or revoking a code because it was pasted here.
|
|
18
18
|
- Start the quickstart only once the NWC code is saved, and the LSC code is saved or the user said "Bitcoin only".
|
|
19
19
|
|
|
20
|
-
These directions describe OpenReceive 0.4.
|
|
20
|
+
These directions describe OpenReceive 0.4.22.
|
|
21
21
|
|
|
22
22
|
Add OpenReceive to a Fastify application — the app you are already working in.
|
|
23
23
|
You do not need a copy of the OpenReceive source: the packages are on npm, and
|
|
@@ -58,11 +58,12 @@ owns orders, users, prices, or fulfillment.
|
|
|
58
58
|
|
|
59
59
|
## Step 0 — ask for the two codes, one question at a time
|
|
60
60
|
|
|
61
|
-
Before anything else,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
Before anything else, check one file: the project's `.env`, if it exists.
|
|
62
|
+
`grep -E '^(NWC_URI|LSC_URI_PRIMARY)=.' .env | cut -d= -f1` names the codes
|
|
63
|
+
it sets without printing them. Check with that, here and after each write,
|
|
64
|
+
not by reading the file, and never print the values. A code that is already
|
|
65
|
+
set is not asked for again; if both are set, skip to step 5 (making the
|
|
66
|
+
server load the file), then the quickstart.
|
|
66
67
|
|
|
67
68
|
Otherwise your next action is a question to the user. Do not install packages,
|
|
68
69
|
edit the app, write `.env.example`, or search anywhere else before asking
|
|
@@ -93,14 +94,17 @@ you store it. Ask one question per message.
|
|
|
93
94
|
Do not mention `.env`, exports, or "tell me when it's set".
|
|
94
95
|
2. **When they paste it.** If it does not start with `nostr+walletconnect://`,
|
|
95
96
|
ask them to copy the receive-only code again. Otherwise write
|
|
96
|
-
`NWC_URI=<paste>` into the project's `.env
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
97
|
+
`NWC_URI=<paste>` into the project's `.env` with your file-editing tool,
|
|
98
|
+
creating the file if needed. Never write it with a shell command (`echo`,
|
|
99
|
+
`printf`, a heredoc, `python -c`): the command line shows the code. Make
|
|
100
|
+
sure `.gitignore` covers `.env` (and `.dockerignore`, if the app has one).
|
|
101
|
+
Never echo the value, commit it, or put it in client code. Reply only that
|
|
102
|
+
it is saved, then ask the next question.
|
|
103
|
+
3. **Second message — swaps.** If the user asked for stablecoins, USDT, USDC,
|
|
104
|
+
ETH, SOL, altcoins or "crypto" (as in "Bitcoin and stablecoin payments"),
|
|
105
|
+
this message IS the walkthrough below: send it as it is, and do not ask yes
|
|
106
|
+
or no first. Otherwise ask whether payers should also be able to pay with
|
|
107
|
+
USDT, USDC, ETH or SOL, then give the walkthrough. The walkthrough:
|
|
104
108
|
|
|
105
109
|
> Go to https://lightning-swap.com, sign in for API keys, create a key, and
|
|
106
110
|
> copy the whole URI (https://openreceive.org/set_up_swap_provider). Paste
|
|
@@ -110,10 +114,10 @@ you store it. Ask one question per message.
|
|
|
110
114
|
Mention FixedFloat only if they already use it.
|
|
111
115
|
4. **When they paste it.** If it does not start with
|
|
112
116
|
`lightning+swapconnect://`, ask them to copy it again. Otherwise add
|
|
113
|
-
`LSC_URI_PRIMARY=<paste>` to the same `.env
|
|
114
|
-
are now on, so build the refund route back
|
|
115
|
-
part of this integration. If they chose
|
|
116
|
-
`LSC_URI_PRIMARY` unset and skip that route.
|
|
117
|
+
`LSC_URI_PRIMARY=<paste>` to the same `.env` with the file-editing tool,
|
|
118
|
+
never a shell command. Swaps are now on, so build the refund route back
|
|
119
|
+
(the swap non-negotiable below) as part of this integration. If they chose
|
|
120
|
+
Bitcoin only, leave `LSC_URI_PRIMARY` unset and skip that route.
|
|
117
121
|
5. **Make the server load the file — yourself.** OpenReceive reads
|
|
118
122
|
`process.env`, and a `.env` file on disk is not in it. Put
|
|
119
123
|
`import "dotenv/config";` at the top of the server entry, as the quickstart
|
|
@@ -148,23 +152,28 @@ Doctor reads `.env` itself. Never source it into a shell: the `&` in a
|
|
|
148
152
|
code splits the value and prints the pieces.
|
|
149
153
|
|
|
150
154
|
Give the user that checkout link. The browser check in the quickstart's step 6
|
|
151
|
-
(payment-method icons, wallet logos, a pay tutorial) is theirs:
|
|
152
|
-
|
|
155
|
+
(payment-method icons, wallet logos, a pay tutorial) is theirs: name it in one
|
|
156
|
+
line of your closing message, and do not run it yourself.
|
|
153
157
|
|
|
154
158
|
You cannot pay the invoice: the code is receive-only. Do not pay, settle or
|
|
155
159
|
mark an order paid, and do not look for a way to (a wallet control port, a
|
|
156
160
|
test endpoint, another wallet). If the user wants a real settlement test, they
|
|
157
161
|
pay on that link from their own wallet, and `onPaid` marks the order paid.
|
|
158
162
|
|
|
159
|
-
Setup ends here.
|
|
160
|
-
|
|
161
|
-
|
|
163
|
+
Setup ends here. Your last message starts "Setup is finished" and has at most
|
|
164
|
+
five short lines (about 80 characters each): the link, the methods it offers,
|
|
165
|
+
and one line of what to look at. Send nothing after it. Do not list what
|
|
166
|
+
changed, copy out the quickstart's browser checklist, offer more work, or end
|
|
167
|
+
the message on a question.
|
|
162
168
|
|
|
163
169
|
- The link is to a real unpaid order. Keep that order; do not delete it.
|
|
170
|
+
- When this app's orders belong to a session or cookie, the user's browser
|
|
171
|
+
cannot open the order you made. Then the link is the shop's own page:
|
|
172
|
+
"Open <shop url> and click Buy: it opens the checkout." Do not explain order
|
|
173
|
+
ownership or mention your test order.
|
|
164
174
|
- Name the methods it offers: Bitcoin, plus USDT, USDC, ETH and SOL when
|
|
165
|
-
`LSC_URI_PRIMARY` is saved.
|
|
166
|
-
|
|
167
|
-
order's total says so on its own tile.
|
|
175
|
+
`LSC_URI_PRIMARY` is saved. Do not mention minimums, and never say a coin
|
|
176
|
+
will not work or will not be offered.
|
|
168
177
|
|
|
169
178
|
## Non-negotiables
|
|
170
179
|
|
|
@@ -181,6 +190,21 @@ itself, and they hold for every integration.
|
|
|
181
190
|
- Work only in this application. Never read or run anything from another
|
|
182
191
|
project on this machine (its `node_modules`, tools or source), for any
|
|
183
192
|
reason. A browser and Playwright are not part of setup.
|
|
193
|
+
- Restart only this app's server, on the port it already uses: stop the
|
|
194
|
+
process you started, or the one listening on that port, by its pid (or
|
|
195
|
+
restart its Compose service). Never `pkill` or `killall` by name: that
|
|
196
|
+
stops other people's servers too. Start it the way this project already
|
|
197
|
+
does (its README, Procfile, compose file or package script), on its own
|
|
198
|
+
port, not a port you pick.
|
|
199
|
+
- Run commands where the app runs. When a compose file builds it, run its
|
|
200
|
+
package manager, generators, migrations and doctor inside that service
|
|
201
|
+
(`docker compose exec` or `run`), and rebuild the image after adding a
|
|
202
|
+
package. This machine's language version and database path are not the
|
|
203
|
+
app's.
|
|
204
|
+
- To check that the running app sees the codes, run doctor: it reports each
|
|
205
|
+
one as present or missing and never prints a value. Never print the
|
|
206
|
+
environment (`printenv`, `env`, `docker compose config`), even filtered to
|
|
207
|
+
names.
|
|
184
208
|
- The host owns the price. `amountFor` reads it from your own data; reject
|
|
185
209
|
payer-supplied amounts.
|
|
186
210
|
- `authorize` runs on every request, and the `resource` it receives is a CLAIM
|
|
@@ -256,7 +280,10 @@ products, and you do not join them.
|
|
|
256
280
|
are buying.
|
|
257
281
|
- **Users own the order; OpenReceive never sees them.** `authorize` uses the
|
|
258
282
|
same ownership check this app already uses on the order show / pay page —
|
|
259
|
-
`sessions.currentUser(
|
|
283
|
+
`sessions.currentUser(native)`, a cookie, whatever it is. Pass `native` (the
|
|
284
|
+
Fastify request) to this app's own cookie and session helpers, never
|
|
285
|
+
`request`: that one is a Web Request, a helper that reads
|
|
286
|
+
`req.headers.cookie` finds nothing on it, and every payer gets a 403.
|
|
260
287
|
`resource.reference` is a claim the payer sent, not proof.
|
|
261
288
|
- **The order is unpaid or paid.** Do not copy `pending` / `expired` / `failed`
|
|
262
289
|
/ `attention` onto it. Those are attempt statuses on `openreceive_payments`. An
|
|
@@ -521,11 +548,14 @@ await app.register(openReceiveFastify, {
|
|
|
521
548
|
// Your own access check: may this caller do this action to this reference?
|
|
522
549
|
// `resource.reference` is your own order id, sent back by the payer's
|
|
523
550
|
// browser — a claim, not proof — already validated as a non-empty string.
|
|
524
|
-
// `native` is the untouched Fastify request
|
|
525
|
-
//
|
|
526
|
-
|
|
551
|
+
// `native` is the untouched Fastify request: pass it to this app's own
|
|
552
|
+
// cookie and session helpers, and a session decorated by @fastify/session
|
|
553
|
+
// (or whatever this app uses) is readable on it. `request` is a Web
|
|
554
|
+
// Request, so a helper that reads `req.headers.cookie` finds nothing on it
|
|
555
|
+
// and every payer gets a 403.
|
|
556
|
+
authorize: async ({ action, native, resource }) =>
|
|
527
557
|
orders.viewerMay(
|
|
528
|
-
await sessions.currentUser(
|
|
558
|
+
await sessions.currentUser(native),
|
|
529
559
|
resource.reference,
|
|
530
560
|
action,
|
|
531
561
|
),
|
|
@@ -541,7 +571,7 @@ await app.register(openReceiveFastify, {
|
|
|
541
571
|
```
|
|
542
572
|
|
|
543
573
|
Register the plugin after whichever plugin gives you sessions or auth
|
|
544
|
-
decorations, because `
|
|
574
|
+
decorations, because `native` is that same request object. The plugin
|
|
545
575
|
handles shutdown for you. It registers an `onClose` hook that closes the
|
|
546
576
|
wallet client together with the app, so you have no `ready`/`close` pair to
|
|
547
577
|
manage. A deploy health check awaits `fastify.ready()` instead.
|