upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/Makefile
diff options
context:
space:
mode:
authorYour Name <you@example.com>2026-05-19 13:14:48 +0530
committerYour Name <you@example.com>2026-05-19 13:14:48 +0530
commitfe6aa9663d4cdabdc6e71db6068f8cd9e3739ffe (patch)
tree8cadb07243c07a6b3fa9453b239c9ac5cb02b454 /Makefile
parent77031f06a9a87320d011f501590985161d1eb305 (diff)
feat: WiFi beacon price discovery via Vendor IE (two-board verified)
Price discovery allows TollGate ESP32 boards to advertise their per-step price via WiFi Vendor-Specific Information Elements (OUI 0xC0FFEE) in beacon and probe response frames. Nearby boards passively scan and build a market view of competing TollGates without requiring internet access. Features: - beacon_price.c/h: 26-byte packed Vendor IE payload (price, step, metric, mint_hash, geohash, npub_hash), injected via esp_wifi_set_vendor_ie() - market.c/h: Passive WiFi scan receiver, vendor IE callback parsing, BSSID-correlated market entries, effective price ranking - GET /market API endpoint: JSON market snapshot with discovered entries - AP-only services: beacon + market + API start on WIFI_EVENT_AP_START, independent of STA connectivity - STA reconnect fix: 2s delay between retries creates scan windows; s_sta_connecting guard prevents double-connect - write-config-ap-only-a/b Makefile targets for STA-less testing - market_tick() in main loop, client price comparison logging Hardware verified: both boards discover each other via Vendor IE beacons. Board A sees TollGate-C0E9CA (RSSI=-30), Board B sees TollGate-B96D80 (RSSI=-25). test-market.mjs: 9/9, test-price-discovery.mjs: 7/7 per board. Unit tests: 45 new assertions across test_beacon_price (28) and test_market (17). All 15 test suites pass. ESP-IDF build clean for ESP32-S3.
Diffstat (limited to 'Makefile')
-rw-r--r--Makefile65
1 files changed, 65 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 7443e26..ef8dfcc 100644
--- a/Makefile
+++ b/Makefile
@@ -18,6 +18,16 @@ NPM ?= npm
18PYTHON ?= python3 18PYTHON ?= python3
19 19
20TOLLGATE_IP ?= 10.192.45.1 20TOLLGATE_IP ?= 10.192.45.1
21TOLLGATE_B_IP ?= 10.185.47.1
22
23NSEC_A ?= 9af47906b45aca5e238390f3d03c8274e154198e81aa2095065627d1e61ca968
24NSEC_B ?= a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
25MINT_URL ?= https://testnut.cashu.space
26BOARD_A_IP = 10.185.47.1
27BOARD_B_IP = 10.192.45.1
28SPIFFS_OFFSET = 0x410000
29SPIFFS_SIZE = 0xF0000
30SPIFFSGEN = $(IDF_PATH)/components/spiffs/spiffsgen.py
21 31
22BOARD ?= b 32BOARD ?= b
23 33
@@ -81,6 +91,7 @@ endef
81.PHONY: test-smoke test-api test-network test-portal test-payment 91.PHONY: test-smoke test-api test-network test-portal test-payment
82.PHONY: test-reset-auth test-session-expiry test-dns-firewall test-cvm 92.PHONY: test-reset-auth test-session-expiry test-dns-firewall test-cvm
83.PHONY: test-local-relay test-relay-nip11 test-cvm-roundtrip test-cross-board test-cvm-mcp 93.PHONY: test-local-relay test-relay-nip11 test-cvm-roundtrip test-cross-board test-cvm-mcp
94.PHONY: test-market test-price-discovery
84.PHONY: tokens wallet-setup wallet-info wallet-balance mint-token send-token 95.PHONY: tokens wallet-setup wallet-info wallet-balance mint-token send-token
85.PHONY: clean erase-nvs reset serial-log bootstrap-config 96.PHONY: clean erase-nvs reset serial-log bootstrap-config
86.PHONY: cvm-pubkey cvm-test-tool cvm-announce 97.PHONY: cvm-pubkey cvm-test-tool cvm-announce
@@ -311,6 +322,60 @@ test-cross-board:
311 @echo "=== Running cross-board payment test ===" 322 @echo "=== Running cross-board payment test ==="
312 TOLLGATE_IP=$(TOLLGATE_IP) $(NODE) tests/integration/test-cross-board.mjs 323 TOLLGATE_IP=$(TOLLGATE_IP) $(NODE) tests/integration/test-cross-board.mjs
313 324
325test-market:
326 $(call _require_board_lock)
327 @echo "=== Running market endpoint test ==="
328 TOLLGATE_IP=$(TOLLGATE_IP) $(NODE) tests/integration/test-market.mjs
329
330test-price-discovery:
331 $(call _require_board_lock)
332 @echo "=== Running two-board price discovery test ==="
333 TOLLGATE_IP=$(TOLLGATE_IP) TOLLGATE_B_IP=$(TOLLGATE_B_IP) $(NODE) tests/integration/test-price-discovery.mjs
334
335# ──────────────────────────────────────────────
336# SPIFFS Config
337# ──────────────────────────────────────────────
338
339define write_board_config
340 $(call require_lock_$(1))
341 @echo "=== Writing SPIFFS config to Board $(1) ($(PORT_$(1))) ==="
342 @TMPDIR=$$(mktemp -d) && \
343 echo '{"nsec":"$(NSEC_$(1))","wifi_networks":[{"ssid":"$(WIFI_SSID)","password":"$(WIFI_PASSWORD)"}],"ap_password":"","mint_url":"$(MINT_URL)","price_per_step":21,"step_size_ms":60000,"client_enabled":false,"nostr_geohash":"u281w0dfz","nostr_relays":["wss://relay.damus.io","wss://nos.lol"],"nostr_publish_interval_s":21600}' > "$$TMPDIR/config.json" && \
344 echo " Generating SPIFFS image..." && \
345 python3 $(SPIFFSGEN) --page-size 256 --obj-name-len 32 --use-magic --use-magic-len $(SPIFFS_SIZE) "$$TMPDIR" "$$TMPDIR/spiffs.bin" && \
346 echo " Writing to flash..." && \
347 python3 -m esptool --port $(PORT_$(1)) --baud $(BAUD) write_flash $(SPIFFS_OFFSET) "$$TMPDIR/spiffs.bin" && \
348 rm -rf "$$TMPDIR" && \
349 echo "Config written."
350 @python3 -m esptool --port $(PORT_$(1)) run 2>/dev/null || true
351endef
352
353define write_board_config_ap_only
354 $(call require_lock_$(1))
355 @echo "=== Writing AP-only SPIFFS config to Board $(1) ($(PORT_$(1))) ==="
356 @TMPDIR=$$(mktemp -d) && \
357 echo '{"nsec":"$(NSEC_$(1))","wifi_networks":[],"ap_password":"","mint_url":"$(MINT_URL)","price_per_step":21,"step_size_ms":60000,"client_enabled":false,"nostr_geohash":"u281w0dfz","nostr_relays":["wss://relay.damus.io","wss://nos.lol"],"nostr_publish_interval_s":21600}' > "$$TMPDIR/config.json" && \
358 echo " Generating SPIFFS image..." && \
359 python3 $(SPIFFSGEN) --page-size 256 --obj-name-len 32 --use-magic --use-magic-len $(SPIFFS_SIZE) "$$TMPDIR" "$$TMPDIR/spiffs.bin" && \
360 echo " Writing to flash..." && \
361 python3 -m esptool --port $(PORT_$(1)) --baud $(BAUD) write_flash $(SPIFFS_OFFSET) "$$TMPDIR/spiffs.bin" && \
362 rm -rf "$$TMPDIR" && \
363 echo "AP-only config written."
364 @python3 -m esptool --port $(PORT_$(1)) run 2>/dev/null || true
365endef
366
367write-config-a:
368 $(call write_board_config,A)
369
370write-config-b:
371 $(call write_board_config,B)
372
373write-config-ap-only-a:
374 $(call write_board_config_ap_only,A)
375
376write-config-ap-only-b:
377 $(call write_board_config_ap_only,B)
378
314# ────────────────────────────────────────────── 379# ──────────────────────────────────────────────
315# Wallet 380# Wallet
316# ────────────────────────────────────────────── 381# ──────────────────────────────────────────────