[chain] enabled, and a board that can drive one output pin. The ESP32 starter in firmware/esp32 already answers gpio_write on pins 2 and 13.
Decide the record
One sale is one line. Put this in the device config, or inrecords.example.toml if you are shipping a package:
Write the procedure
Create~/.kinetic/sops/vend/SOP.toml and SOP.md, or let kinetic plugin create ./vending write the starter and replace it.
SOP.toml
agent is required because the keypad trigger has no Telegram turn to borrow an agent from. Quickstart names that agent device.
SOP.md
monad_attest with:
The host canonicalizes that object, signs the line, and appends it only after the transaction succeeds.
check_code is your tool. The first plugin tutorial is how you compile and install it. Until that tool exists, you can run the procedure manually from Telegram and have the model choose the slot itself. Do not attest a sale the motor step did not finish.
Connect the keypad
Infirmware/esp32/src/main.rs, take_host_message returns nothing. When the customer presses enter, return one message and then nothing until the next code:
board = "esp32" and signal = "keypad". Returning the same message on every idle poll starts a new run on every poll. The protocol and the default serial ports are in Hardware and firmware.
Let it pay, if a sale takes MON
A vend that pays a supplier usesvault_pay. Two things have to be true first:
- The vault holds MON.
/depositin Telegram opens the deposit page. - The supplier address is allowlisted.
/approve 0x…returns a digest. Sign it with the owner wallet and send the signature back. The flow is in Telegram owner commands.
vault_pay asks for approval in the chat before it runs. The vault still enforces the caps and the allowlist if that approval is given.
Watch a sale land
After a vend,/status lists the attestation transaction. On the device, the same sale is one line:
~/.kinetic/records/operations.jsonl, with the request hash on the same line number in operation-requests.txt.