# API design and consistency We have a few interfaces to configure a Delivery node: CLI, library (Nim / C-bindings), REST. We should agree which is for which role, and what each looks like. ## Discussions - https://github.com/logos-messaging/logos-delivery/issues/3795 - https://github.com/logos-messaging/logos-delivery/pull/3828 - https://github.com/logos-messaging/logos-delivery/pull/3828#issuecomment-4317261531 - https://github.com/logos-messaging/logos-delivery/pull/3828#issuecomment-4337495581 - https://github.com/logos-messaging/logos-delivery/pull/3828#issuecomment-4353802313 - https://github.com/logos-co/logos-delivery-module/issues/18 ## Roles - **App developer** — sends/receives messages on a known network. - **Node operator** — runs a fleet node 24/7. - **Tester (DST / QA)** — drives custom configs, often many nodes per host. ## Requirements - **No breaking changes.** Soft deprecations are fine. - **Good defaults.** App developers should get a working node from a one-liner. - **Flexibility for node operators.** Every preset/mode-controlled value must be overridable by an explicit field (#3795). ## Principles 1. Every node starts from a `WakuNodeConf`. Every interface must produce one deterministically: ```mermaid flowchart LR CLI["CLI flags
--preset, --tcp-port, --relay, ..."] -->|build| Conf Msg["Library: Messaging API
preset, mode, overrides"] -->|build| Conf Full["Library:
full WakuNodeConf"] -->|pass| Conf Conf[WakuNodeConf] --> Waku["Waku.new(conf)"] ``` 2. Different interfaces don't need identical argument lists. Each is shaped for its role. 3. Developer gets a shortcut: `(preset, mode, overrides?)`. They never assemble a full `WakuNodeConf`. 4. Operator gets the full `WakuNodeConf` surface. ## Problems 1. **No `(preset, mode)` entry point.** The library only has `createNode(conf: WakuNodeConf)`: https://github.com/logos-messaging/logos-delivery/blob/75864a705ea0b913d517a5f3640747f8709e9e53/waku/api/api.nim#L16 and the C FFI mirror at: https://github.com/logos-messaging/logos-delivery/blob/75864a705ea0b913d517a5f3640747f8709e9e53/liblogosdelivery/logos_delivery_api/node_api.nim#L94-L96 The Messaging API shape doesn't exist. 2. **`logosdelivery_create_node(configJson)` mixes Messaging-API and full-CLI fields in the same blob.** A caller can pass `"preset": "twn"` next to any of ~80 `WakuNodeConf` fields. 3. **`--preset` overrides aren't uniform.** Some preset-controlled fields silently win, some warn, some get overridden. Behaviour differs per field. 4. **Cluster-id implicitly selects a preset.** [`cli_args.nim:926-935`](tools/confutils/cli_args.nim#L926-L935) infers presets from `--cluster-id=1` / `--cluster-id=2` and only warns. Implicit and confusing. > See also [`ffi-libraries.md`](ffi-libraries.md) for the separate question of consolidating the two C FFI libraries. ## Proposal ### Library Two entry points, both produce a `WakuNodeConf` and call the same `Waku.new(...)`: | Entry point | Audience | |-|-| | `createNode(preset, mode, overrides?)` | Developer (Messaging API) | | `createNode(conf: WakuNodeConf)` | Tester, advanced tooling | ### CLI Full `WakuNodeConf` surface. `--preset` is a shortcut for network-level params; explicit flags override. **`--mode` should be removed.** Today it is purely a protocol-toggle shortcut ([`cli_args.nim:1126-1144`](tools/confutils/cli_args.nim#L1126-L1144)) — six `withRelay` / `withLightPush` / `withFilter…` / `withDiscv5` / `withPeerExchange` / `withRendezvous` calls plus a rate-limit default. Nothing else. So it overlaps with the explicit protocol flags an operator already uses, and it doesn't carry any of the broader meaning the Messaging API's `mode` is supposed to have. Keep it on the CLI only if DST/QA actually depend on the shortcut. If they do, this should be the documented reason. If they don't, drop it. ## Code changes 1. **Add `(preset, mode, overrides?)` to the library Messaging API.** - In [`waku/api/api.nim`](waku/api/api.nim): a new `createNode` overload that builds a `WakuNodeConf` from `(preset, mode, overrides)` and delegates to the existing one. - Mirror in [`liblogosdelivery`](liblogosdelivery/logos_delivery_api/node_api.nim) — either a dedicated FFI call or a documented Messaging-API JSON shape (`{"preset": "...", "mode": "...", "overrides": {...}}`). - Define `WakuNodeConfOverrides` (likely `Option[T]` per field, derived from `WakuNodeConf`). 2. **Audit preset overrides.** For every field set by [`NetworkConf`](waku/factory/networks_config.nim#L20-L36), confirm: explicit override wins; warning is logged; resulting config validated. 3. **Drop cluster-id → preset auto-mapping.** Soft-deprecate first ([`cli_args.nim:926-935`](tools/confutils/cli_args.nim#L926-L935)), remove in a later release.
What --preset sets See [`waku/factory/networks_config.nim`](waku/factory/networks_config.nim). A preset fills in: `entryNodes`, `clusterId`, `numShardsInCluster`, `maxMessageSize`, RLN config (contract, chain id, epoch, message limit), discv5 bootstrap, kad bootstrap, `mix`, `p2pReliability`.
What mode means **In CLI today** ([`cli_args.nim:1126-1144`](tools/confutils/cli_args.nim#L1126-L1144)) A protocol-toggle shortcut. Nothing more. - `Core` / `Edge` / `noMode` **What `mode` should mean (Messaging API)** A developer-facing role/profile. The app developer says "my app is a Core participant" or "my app is an Edge consumer", and the library translates that into a coherent set of defaults. But also, Messaging API runs background routines, which is not the case when one would use existing `--mode` from CLI. This is why `mode` doesn't fit the CLI: an operator wiring a fleet by hand picks each of those values explicitly. And it should not be look like they're using anything close to Messaging API. And note that in Messaging API `noMode` is impossible.