Skip to content
Merged
Changes from 35 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
93bd790
Propose custom IDL for Waku API definition
fryorcraken Jun 17, 2025
e013c15
add language translation
fryorcraken Jun 18, 2025
adaba54
typos and types
fryorcraken Jun 24, 2025
d5c688a
set default value
fryorcraken Jun 24, 2025
95ebcd9
Reducing prescription re language mapping
fryorcraken Jun 24, 2025
25984c0
Remove shard relay subscription for init config
fryorcraken Jun 30, 2025
73354fd
Only specify nim and TS naming convention
fryorcraken Jun 30, 2025
2096211
remove extra
fryorcraken Jun 30, 2025
b20f5fd
rename RFC
fryorcraken Jun 30, 2025
4ca0e08
rework structure, include feedback
fryorcraken Jun 30, 2025
6289f91
wip
fryorcraken Jul 21, 2025
e92d2f8
Change `init` to `create`
fryorcraken Aug 5, 2025
1e312bc
update sharding defaults from previous discussions
fryorcraken Aug 5, 2025
6a37950
user snake case for field names
fryorcraken Aug 5, 2025
bebbe8b
Add message validation
fryorcraken Aug 6, 2025
872115a
Apply suggestion from @chaitanyaprem
fryorcraken Sep 9, 2025
1ec7527
rename function to `createNode`
fryorcraken Sep 9, 2025
f1225e1
Add web3 RPC API URLs
fryorcraken Sep 9, 2025
b2b81b4
remove multiaddr type
fryorcraken Sep 10, 2025
f68707e
default network message validation
fryorcraken Sep 10, 2025
cf84d3d
Move eth rpc endpoints to top
fryorcraken Sep 10, 2025
a3c37c1
if a default is possible it means values are optional
fryorcraken Sep 10, 2025
0004fff
if a default is possible it means values are optional
fryorcraken Sep 10, 2025
6c01164
only auto sharding, remove mix up on option
fryorcraken Sep 11, 2025
4045000
use "waku config"
fryorcraken Sep 12, 2025
f834dc4
by default no static store nodes are passed
fryorcraken Sep 12, 2025
5bb37c2
update networking section
fryorcraken Sep 15, 2025
a0700f0
results may return void
fryorcraken Sep 25, 2025
6de55db
change confirmation to store/filter
fryorcraken Sep 25, 2025
036fe61
change to seed nodes
fryorcraken Sep 25, 2025
4ab8821
change address to ipv4
fryorcraken Sep 25, 2025
fa5bf8c
finish sentence
fryorcraken Sep 25, 2025
9d5191f
static store default value
fryorcraken Sep 25, 2025
616306e
Mention trait approach for ETH RPC
fryorcraken Sep 25, 2025
388c257
add toc
fryorcraken Sep 25, 2025
ad4fb96
prefer `entry_nodes`
fryorcraken Sep 26, 2025
0c64eaa
integrate feedback
fryorcraken Sep 26, 2025
82181bf
fix inconsistencies
fryorcraken Sep 26, 2025
09e3ade
clarify scope
fryorcraken Sep 26, 2025
34b9443
raw spec
fryorcraken Sep 26, 2025
214ee73
note on errors
fryorcraken Sep 26, 2025
7748d6a
add metadata
fryorcraken Sep 26, 2025
b9454e3
change "relay" to "sovereign"
fryorcraken Sep 26, 2025
6a421f5
change "sovereign" to "core"
fryorcraken Sep 26, 2025
5cd0080
remove message confirmation
fryorcraken Sep 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
327 changes: 327 additions & 0 deletions standards/application/waku-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,327 @@
---
title: WAKU-API
name: Waku API definition
category: Standards Track
tags: [reliability, application, api, protocol composition]
editor: Oleksandr Kozlov <oleksandr@status.im>
contributors:
- Oleksandr Kozlov <oleksandr@status.im>
- Prem Chaitanya Prathi <prem@status.im>
- Franck Royer <franck@status.im>
---

## Table of contents

