Core concepts
Three capabilities, in the order you will use them. Each one stands on the one before it, so a device can stop at identity, add signed data, or go all the way to payments.
Device identity#
On first boot the device generates two keypairs and persists them through the platform layer:
- Ed25519 signs attestations — fast, compact, chain-neutral.
- secp256k1 signs payment authorizations and supports
ecrecover, so an EVM settlement service can tell which device signed.
From them the device derives a did:mw:… identifier and an EVM address. The keys are not exported, not derived from a server secret, and not shared between the two sides of a payment. A device that loses its storage loses its identity — that is the intended trade.
boat_keypair_t kp;
boat_crypto_init(&kp); /* load, or generate and persist */
printf("%s\n%s\n", kp.did, kp.eth_addr_hex);Verifiable machine data#
An attestation is a SHA-256 hash of a reading, signed with the device's Ed25519 key. A third party holding the payload and the public key can check later that this device said this, unaltered.
boat_attestation_t att;
boat_attest_create(&kp, "{\"kwh\":0.417,\"t\":1756713600}", &att);Unpaid attestation carries no chain binding. The paid submission path (boat_attest_submit_paid) speaks x402 against an eip155:<chain_id> network.
It proves the device signed the reading and that it has not changed. Whether the reading was accurate still depends on the sensor, its calibration and the device's security.
Machine payments#
A payment authorization is an EIP-3009 transfer authorization over EIP-712 typed data, signed on the device. The device signs; it does not submit. A settlement service verifies the signature and carries it on-chain, often many at once.
boat_nano_auth_t auth; /* 417 micro-USDC */
boat_nano_sign(&kp, payee, 417u, chain_id, verifier,
"GatewayWalletBatched", "1", NULL, &auth);
uint8_t recovered[20]; /* what settlement does */
boat_nano_verify(&auth, chain_id, verifier,
"GatewayWalletBatched", "1", recovered);The EIP-712 domain binds a signature to one chain and one verifying contract. Presented anywhere else, it does not verify — which is why the Quick Start ends with cross-chain correctly rejected.
Layers and headers#
#include "boat_mer.h" pulls in tiers 0–4 and the platform layer. The BLE engine headers are not in that umbrella — include them directly.| Tier | Header | What it does |
|---|---|---|
| 0 | boat_crypto.h | Ed25519 and secp256k1 keygen, signing, ecrecover, Keccak-256, SHA-256 |
| 1 | boat_identity.h | DID generation, device registration |
| 2 | boat_attest.h | SHA-256 + Ed25519, unpaid and paid submission |
| 3 | boat_nano.h, boat_pay.h | EIP-712 typed data, EIP-3009 sign / verify / settle |
| 3 | boat_lightning.h, boat_hashkey.h | additional payment integrations |
| 4 | boat_x402.h | x402 in both directions: buyer pay, seller offer |
| — | boat_buyer_nanopay.h, boat_seller_nanopay.h, boat_nano_wire.h | BLE GATT buyer and seller engines |
| — | boat_pal.h | platform abstraction |