2025-10-08 23:49:54 +02:00

14 KiB

title name category status tags editor contributors
WAKU-API Waku API definition Standards Track raw
reliability
application
api
protocol composition
Oleksandr Kozlov <oleksandr@status.im>
Oleksandr Kozlov <oleksandr@status.im>
Prem Chaitanya Prathi <prem@status.im>
Franck Royer <franck@status.im>

Table of contents

Abstract

This document specifies an Application Programming Interface (API) that is RECOMMENDED for developers of the WAKU2 clients to implement, and for consumers to use as a single entry point to its functionalities.

This API defines the RECOMMENDED interface for leveraging Waku protocols to send and receive messages. Application developers SHOULD use it to access capabilities for peer discovery, message routing, and peer-to-peer reliability.

TODO: This spec must be further extended to include connection health inspection, message sending, subscription and store hash queries.

Motivation

The accessibility of Waku protocols is capped by the accessibility of their implementations, and hence API. This RFC enables a concerted effort to draft an API that is simple and accessible, and provides an opinion on sane defaults.

The API defined in this document is an opinionated-by-purpose method to use the more agnostic WAKU2 protocols.

Syntax

The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC2119.

API design

IDL

A custom Interface Definition Language (IDL) in YAML is used to define the Waku API. Existing IDL Such as OpenAPI, AsyncAPI or WIT do not exactly fit the requirements for this API. Hence, instead of having the reader learn a new IDL, we propose to use a simple IDL with self-describing syntax.

An alternative would be to choose a programming language. However, such choice may express unintended opinions on the API.

Primitive types and general guidelines

  • No default means that the value is mandatory, meaning a default value implies an optional parameter.
  • Primitive types are string, int, bool, byte, enum and uint
  • Complex pre-defined types are:
    • object: object and other nested types.
    • array: iterable object containing values of all the same type.
    • result: an enum type that either contains a value or void (success), or an error (failure); The error is left to the implementor.
    • error: Left to the implementor on whether error types are string or object in the given language.
  • Usage of result is RECOMMENDED, usage of exceptions is NOT RECOMMENDED, no matter the language.

TODO: Review whether to specify categories of errors.

Language mappings

How the API definition should be translated to specific languages.

language_mappings:
  typescript:
    naming_convention:
      - functions: "camelCase"
      - variables: "camelCase"
      - types: "PascalCase"
  nim:
    naming_convention:
      - functions: "camelCase"
      - variables: "camelCase"
      - types: "PascalCase"

Application

This API is designed for generic use and ease across all programming languages, for edge and core type nodes.

The Waku API

api_version: "0.0.1"
library_name: "waku"
description: "Waku: a private and censorship-resistant message routing library."

Initialise Waku node

Type definitions

types:
  WakuNode:
    type: object
    description: "A Waku node instance."

  NodeConfig:
    type: object
    fields:
      mode:
        type: string
        constraints: [ "edge", "core" ]
        default: "core" # "edge" for mobile and browser devices.
        description: "The mode of operation of the Waku node; 'edge' of the network: relies on other nodes for message routing; 'core' of the network: fully participate to message routing."
      protocols_config:
        type: ProtocolsConfig
        default: TheWakuNetworkPreset
      networking_config:
        type: NetworkConfig
        default: DefaultNetworkingConfig 
      eth_rpc_endpoints:
        type: array<string>
        description: "Eth/Web3 RPC endpoint URLs, only required when RLN is used for message validation; fail-over available by passing multiple URLs. Accepting an object for ETH RPC will be added at a later stage."

  ProtocolsConfig:
    type: object
    fields:
      entry_nodes:
        type: array<string>
        default: []
        description: "Nodes to connect to; used for discovery bootstrapping and quick connectivity. enrtree and multiaddr formats are accepted. If not provided, node does not bootstrap to the network (local dev)."
      static_store_nodes:
        type: array<string>
        default: []
        # TODO: confirm behaviour at implementation time.
        description: "The passed nodes are prioritised for store queries."
      cluster_id:
        type: uint
      auto_sharding_config:
        type: AutoShardingConfig
        default: DefaultAutoShardingConfig
        description: "The auto-sharding config, if sharding mode is `auto`"
      message_validation:
        type: MessageValidation
        description: "If the default config for TWN is not used, then we still provide default configuration for message validation." 
        default: DefaultMessageValidation

  NetworkingConfig:
    type: object
    fields:
      listen_ipv4:
        type: string
        default: "0.0.0.0"
        description: "The network IP address on which libp2p and discv5 listen for inbound connections. Not applicable for some environments such as the browser." 
      p2p_tcp_port:
        type: uint
        default: 60000
        description: "The TCP port used for libp2p, relay, etc aka, general p2p message routing. Not applicable for some environments such as the browser."
      discv5_udp_port:
        type: uint
        default: 9000
        description: "The UDP port used for discv5. Not applicable for some environments such as the browser."

  AutoShardingConfig:
    type: object
    fields:
      num_shards_in_cluster:
        type: uint
        description: "The number of shards in the configured cluster; this is a globally agreed value for each cluster."

  MessageValidation:
    type: object
    fields:
      max_message_size:
        type: string
        default: "150 KiB"
        description: "Maximum message size. Accepted units: KiB, KB, and B. e.g. 1024KiB; 1500 B; etc."
      # For now, RLN is the only message validation available
      rln_config:
        type: RlnConfig
        # If the default config for TWN is not used, then we do not apply RLN
        default: none

  RlnConfig:
    type: object
    fields:
      contract_address:
        type: string
        description: "The address of the RLN contract exposes `root` and `getMerkleRoot` ABIs"
      chain_id:
        type: uint
        description: "The chain id on which the RLN contract is deployed"
      epoch_size_sec:
        type: uint
        description: "The epoch size to use for RLN, in seconds"