<!-- TOC -->
* [Table of contents](#table-of-contents)
* [Abstract](#abstract)
* [Motivation](#motivation)
* [Syntax](#syntax)
* [API design](#api-design)
* [IDL](#idl)
* [Primitive types and general guidelines](#primitive-types-and-general-guidelines)
* [Language mappings](#language-mappings)
* [Application](#application)
* [The Waku API](#the-waku-api)
* [Initialise Waku node](#initialise-waku-node)
* [Type definitions](#type-definitions)
* [Function definitions](#function-definitions)
* [Predefined values](#predefined-values)
* [Extended definitions](#extended-definitions)
* [The Validation API](#the-validation-api)
* [Security/Privacy Considerations](#securityprivacy-considerations)
* [Copyright](#copyright)
<!-- TOC -->

## Abstract

This document specifies an Application Programming Interface (API) that is RECOMMENDED for developers of the [WAKU2](https://github.com/vacp2p/rfc-index/blob/7b443c1aab627894e3f22f5adfbb93f4c4eac4f6/waku/standards/core/10/waku2.md) 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.

## 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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The API defined in this document is an opinionated-by-purpose method to use the more agnostic [WAKU2]() protocols.
The API defined in this document is an opinionated-by-purpose method to use the more agnostic [WAKU2](https://github.com/vacp2p/rfc-index/blob/7b443c1aab627894e3f22f5adfbb93f4c4eac4f6/waku/standards/core/10/waku2.md) 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](https://www.ietf.org/rfc/rfc2119.txt).

## 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`, `enum` and `uint`
- Complex pre-defined types are:
- `struct`: object and other nested types.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: by being biased by high level languages I would prefer object instead of struct

- `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.

### Language mappings

How the API definition should be translated to specific languages.

```yaml
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 `relay` type nodes.

## The Waku API

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

### Initialise Waku node

#### Type definitions

```yaml
types:
WakuNode:
type: struct
description: "A Waku node instance."

NodeConfig:
type: struct
fields:
mode:
type: string
constraints: [ "edge", "relay" ]
default: "_platform dependent_"
description: "The mode of operation of the Waku node. Core protocols used by the node are inferred from this mode."
waku_config:
type: WakuConfig
default: TheWakuNetworkPreset
message_confirmation:
type: array<string>
constraints: [ "store", "filter" ]
# Until further dogfooding, assuming default false, usage of SDS should be preferred
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why we mention SDS here as it is in dogfooding / experimental stage too

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed, what I mean is that I expect we change the default in the future.

default: [ "none" ]
Copy link
Copy Markdown
Contributor

@Ivansete-status Ivansete-status Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EDITED:

I think we don't need that message_confirmation parameter. That can be considered internally as per the given operation mode (edge, relay.)


EDITED: disregard the following comment. I was confused.

Maybe :)?

Suggested change
constraints: [ "store", "filter" ]
# Until further dogfooding, assuming default false, usage of SDS should be preferred
default: [ "none" ]
constraints: [ "none", "store", "sds" ]
# Until further dogfooding, assuming default none, usage of SDS should be preferred
default: [ "none" ]

Besides, I can't quite get why an array<string> is needed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides, I can't quite get why an array is needed

@Ivansete-status as I understand it is because we can have multiple confirmation mechanisms working at the same time filter + store

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What @weboko said: the p2p reliability strategies are not mutually exclusive.

description: "Whether to apply peer-to-peer reliability strategies to confirm that outgoing message have been received by other peers."
networking_config:
type: NetworkConfig
default: DefaultNetworkingConfig
# TODO: to be reviewed, developers have expressed that accepting an object implementing specific traits is useful.
eth_rpc_endpoints:
type: array<string>
description: "Eth/Web3 RPC endpoint URLs"

WakuConfig:
type: struct
fields:
seed_nodes:
type: array<string>
# Default means the node does not bootstrap, e.g. for local development
default: []
description: "Nodes to connect to; used for discovery bootstrapping and quick connectivity. entree and multiaddr formats are accepted."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: and we can remove the comment above

Suggested change
description: "Nodes to connect to; used for discovery bootstrapping and quick connectivity. entree and multiaddr formats are accepted."
description: "Nodes to connect to; used for discovery bootstrapping and quick connectivity. entree and multiaddr formats are accepted. If not provided, node does not bootstrap (e.g for local development)"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we ever add mDNS the comment will be false. But will add in the mean time.

static_store_nodes:
type: array<string>
default: []
description: "Only the passed nodes are used for store queries, discovered store nodes are discarded."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry if you mentioned it somewhere and I didn't see

question: why discarded? previously we were discussing it in the way that discovered nodes will be de-prioritized and used only if static store nodes are not available

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can re-adjust at implementation time. Will correct and add todo.

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
# If the default config for TWN is not used, then we still provide a message validation default
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# If the default config for TWN is not used, then we still provide a message validation default
description: If the default config for TWN is not used, then we still provide a message validation default

default: DefaultMessageValidation

NetworkingConfig:
type: string
fields:
listen_ipv4:
# Is not applicable in some environments such as browser.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: should we include comments into description? I think this gives needed context and doesn't over bloat them

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes all done

type: string
default: "0.0.0.0"
description: "The network IP address on which libp2p and discv5 listen for inbound connections"
p2p_tcp_port:
# Is not applicable in non-TCP environments such as browser
type: uint
default: 60000
description: "The TCP port used for libp2p, relay, aka, general p2p message routing."
discv5_udp_port:
# Is not applicable in non-UDP environments such as browser
type: uint
default: 9000
description: "The UDP port used for discv5."

AutoShardingConfig:
type: struct
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: struct
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: struct
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

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

#### Predefined values

```yaml
values:

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

TheWakuNetworkPreset:
type: WakuConfig
fields:
remote_nodes: [ "enrtree://AIRVQ5DDA4FFWLRBCHJWUWOO6X6S4ZTZ5B667LQ6AJU6PEYDLRD5O@sandbox.waku.nodes.status.im" ]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure it worth mentioning remote nodes and contract address as they can get outdated rather fast: unpredicted contract changes like we did recently etc.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point. I think it's fine to have it and forces us to update it as the intent is to ensure that all implementations are interoperable by default.

# On TWN, we encourage the usage of discovered store nodes
static_store_nodes: []
cluster_id: 1
auto_sharding_config:
fields:
numShardsInCluster: 8
message_validation: TheWakuNetworkMessageValidation

TheWakuNetworkMessageValidation:
type: MessageValidation
fields:
max_message_bytes_uint: 153600 # 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_bytes_uint: 153600 # 150 KiB
rln_config: none
```

#### Extended definitions

If the `mode` set is `edge`, the initialised `WakuNode` MUST mount:

- [LIGHTPUSH](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/19/lightpush.md) as client
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metadata should be loaded too.

- [FILTER](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/12/filter.md) as client
- [STORE](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/13/store.md) as client

And must use mount and use the following protocols to discover peers:

- [PEER-EXCHANGE](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/34/peer-exchange.md)

If the `mode` set is `relay`, the initialised `WakuNode` MUST mount:

- [RELAY](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/11/relay.md)
- [LIGHTPUSH](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/19/lightpush.md) as service node
- [FILTER](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/12/filter.md) as service node
- [PEER-EXCHANGE](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/34/peer-exchange.md) as service node
- [STORE](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/13/store.md) as client

And must use mount and use the following protocols to discover peers:

- [DISCV5](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/33/discv5.md)
- [PEER-EXCHANGE](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/34/peer-exchange.md)
- [RENDEZVOUS](https://github.com/waku-org/specs/blob/master/standards/core/rendezvous.md)

`edge` mode SHOULD be used if node functions in resource restricted environment,
whereas `relay` SHOULD be used if node has no strong hardware or bandwidth restrictions.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can refer to roughly estimated bandwidth and hardware specified somewhere in specs?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea, but maybe best to do that later.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm starting to think that we also need another type of node: boot
This mode makes the node to become a facilitator within the network (PX, discv5, etc.) and doesn't mount relay and doesn't mount store either.

Copy link
Copy Markdown
Contributor Author

@fryorcraken fryorcraken Sep 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I agree there is a type boot, but it is out of scope for the Waku API.
If someone wants to run a boot node, they can use wakunode2.


## The Validation API

[WAKU2-RLN-RELAY](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/17/rln-relay.md) 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](https://github.com/waku-org/specs/blob/master/informational/adversarial-models.md).

## Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
Loading