Skip to content

GameChangerFinance/cardano-relay

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cardano CIP-8 Relay Control on a ESP01

A Cardano integration on a 32-bit 80 MHz processor in less than 40Kb of RAM. No middlemen: direct device to user wallet connection

Integrating Cardano on the ESP8266 using UDC

Watch it in action

This is a web app written in C/C++ and leveraging on Cardano cryptography using the Universal Dapp Connector (UDC). Uses a tiny ESP8266 ESP-01 board that controls a serial LC Technology / HW-655 / HW-566 style relay through a minimal local web app which dinamically generates GCScript DSL to perform a CIP8 signing flow intent on user wallet. This is an Arduino IDE project.

The ESP01 serves a web page with a button to toggle the relay. Pressing the button opens GameChanger Wallet. The user signs a message through CIP-8, returns a GCScript DSL export, and the ESP01 toggles the relay only if the returned value matches the device challenge, a secret and the new target state.

Flow

ESP01 page
  -> user presses Turn ON / Turn OFF
  -> GameChanger Wallet opens through a UDC URL
  -> GCScript signs with CIP-8
  -> wallet redirects back to the ESP01
  -> ESP01 extracts 'exports.CIP8RelayControl' payload
  -> ESP01 checks if payload matches SHA512(CIP8_SIGNATURE_SHA512 + CHALLENGE + STATE)
  -> relay toggles only on match
  -> ESP01 persists the new state and rotates the random challenge

Runtime formula used by the ESP01:

SHA512(CIP8_SIGNATURE_SHA512 + CHALLENGE_STR + STATE) === USER_PAYLOAD

That matches the GCScript intent formula:

{sha512(join('',sha512(get('cache.sign.signature')),get('args.challenge'),get('args.state')))}

This optimized design is perfect for the ESP01:

  • keep the HTML/CSS small,
  • offload all the heavy Cardano work to the user wallet
  • avoid JSON libraries when possible for GCScript DSL,
  • avoid on-chip CIP8 verification,
  • and use SHA-512 comparison instead.

Files

cardano-relay.ino                 Main Arduino sketch, web server, app state, UI, verification flow
env.h                             Small user configuration file
hardware.h                        ESP01 LED, serial relay, relay-board AT bridge, Wi-Fi, reconnect, and mDNS HAL
udc.h                             GCScript JSON builder, base64url encoder, UDC URL builder, return parser
tools/enrollment_gcscript.json    Helper intent to obtain SHA512(cache.sign.signature). Import on GameChanger Wallet IDE and run
enrollment_gcscript.png			  Helper intent to obtain SHA512(cache.sign.signature) encoded as QR code. Scan and run.
example-admin-wallet.png          Public default admin wallet QR for quick testing. Import on GameChanger Wallet and use to sign

Configure env.h

Edit only the values you actually need for deployment:

#define WIFI_SSID       "YOUR_WIFI_SSID"
#define WIFI_PASSWORD   "YOUR_WIFI_PASSWORD"
#define WIFI_HOSTNAME   "cardano-relay"
#define UDC_NETWORK_TAG "mainnet"
#define AUTHORIZED_CIP8_SIGNATURE_SHA512_HEX "dca6b2731fd8149e41e17a2127f5ffb2e29568cd0558727e857dd44586c4dc8d1967d6c4aade081100cf4ffbb23d82242d4b335f0b7dd9c1080d30b2f191460a"

The default hash above matches the included public example admin wallet. Scan/import the QR image below with GameChanger Wallet and use this password:

admin

Default admin wallet QR

This wallet is public and only intended for quick local testing. Do not send ADA, tokens, or any funds to this wallet. For real use, create/import your own wallet, run the enrollment flow, and replace AUTHORIZED_CIP8_SIGNATURE_SHA512_HEX in env.h with your own value.

The hostname is advertised with mDNS, so the default local URL is:

http://cardano-relay.local/

If .local resolution is not available on your client device, open the ESP01 IP address from your router DHCP leases instead.

Arduino IDE setup

Install the ESP8266 Arduino board package and select an ESP-01-compatible board target, for example:

Board: Generic ESP8266 Module
Flash Size: 1M
CPU Frequency: 80 MHz
Upload Speed: 115200

No extra Arduino library is required to keep it simple. The project uses the ESP8266 core APIs, EEPROM emulation, ESP8266WebServer, ESP8266mDNS, and BearSSL SHA-512 from the ESP8266 Arduino core.

How to get AUTHORIZED_CIP8_SIGNATURE_SHA512_HEX

Use the helper intent in:

tools/enrollment_gcscript.json

Set its returnURLPattern to a page you control, run it through GameChanger Wallet, and copy the exported value:

{
  "exports": {
    "CIP8RelayEnrollment": "<copy-this-128-char-sha512-hex>"
  }
}

Paste that 128-character value into env.h.

Web behavior

The button is a normal link with popup behavior:

<a href="https://wallet.gamechanger.finance/api/2/run/..." id="intentBtn" class="button" onclick="window.open(this.href, 'dapp connection', 'noopener,width=500,height=700'); return false;">Turn ON</a>

This gives two UX paths:

  • Normal click: opens GameChanger Wallet in a popup-sized window.
  • Long-press, right-click, or manual open: lets the user open the intent in a new tab.