Function definitions

functions:
  createNode:
    description: "Initialise a Waku node instance"
    parameters:
      - name: nodeConfig
        type: NodeConfig
        description: "The Waku node configuration."
    returns:
        type: result<WakuNode, error>

Predefined values

values:

  DefaultNetworkingConfig:
    type: NetworkConfig
    fields:
      listen_ipv4: "0.0.0.0"
      p2p_tcp_port: 60000
      discv5_udp_port: 9000

  TheWakuNetworkPreset:
    type: ProtocolsConfig
    fields:
      entry_nodes: [ "enrtree://AIRVQ5DDA4FFWLRBCHJWUWOO6X6S4ZTZ5B667LQ6AJU6PEYDLRD5O@sandbox.waku.nodes.status.im" ]
      # On TWN, we encourage the usage of discovered store nodes
      static_store_nodes: []
      cluster_id: 1
      auto_sharding_config:
        fields:
          num_shards_in_cluster: 8
      message_validation: TheWakuNetworkMessageValidation

  TheWakuNetworkMessageValidation:
    type: MessageValidation
    fields:
      max_message_size: "150 KiB"
      rln_config:
        fields:
          contract_address: "0xB9cd878C90E49F797B4431fBF4fb333108CB90e6"
          chain_id: 59141
          epoch_size_sec: 600 # 10 minutes

  # If not preset is used, autosharding on one cluster is applied by default
  # This is a safe default that abstract shards (content topic shard derivation), and it enables scaling at a later stage
  DefaultAutoShardingConfig:
    type: AutoShardingConfig
    fields:
      num_shards_in_cluster: 1

  # If no preset is used, we only apply a max size limit to messages
  DefaultMessageValidation:
    type: MessageValidation
    fields:
      max_message_size: "150 KiB"
      rln_config: none

Extended definitions

mode:

If the mode set is edge, the initialised WakuNode SHOULD use:

If the mode set is core, the initialised WakuNode SHOULD use:

edge mode SHOULD be used if node functions in resource restricted environment, whereas core SHOULD be used if node has no strong hardware or bandwidth restrictions.

Send messages

Type definitions

types:
  SendMessage:
    type: object
    fields:
      contentTopic:
        type: string
        description: "The content topic for the message."
      payload:
        type: array<byte>
        description: "The message data to be sent."
      ephemeral:
        type: bool
        default: false
        description: "Whether the message is ephemeral. Read at [ATTRIBUTES](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/14/message.md#message-attributes)"
      rateLimitProof:
        type: array<byte>
        default: none
        description: "Rate limiting proof needed for [PUBLISHING](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/17/rln-relay.md#publishing)"

  RequestId:
    type: string
    description: "A unique identifier for a request"

Function definitions

functions:
  send:
    description: "Send a message through the network."
    parameters:
      - name: message
        type: SendMessage
        description: "The message to send"
    returns:
      type: result<RequestId, error>

Extended definitions

When message is sent with contentTopic for a first time, the node SHOULD trigger a subscription based on Subscribe to messages section.

Additionally, the node SHOULD initiate recurring STORE queries to validate if sent message was stored on the network and static_store_nodes SHOULD be prioritised.

The Validation API

WAKU2-RLN-RELAY is currently the primary message validation mechanism in place.

Work is scheduled to specify a validate API to enable plug-in validation. As part of this API, it will be expected that a validation object can be passed, that would contain all validation parameters including RLN.

In the time being, parameters specific to RLN are accepted for the message validation. RLN can also be disabled.

Security/Privacy Considerations

See WAKU2-ADVERSARIAL-MODELS.

Copyright and related rights waived via CC0.