Skip to main content
This tutorial builds the smallest machine that does all three KineticVM jobs. It takes payment authority from the vault, it moves a pin, and it leaves a signed record of the sale. You need a claimed device from the quickstart, with [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 in records.example.toml if you are shipping a package:
Leave the keypad code out. The host refuses fields that are not in this list, which is what keeps a code or a chat id out of a dataset you might sell later. See Operation records.

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
Step 3 is the one that makes the sale provable. Tell the model, in the step body or in a skill, to call 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

In firmware/esp32/src/main.rs, take_host_message returns nothing. When the customer presses enter, return one message and then nothing until the next code:
The daemon matches 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 uses vault_pay. Two things have to be true first:
  1. The vault holds MON. /deposit in Telegram opens the deposit page.
  2. 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:
in ~/.kinetic/records/operations.jsonl, with the request hash on the same line number in operation-requests.txt.
execution_mode = "supervised" asks the paired chat before the run starts. Switch to auto only after you have watched a few sales and the caps are amounts you can lose.