When the wallet redirects back:

  1. The returned page extracts the export payload.
  2. The ESP01 accepts or rejects the payload.
  3. The returned page writes the result to localStorage.
  4. Already-open tabs of the same ESP01 origin receive the storage event and refresh.
  5. The popup attempts to close itself.

For the refresh signaling to work across tabs, open the original page and the wallet return URL on the same origin. The sketch now builds the wallet returnURLPattern from the current request host, so http://cardano-relay.local/ returns to .local, while http://<ip>/ returns to that IP.

Relay-board compatibility notes

Some LC Technology relay boards include a second MCU on the relay PCB. The ESP01 is only the Wi-Fi/UART side, while that second MCU actually drives the relay. For those boards, two details matter:

  • the relay command baud rate can be 115200 on newer boards or 9600 on older boards;
  • some Nuvoton-style boards send AT+CWMODE / AT+RST to the ESP01 and refuse relay commands until the ESP01 answers like stock AT firmware.

hardware.h now includes a tiny AT-response bridge for this boot handshake. This is why the firmware uses full-duplex UART instead of SERIAL_TX_ONLY. If the relay board red LED stays in a repeating blinking pattern and commands are ignored, it usually means the board-side MCU is still waiting for that boot handshake or is not connected to the ESP01 UART.

On boot, setupHardware() initializes the LED/UART and services the relay-board MCU. The sketch then reads the persisted relay state from EEPROM and applies that state once, so reboot behavior follows the stored app state instead of briefly forcing the relay OFF.

Troubleshooting checklist:

  1. Try the default 115200 baud first.
  2. If the business logic accepts wallet signatures but the relay does not move, try 9600 baud in hardware.h.
  3. Make sure ESP01 TX/RX are actually connected to the relay-board MCU. Some multi-relay boards use jumpers for this path.
  4. If the board LEDs continuously flash even with no ESP01 inserted, the board-side MCU firmware itself may be missing or wrong; in that case the ESP01 sketch cannot fix the relay board until that controller is programmed or replaced. I had a missing firmware issue on my relay board and I was able to solve it by flashing this firmware here: https://github.com/libretto/RelayMCU.git

Wiring notes

This project keeps the serial relay behavior from the ESP01/HW-655/HW-566 style adapter:

ESP01 TX  -> relay-board MCU RX / serial input
ESP01 RX  -> relay-board MCU TX / AT-boot handshake output, when present
ESP01 GND -> relay adapter GND
ESP01 VCC -> regulated 3.3V supply

The relay adapter is controlled through the ESP01 UART. On many LC Technology boards, the relay is not wired directly to a GPIO; the ESP01 sends command frames to a second MCU on the relay PCB:

Relay 1 ON:  A0 01 01 A2
Relay 1 OFF: A0 01 00 A1

The current firmware defaults to full-duplex UART at 115200 baud because newer LC Technology / Nuvoton-style boards often expect the ESP01 to behave like the original ESP8266 AT firmware during boot before they accept relay commands:

Serial.begin(115200, SERIAL_8N1);

Older single-relay boards may require 9600 baud. If relay authorization works but the physical relay does not move, edit this constant in hardware.h and flash again:

static const uint32_t SERIAL_RELAY_BAUD_RATE = 9600;

Do not use normal Serial.print() debugging on the same UART while connected to the relay adapter. Random serial text can be interpreted as relay commands or as fake AT-firmware responses.

Persistence model

The ESP01 persists:

  • relay state
  • current random challenge
  • successful toggle count
  • a magic value used to detect uninitialized EEPROM state

Flash writes are intentionally limited. The sketch writes persistence only on first initialization and after an accepted relay toggle. Invalid wallet returns do not rotate the challenge and do not write state.

Expected wallet return payload

The parser accepts a returned JSON payload containing:

{
  "exports": {
    "CIP8RelayControl": "51d3b5ac9389482c3003f413e99164013486e2e57f435032f83655b16dfe878507f856807145a54f2878f7510257e64875d8454b8ef10110e183dc0374a07bd9"
  }
}

It also accepts a direct query value containing the 128-character export.

Security notes

This project has been vibe-coded for educational purposes.

This is not full on-device CIP-8 verification. The ESP01 checks a challenge-bound hash derived from a preconfigured signature hash:

SHA512(SHA512(CIP8 signature) + challenge + target_state)

This design, while rudimentary, is lightweight for this constraint hardware and also privacy preserving: device rejects invalid private keys without knowing exactly the private keys/address of the allowed user!

It's intentionally lightweight for an ESP01 educational prototype, but it is not the same as independently verifying the CIP-8 signature, address, COSE structure, and signed payload on the microcontroller.

For production, use encrypted communications (GCScript DSL can help you) and real on-device verification or a more complete enrollment, revocation, and key-rotation design unless this basic cryptography suit your needs.

Media

screenshot 1 2 3

About

A web app written in C/C++ and leveraging on Cardano cryptography using the Universal Dapp Connector (UDC). Uses a tiny ESP8266 ESP-01 board that controls a serial relay through a minimal local web app which dinamically generates GCScript DSL to perform a CIP8 signing flow intent on user wallet. This is an Arduino IDE project.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors