Update documentation

This commit is contained in:
Jenkins 2021-12-01 05:24:13 +00:00
parent 097610118c
commit a32d67fb90
17 changed files with 4594 additions and 11 deletions

View File

@ -84,7 +84,7 @@
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded "><a href="chapter_1.html"><strong aria-hidden="true">1.</strong> Chapter 1</a></li></ol> </div>
<ol class="chapter"><li class="chapter-item expanded affix "><a href="introduction.html">Introduction</a></li><li class="chapter-item expanded "><a href="quick_start.html"><strong aria-hidden="true">1.</strong> Quick Start</a></li><li class="chapter-item expanded "><a href="guides/index.html"><strong aria-hidden="true">2.</strong> Guides</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="guides/choose_content_topic.html"><strong aria-hidden="true">2.1.</strong> How to Choose a Content Topic</a></li><li class="chapter-item expanded "><a href="guides/relay_receive_send_messages.html"><strong aria-hidden="true">2.2.</strong> Receive and Send Messages Using Waku Relay</a></li><li class="chapter-item expanded "><a href="guides/store_retrieve_messages.html"><strong aria-hidden="true">2.3.</strong> Retrieve Messages Using Waku Store</a></li><li class="chapter-item expanded "><a href="guides/encrypt_messages_version_1.html"><strong aria-hidden="true">2.4.</strong> Encrypt Messages Using Waku Message Version 1</a></li><li class="chapter-item expanded "><a href="guides/reactjs_relay.html"><strong aria-hidden="true">2.5.</strong> Receive and Send Messages Using Waku Relay With ReactJS</a></li><li class="chapter-item expanded "><a href="guides/reactjs_store.html"><strong aria-hidden="true">2.6.</strong> Retrieve Messages Using Waku Store With ReactJS</a></li><li class="chapter-item expanded "><a href="guides/light_push_send_messages.html"><strong aria-hidden="true">2.7.</strong> Send Messages Using Waku Light Push</a></li></ol></li><li class="chapter-item expanded "><a href="examples.html"><strong aria-hidden="true">3.</strong> Examples</a></li><li class="chapter-item expanded affix "><a href="waku_protocols.html">Implemented Waku Protocols</a></li></ol> </div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>

272
examples.html Normal file
View File

@ -0,0 +1,272 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Examples - DappConnect Docs</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="custom.css">
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="introduction.html">Introduction</a></li><li class="chapter-item expanded "><a href="quick_start.html"><strong aria-hidden="true">1.</strong> Quick Start</a></li><li class="chapter-item expanded "><a href="guides/index.html"><strong aria-hidden="true">2.</strong> Guides</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="guides/choose_content_topic.html"><strong aria-hidden="true">2.1.</strong> How to Choose a Content Topic</a></li><li class="chapter-item expanded "><a href="guides/relay_receive_send_messages.html"><strong aria-hidden="true">2.2.</strong> Receive and Send Messages Using Waku Relay</a></li><li class="chapter-item expanded "><a href="guides/store_retrieve_messages.html"><strong aria-hidden="true">2.3.</strong> Retrieve Messages Using Waku Store</a></li><li class="chapter-item expanded "><a href="guides/encrypt_messages_version_1.html"><strong aria-hidden="true">2.4.</strong> Encrypt Messages Using Waku Message Version 1</a></li><li class="chapter-item expanded "><a href="guides/reactjs_relay.html"><strong aria-hidden="true">2.5.</strong> Receive and Send Messages Using Waku Relay With ReactJS</a></li><li class="chapter-item expanded "><a href="guides/reactjs_store.html"><strong aria-hidden="true">2.6.</strong> Retrieve Messages Using Waku Store With ReactJS</a></li><li class="chapter-item expanded "><a href="guides/light_push_send_messages.html"><strong aria-hidden="true">2.7.</strong> Send Messages Using Waku Light Push</a></li></ol></li><li class="chapter-item expanded "><a href="examples.html" class="active"><strong aria-hidden="true">3.</strong> Examples</a></li><li class="chapter-item expanded affix "><a href="waku_protocols.html">Implemented Waku Protocols</a></li></ol> </div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">DappConnect Docs</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/vacp2p/docs.dappconnect.dev" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="examples"><a class="header" href="#examples">Examples</a></h1>
<p>Here is the list of the code examples and the features they demonstrate.
To run or studies the example, click on the <em>repo</em> links.</p>
<h2 id="minimal-reactjs-chat-app"><a class="header" href="#minimal-reactjs-chat-app">Minimal ReactJS Chat App</a></h2>
<p>Repo: <a href="https://github.com/status-im/js-waku/tree/main/examples/min-react-js-chat">min-react-js-chat</a>.</p>
<p>Demonstrates:</p>
<ul>
<li>Group chat</li>
<li>React/JavaScript</li>
<li>Waku Relay</li>
<li>Protobuf using <a href="https://www.npmjs.com/package/protons">protons</a></li>
<li>No async/await syntax</li>
</ul>
<h2 id="minimal-reactjs-waku-store-app"><a class="header" href="#minimal-reactjs-waku-store-app">Minimal ReactJS Waku Store App</a></h2>
<p>Repo: <a href="https://github.com/status-im/js-waku/tree/main/examples/store-reactjs-chat">store-reactjs-chat</a>.</p>
<p>Demonstrates:</p>
<ul>
<li>Waku Store</li>
<li>React/JavaScript</li>
<li>Protobuf using <a href="https://www.npmjs.com/package/protons">protons</a></li>
</ul>
<h2 id="vanilla-javascript-using-minified-library"><a class="header" href="#vanilla-javascript-using-minified-library">Vanilla Javascript Using Minified Library</a></h2>
<p>Repo: <a href="https://github.com/status-im/js-waku/tree/main/examples/unpkg-js-store">unpkg-js-store</a>.</p>
<p>Demonstrates: </p>
<ul>
<li>How to stop retrieving results from Waku Store on condition</li>
<li>Use minified bundle from Unpkg.com</li>
<li>Vanilla JavaScript application</li>
</ul>
<h2 id="web-chat-app"><a class="header" href="#web-chat-app">Web Chat App</a></h2>
<p>Repo: <a href="https://github.com/status-im/js-waku/tree/main/examples/web-chat">web-chat</a>.</p>
<p>Demonstrates:</p>
<ul>
<li>Group chat</li>
<li>React/TypeScript</li>
<li>Waku Relay</li>
<li>Waku Store</li>
<li>Protobuf using .proto files + <a href="https://github.com/bufbuild/buf">bufbuild</a> + <a href="https://www.npmjs.com/package/ts-proto">ts-proto</a></li>
</ul>
<h2 id="ethereum-private-message-web-app"><a class="header" href="#ethereum-private-message-web-app">Ethereum Private Message Web App</a></h2>
<p>Repo: <a href="https://github.com/status-im/js-waku/tree/main/examples/eth-pm">eth-pm</a>.</p>
<p>Demonstrates:</p>
<ul>
<li>Private messaging</li>
<li>React/TypeScript</li>
<li>Waku Light Push</li>
<li>Signature with Web3 Wallet</li>
<li>Asymmetric Encryption</li>
<li>Symmetric Encryption</li>
<li>Protobuf using <a href="https://www.npmjs.com/package/protobufjs">protobufjs</a></li>
</ul>
<h2 id="ethereum-private-message-using-web3-wallet-encryption-api-web-app"><a class="header" href="#ethereum-private-message-using-web3-wallet-encryption-api-web-app">Ethereum Private Message Using Web3 Wallet Encryption API Web App</a></h2>
<p>Repo: <a href="https://github.com/status-im/js-waku/tree/main/examples/eth-pm-wallet-encryption">eth-pm-wallet-encryption</a>.</p>
<p>Demonstrates:</p>
<ul>
<li>Private Messaging</li>
<li>React/TypeScript</li>
<li>Waku Light Push</li>
<li>Signature with Web3 using EIP-712: <code>eth_signTypedData_v4</code></li>
<li>Asymmetric Encryption</li>
<li>Usage of <code>eth_decrypt</code> Web3 Wallet API</li>
<li>Protobuf using <a href="https://www.npmjs.com/package/protobufjs">protobufjs</a></li>
</ul>
<h2 id="uber-like-minimalistic-car-sharing-app-suing-vuejs"><a class="header" href="#uber-like-minimalistic-car-sharing-app-suing-vuejs">Uber-like minimalistic car sharing app suing Vue.js</a></h2>
<p>Repo: <a href="https://github.com/TheBojda/waku-uber">TheBojda/waku-uber</a>.</p>
<p>Article: <a href="https://hackernoon.com/decentralized-uber-heres-how-i-built-it-with-statusim-waku-and-vuejs">Decentralized Uber: Here's How I Built It With Status.im, Waku, and Vue.js</a>.</p>
<p>Demonstrates:</p>
<ul>
<li>Vue.js</li>
<li>Waku Relay</li>
<li>Protobuf using <a href="https://www.npmjs.com/package/protons">protons</a></li>
</ul>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="guides/light_push_send_messages.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="waku_protocols.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="guides/light_push_send_messages.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="waku_protocols.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>

View File

@ -0,0 +1,222 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>How to Choose a Content Topic - DappConnect Docs</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="../custom.css">
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../introduction.html">Introduction</a></li><li class="chapter-item expanded "><a href="../quick_start.html"><strong aria-hidden="true">1.</strong> Quick Start</a></li><li class="chapter-item expanded "><a href="../guides/index.html"><strong aria-hidden="true">2.</strong> Guides</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../guides/choose_content_topic.html" class="active"><strong aria-hidden="true">2.1.</strong> How to Choose a Content Topic</a></li><li class="chapter-item expanded "><a href="../guides/relay_receive_send_messages.html"><strong aria-hidden="true">2.2.</strong> Receive and Send Messages Using Waku Relay</a></li><li class="chapter-item expanded "><a href="../guides/store_retrieve_messages.html"><strong aria-hidden="true">2.3.</strong> Retrieve Messages Using Waku Store</a></li><li class="chapter-item expanded "><a href="../guides/encrypt_messages_version_1.html"><strong aria-hidden="true">2.4.</strong> Encrypt Messages Using Waku Message Version 1</a></li><li class="chapter-item expanded "><a href="../guides/reactjs_relay.html"><strong aria-hidden="true">2.5.</strong> Receive and Send Messages Using Waku Relay With ReactJS</a></li><li class="chapter-item expanded "><a href="../guides/reactjs_store.html"><strong aria-hidden="true">2.6.</strong> Retrieve Messages Using Waku Store With ReactJS</a></li><li class="chapter-item expanded "><a href="../guides/light_push_send_messages.html"><strong aria-hidden="true">2.7.</strong> Send Messages Using Waku Light Push</a></li></ol></li><li class="chapter-item expanded "><a href="../examples.html"><strong aria-hidden="true">3.</strong> Examples</a></li><li class="chapter-item expanded affix "><a href="../waku_protocols.html">Implemented Waku Protocols</a></li></ol> </div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">DappConnect Docs</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/vacp2p/docs.dappconnect.dev" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="how-to-choose-a-content-topic"><a class="header" href="#how-to-choose-a-content-topic">How to Choose a Content Topic</a></h1>
<p>A content topic is used for content based filtering.</p>
<p>It allows you to filter out the messages that your dApp processes,
both when receiving live messages (Relay) or retrieving historical messages (Store).</p>
<p>The format for content topics is as follows:</p>
<p><code>/{dapp-name}/{version}/{content-topic-name}/{encoding}</code></p>
<ul>
<li><code>dapp-name</code>: The name of your dApp, it must be unique to avoid conflict with other dApps.</li>
<li><code>version</code>: We usually start at <code>1</code>, useful when introducing breaking changes in your messages.</li>
<li><code>content-topic-name</code>: The actual content topic name to use for filtering.
If your dApp uses DappConnect for several features,
you should use a content topic per feature.</li>
<li><code>encoding</code>: The encoding format of the message, Protobuf is most often used: <code>proto</code>.</li>
</ul>
<p>For example: Your dApp's name is SuperCrypto,
it enables users to receive notifications and send private messages.
You may want to use the following content topics:</p>
<ul>
<li><code>/supercrypto/1/notification/proto</code></li>
<li><code>/supercrypto/1/private-message/proto</code></li>
</ul>
<p>You can learn more about Waku topics in the <a href="https://rfc.vac.dev/spec/23/">23/WAKU2-TOPICS</a> specs.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../guides/index.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../guides/relay_receive_send_messages.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../guides/index.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../guides/relay_receive_send_messages.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>

View File

@ -0,0 +1,358 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Encrypt Messages Using Waku Message Version 1 - DappConnect Docs</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="../custom.css">
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../introduction.html">Introduction</a></li><li class="chapter-item expanded "><a href="../quick_start.html"><strong aria-hidden="true">1.</strong> Quick Start</a></li><li class="chapter-item expanded "><a href="../guides/index.html"><strong aria-hidden="true">2.</strong> Guides</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../guides/choose_content_topic.html"><strong aria-hidden="true">2.1.</strong> How to Choose a Content Topic</a></li><li class="chapter-item expanded "><a href="../guides/relay_receive_send_messages.html"><strong aria-hidden="true">2.2.</strong> Receive and Send Messages Using Waku Relay</a></li><li class="chapter-item expanded "><a href="../guides/store_retrieve_messages.html"><strong aria-hidden="true">2.3.</strong> Retrieve Messages Using Waku Store</a></li><li class="chapter-item expanded "><a href="../guides/encrypt_messages_version_1.html" class="active"><strong aria-hidden="true">2.4.</strong> Encrypt Messages Using Waku Message Version 1</a></li><li class="chapter-item expanded "><a href="../guides/reactjs_relay.html"><strong aria-hidden="true">2.5.</strong> Receive and Send Messages Using Waku Relay With ReactJS</a></li><li class="chapter-item expanded "><a href="../guides/reactjs_store.html"><strong aria-hidden="true">2.6.</strong> Retrieve Messages Using Waku Store With ReactJS</a></li><li class="chapter-item expanded "><a href="../guides/light_push_send_messages.html"><strong aria-hidden="true">2.7.</strong> Send Messages Using Waku Light Push</a></li></ol></li><li class="chapter-item expanded "><a href="../examples.html"><strong aria-hidden="true">3.</strong> Examples</a></li><li class="chapter-item expanded affix "><a href="../waku_protocols.html">Implemented Waku Protocols</a></li></ol> </div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">DappConnect Docs</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/vacp2p/docs.dappconnect.dev" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="encrypt-messages-using-waku-message-version-1"><a class="header" href="#encrypt-messages-using-waku-message-version-1">Encrypt Messages Using Waku Message Version 1</a></h1>
<p>The Waku Message format provides an easy way to encrypt messages using symmetric or asymmetric encryption.
The encryption comes with several handy <a href="https://rfc.vac.dev/spec/26/#design-requirements">design requirements</a>:
confidentiality, authenticity and integrity.</p>
<p>You can find more details about Waku Message Payload Encryption in <a href="https://rfc.vac.dev/spec/26/">26/WAKU-PAYLOAD</a>.</p>
<h2 id="what-data-is-encrypted"><a class="header" href="#what-data-is-encrypted">What data is encrypted</a></h2>
<p>With Waku Message Version 1, the entire payload is encrypted.</p>
<p>Which means that the only discriminating data available in clear text is the content topic and timestamp (if present).
Hence, if Alice expects to receive messages under a given content topic, she needs to try to decrypt all messages received on said content topic.</p>
<p>This needs to be kept in mind for scalability and forward secrecy concerns:</p>
<ul>
<li>If there is high traffic on a given content topic then all clients need to process and attempt decryption of all messages with said content topic;</li>
<li>If a content topic is only used by a given (group of) user(s) then it is possible to deduce some information about said user(s) communications such as sent time and frequency of messages.</li>
</ul>
<h2 id="key-management"><a class="header" href="#key-management">Key management</a></h2>
<p>By using Waku Message Version 1, you will need to provide a way to your users to generate and store keys in a secure manner.
Storing, backing up and recovering key is out of the scope of this guide.</p>
<p>If key recovery is important for your dApp, then check out
<a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/wrapKey">SubtleCrypto.wrapKey()</a> which can be used to securely store or export private keys.</p>
<p>An example to save and load a key pair in local storage, protected with a password, can be found in <a href="https://github.com/status-im/js-waku/blob/main/examples/eth-pm/src/key_pair_handling/key_pair_storage.ts">Eth-PM</a>.</p>
<h2 id="which-encryption-method-should-i-use"><a class="header" href="#which-encryption-method-should-i-use">Which encryption method should I use?</a></h2>
<p>Whether you should use symmetric or asymmetric encryption depends on your use case.</p>
<p><strong>Symmetric</strong> encryption is done using a single key to encrypt and decrypt.</p>
<p>Which means that if Alice knows the symmetric key <code>K</code> and uses it to encrypt a message,
she can also use <code>K</code> to decrypt any message encrypted with <code>K</code>,
even if she is not the sender.</p>
<p>Group chats is a possible use case for symmetric encryption:
All participants can use an out-of-band method to agree on a <code>K</code>.
Participants can then use <code>K</code> to encrypt and decrypt messages within the group chat.
Participants MUST keep <code>K</code> secret to ensure that no external party can decrypt the group chat messages.</p>
<p><strong>Asymmetric</strong> encryption is done using a key pair:
the public key is used to encrypt messages,
the matching private key is used to decrypt messages.</p>
<p>For Alice to encrypt a message for Bob, she needs to know Bob's Public Key <code>K</code>.
Bob can then use his private key <code>k</code> to decrypt the message.
As long as Bob keep his private key <code>k</code> secret, then he, and only he, can decrypt messages encrypted with <code>K</code>.</p>
<p>Private 1:1 messaging is a possible use case for asymmetric encryption:
When Alice sends an encrypted message for Bob, only Bob can decrypt it.</p>
<h2 id="symmetric-encryption"><a class="header" href="#symmetric-encryption">Symmetric Encryption</a></h2>
<h3 id="generate-key"><a class="header" href="#generate-key">Generate Key</a></h3>
<p>To use symmetric encryption, you first need to generate a key.
Use <code>generateSymmetricKey</code> for secure key generation:</p>
<pre><code class="language-js">import { generateSymmetricKey } from 'js-waku';
const symmetricKey = generateSymmetricKey();
</code></pre>
<h3 id="encrypt-message"><a class="header" href="#encrypt-message">Encrypt Message</a></h3>
<p>To encrypt a message with the previously generated key,
pass the key in the <code>symKey</code> property to <code>WakuMessage.fromBytes</code>.</p>
<p>Same as Waku Messages version 0 (unencrypted),
<code>payload</code> is your message payload and <code>contentTopic</code> is the content topic for your dApp.
See <a href="./relay_receive_send_messages.html">Receive and Send Messages Using Waku Relay</a> for details.</p>
<pre><code class="language-js">import { WakuMessage } from 'js-waku';
const message = await WakuMessage.fromBytes(payload, contentTopic, {
symKey: symmetricKey
});
</code></pre>
<p>The Waku Message can then be sent to the Waku network using Waku Relay or Waku Light Push:</p>
<pre><code class="language-js">await waku.lightPush.push(message);
</code></pre>
<h3 id="decrypt-messages"><a class="header" href="#decrypt-messages">Decrypt Messages</a></h3>
<p>To decrypt messages,
whether they are received over Waku Relay or using Waku Store,
add the symmetric key as a decryption key to your Waku instance.</p>
<pre><code class="language-js">waku.addDecryptionKey(symmetricKey);
</code></pre>
<p>Alternatively, you can pass the key when creating the instance:</p>
<pre><code class="language-js">import { Waku } from 'js-waku';
const waku = Waku.create({ decryptionKeys: [symmetricKey] });
</code></pre>
<p>It will attempt to decrypt any message it receives using the key, for both symmetric and asymmetric encryption.</p>
<p>You can call <code>addDecryptionKey</code> several times if you are using multiple keys,
symmetric key and asymmetric private keys can be used together.</p>
<p>Messages that are not successfully decrypted are dropped.</p>
<h2 id="asymmetric-encryption"><a class="header" href="#asymmetric-encryption">Asymmetric Encryption</a></h2>
<h3 id="generate-key-pair"><a class="header" href="#generate-key-pair">Generate Key Pair</a></h3>
<p>To use asymmetric encryption, you first need to generate a private key and calculate the corresponding public key.
Use <code>generatePrivateKey</code> for secure key generation:</p>
<pre><code class="language-js">import { generatePrivateKey, getPublicKey } from 'js-waku';
const privateKey = generatePrivateKey();
const publicKey = getPublicKey(privateKey);
</code></pre>
<p>The private key must be securely stored and remain private.
If leaked then other parties may be able to decrypt the user's messages.</p>
<p>The public key is unique for a given private key and can always be recovered given the private key,
hence it is not needed to save it as long as as the private key can be recovered.</p>
<h3 id="encrypt-message-1"><a class="header" href="#encrypt-message-1">Encrypt Message</a></h3>
<p>The public key is used to encrypt messages;
to do so, pass it in the <code>encPublicKey</code> property to <code>WakuMessage.fromBytes</code>.</p>
<p>Same as clear Waku Messages,
<code>payload</code> is your message payload and <code>contentTopic</code> is the content topic for your dApp.
See <a href="./relay_receive_send_messages.html">Receive and Send Messages Using Waku Relay</a> for details.</p>
<pre><code class="language-js">import { WakuMessage } from 'js-waku';
const message = await WakuMessage.fromBytes(payload, contentTopic, {
encPublicKey: publicKey
});
</code></pre>
<p>The Waku Message can then be sent to the Waku network using Waku Relay or Waku Light Push:</p>
<pre><code class="language-js">await waku.lightPush.push(message);
</code></pre>
<h3 id="decrypt-messages-1"><a class="header" href="#decrypt-messages-1">Decrypt Messages</a></h3>
<p>The private key is needed to decrypt messages.</p>
<p>To decrypt messages,
whether they are received over Waku Relay or using Waku Store,
add the private key as a decryption key to your Waku instance.</p>
<pre><code class="language-js">waku.addDecryptionKey(privateKey);
</code></pre>
<p>Alternatively, you can pass the key when creating the instance:</p>
<pre><code class="language-js">import { Waku } from 'js-waku';
const waku = Waku.create({ decryptionKeys: [privateKey] });
</code></pre>
<p>It will attempt to decrypt any message it receives using the key, for both symmetric and asymmetric encryption.</p>
<p>You can call <code>addDecryptionKey</code> several times if you are using multiple keys,
symmetric key and asymmetric private keys can be used together.</p>
<p>Messages that are not successfully decrypted are dropped.</p>
<h2 id="handling-wakumessage-instances"><a class="header" href="#handling-wakumessage-instances">Handling <code>WakuMessage</code> instances</a></h2>
<p>When creating a Waku Message using <code>WakuMessage.fromBytes</code> with an encryption key (symmetric or asymmetric),
the payload gets encrypted.
Which means that <code>wakuMessage.payload</code> returns an encrypted payload:</p>
<pre><code class="language-js">import { WakuMessage } from 'js-waku';
const message = await WakuMessage.fromBytes(payload, contentTopic, {
encPublicKey: publicKey
});
console.log(message.payload); // This is encrypted
</code></pre>
<p>However, <code>WakuMessage</code> instances returned by <code>WakuRelay</code> or <code>WakuStore</code> are always decrypted.</p>
<p><code>WakuRelay</code> and <code>WakuStore</code> never return messages that are encrypted.
If a message was not successfully decrypted, then it will be dropped from the results.</p>
<p>Which means that <code>WakuMessage</code> instances returned by <code>WakuRelay</code> and <code>WakuStore</code> always have a clear payload (in regard to Waku Message version 1):</p>
<pre><code class="language-js">import { Waku } from 'js-waku';
const waku = Waku.create({ decryptionKeys: [privateKey] });
const messages = await waku.store.queryHistory([contentTopic]);
if (messages &amp;&amp; messages[0]) {
console.log(messages[0].payload); // This payload is decrypted
}
waku.relay.addObserver((message) =&gt; {
console.log(message.payload); // This payload is decrypted
}, [contentTopic]);
</code></pre>
<h2 id="code-example"><a class="header" href="#code-example">Code Example</a></h2>
<p>The <a href="https://github.com/status-im/js-waku/tree/main/examples/eth-pm">Eth-PM</a> Web App example demonstrates both the use of symmetric and asymmetric encryption.</p>
<p>Asymmetric encryption is used for private messages so that only the intended recipient can read said messages.</p>
<p>Symmetric encryption is used for the public key messages.
In this instance, the same key is used for all users: the Keccak-256 hash of the content topic (which results in 32 bytes array).
While this does not add functional value, it does demonstrate the usage of symmetric encryption in a web app.</p>
<p>A live version of Eth-PM can be found at https://status-im.github.io/js-waku/eth-pm/.</p>
<p>The specifications of the protocol it implements can be found at <a href="https://rfc.vac.dev/spec/20/">20/TOY-ETH-PM</a>.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../guides/store_retrieve_messages.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../guides/reactjs_relay.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../guides/store_retrieve_messages.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../guides/reactjs_relay.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>

217
guides/index.html Normal file
View File

@ -0,0 +1,217 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Guides - DappConnect Docs</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="../custom.css">
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../introduction.html">Introduction</a></li><li class="chapter-item expanded "><a href="../quick_start.html"><strong aria-hidden="true">1.</strong> Quick Start</a></li><li class="chapter-item expanded "><a href="../guides/index.html" class="active"><strong aria-hidden="true">2.</strong> Guides</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../guides/choose_content_topic.html"><strong aria-hidden="true">2.1.</strong> How to Choose a Content Topic</a></li><li class="chapter-item expanded "><a href="../guides/relay_receive_send_messages.html"><strong aria-hidden="true">2.2.</strong> Receive and Send Messages Using Waku Relay</a></li><li class="chapter-item expanded "><a href="../guides/store_retrieve_messages.html"><strong aria-hidden="true">2.3.</strong> Retrieve Messages Using Waku Store</a></li><li class="chapter-item expanded "><a href="../guides/encrypt_messages_version_1.html"><strong aria-hidden="true">2.4.</strong> Encrypt Messages Using Waku Message Version 1</a></li><li class="chapter-item expanded "><a href="../guides/reactjs_relay.html"><strong aria-hidden="true">2.5.</strong> Receive and Send Messages Using Waku Relay With ReactJS</a></li><li class="chapter-item expanded "><a href="../guides/reactjs_store.html"><strong aria-hidden="true">2.6.</strong> Retrieve Messages Using Waku Store With ReactJS</a></li><li class="chapter-item expanded "><a href="../guides/light_push_send_messages.html"><strong aria-hidden="true">2.7.</strong> Send Messages Using Waku Light Push</a></li></ol></li><li class="chapter-item expanded "><a href="../examples.html"><strong aria-hidden="true">3.</strong> Examples</a></li><li class="chapter-item expanded affix "><a href="../waku_protocols.html">Implemented Waku Protocols</a></li></ol> </div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">DappConnect Docs</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/vacp2p/docs.dappconnect.dev" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="guides"><a class="header" href="#guides">Guides</a></h1>
<h2 id="waku-concepts"><a class="header" href="#waku-concepts">Waku Concepts</a></h2>
<ul>
<li><a href="choose_content_topic.html">How to Choose a Content Topic</a></li>
</ul>
<h2 id="javascript"><a class="header" href="#javascript">JavaScript</a></h2>
<ul>
<li><a href="relay_receive_send_messages.html">Receive and Send Messages Using Waku Relay</a></li>
<li><a href="store_retrieve_messages.html">Retrieve Messages Using Waku Store</a></li>
<li><a href="encrypt_messages_version_1.html">Encrypt Messages Using Waku Message Version 1</a></li>
<li><a href="light_push_send_messages.html">Send Messages Using Waku Light Push</a></li>
</ul>
<h2 id="reactjs"><a class="header" href="#reactjs">ReactJS</a></h2>
<ul>
<li><a href="reactjs_relay.html">Receive and Send Messages Using Waku Relay With ReactJS</a></li>
<li><a href="reactjs_store.html">Retrieve Messages Using Waku Store With ReactJS</a></li>
</ul>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../quick_start.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../guides/choose_content_topic.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../quick_start.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../guides/choose_content_topic.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>

View File

@ -0,0 +1,257 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Send Messages Using Waku Light Push - DappConnect Docs</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="../custom.css">
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../introduction.html">Introduction</a></li><li class="chapter-item expanded "><a href="../quick_start.html"><strong aria-hidden="true">1.</strong> Quick Start</a></li><li class="chapter-item expanded "><a href="../guides/index.html"><strong aria-hidden="true">2.</strong> Guides</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../guides/choose_content_topic.html"><strong aria-hidden="true">2.1.</strong> How to Choose a Content Topic</a></li><li class="chapter-item expanded "><a href="../guides/relay_receive_send_messages.html"><strong aria-hidden="true">2.2.</strong> Receive and Send Messages Using Waku Relay</a></li><li class="chapter-item expanded "><a href="../guides/store_retrieve_messages.html"><strong aria-hidden="true">2.3.</strong> Retrieve Messages Using Waku Store</a></li><li class="chapter-item expanded "><a href="../guides/encrypt_messages_version_1.html"><strong aria-hidden="true">2.4.</strong> Encrypt Messages Using Waku Message Version 1</a></li><li class="chapter-item expanded "><a href="../guides/reactjs_relay.html"><strong aria-hidden="true">2.5.</strong> Receive and Send Messages Using Waku Relay With ReactJS</a></li><li class="chapter-item expanded "><a href="../guides/reactjs_store.html"><strong aria-hidden="true">2.6.</strong> Retrieve Messages Using Waku Store With ReactJS</a></li><li class="chapter-item expanded "><a href="../guides/light_push_send_messages.html" class="active"><strong aria-hidden="true">2.7.</strong> Send Messages Using Waku Light Push</a></li></ol></li><li class="chapter-item expanded "><a href="../examples.html"><strong aria-hidden="true">3.</strong> Examples</a></li><li class="chapter-item expanded affix "><a href="../waku_protocols.html">Implemented Waku Protocols</a></li></ol> </div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">DappConnect Docs</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/vacp2p/docs.dappconnect.dev" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="send-messages-using-waku-light-push"><a class="header" href="#send-messages-using-waku-light-push">Send Messages Using Waku Light Push</a></h1>
<p>Waku Light Push enables a client to receive a confirmation when sending a message.</p>
<p>The Waku Relay protocol sends messages to connected peers but does not provide any information on whether said peers have received messages.
This can be an issue when facing potential connectivity issues.
For example, when the connection drops easily, or it is connected to a small number of relay peers.</p>
<p>Waku Light Push allows a client to get a response from a remote peer when sending a message.
Note this only guarantees that the remote peer has received the message,
it cannot guarantee propagation to the network.</p>
<p>It also means weaker privacy properties as the remote peer knows the client is the originator of the message.
Whereas with Waku Relay, a remote peer would not know whether the client created or forwarded the message.</p>
<p>You can find Waku Light Push's specifications on <a href="https://rfc.vac.dev/spec/19/">Vac RFC</a>.</p>
<h1 id="content-topic"><a class="header" href="#content-topic">Content Topic</a></h1>
<p>Before starting, you need to choose a <em>Content Topic</em> for your dApp.
Check out the <a href="./choose_content_topic.html">how to choose a content topic guide</a> to learn more about content topics.</p>
<p>For this guide, we are using a single content topic: <code>/light-push-guide/1/guide/proto</code>.</p>
<h1 id="installation"><a class="header" href="#installation">Installation</a></h1>
<p>You can install <a href="https://npmjs.com/package/js-waku">js-waku</a> using your favorite package manager:</p>
<pre><code class="language-shell">npm install js-waku
</code></pre>
<h1 id="create-waku-instance"><a class="header" href="#create-waku-instance">Create Waku Instance</a></h1>
<p>In order to interact with the Waku network, you first need a Waku instance:</p>
<pre><code class="language-js">import { Waku } from 'js-waku';
const wakuNode = await Waku.create({ bootstrap: true });
</code></pre>
<p>Passing the <code>bootstrap</code> option will connect your node to predefined Waku nodes.
If you want to bootstrap to your own nodes, you can pass an array of multiaddresses instead:</p>
<pre><code class="language-js">import { Waku } from 'js-waku';
const waku = await Waku.create({
bootstrap: [
'/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm',
'/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ'
]
});
</code></pre>
<h1 id="wait-to-be-connected"><a class="header" href="#wait-to-be-connected">Wait to be connected</a></h1>
<p>When using the <code>bootstrap</code> option, it may take some time to connect to other peers.
To ensure that you have a light push peer available to send messages to,
use the following function:</p>
<pre><code class="language-js">await waku.waitForConnectedPeer();
</code></pre>
<p>The returned <code>Promise</code> will resolve once you are connected to a Waku peer.</p>
<h1 id="send-messages"><a class="header" href="#send-messages">Send messages</a></h1>
<p>You can now send a message using Waku Light Push.
By default, it sends the messages to a single randomly selected light push peer.
The peer is selected among the dApp's connected peers.</p>
<p>If the dApp is not connected to any light push peer, an error is thrown.</p>
<pre><code class="language-ts">import {WakuMessage} from 'js-waku';
const wakuMessage = await WakuMessage.fromUtf8String('Here is a message', `/light-push-guide/1/guide/proto`);
const ack = await waku.lightPush.push(wakuMessage);
if (!ack?.isSuccess) {
// Message was not sent
}
</code></pre>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../guides/reactjs_store.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../examples.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../guides/reactjs_store.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../examples.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>

446
guides/reactjs_relay.html Normal file
View File

@ -0,0 +1,446 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Receive and Send Messages Using Waku Relay With ReactJS - DappConnect Docs</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="../custom.css">
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../introduction.html">Introduction</a></li><li class="chapter-item expanded "><a href="../quick_start.html"><strong aria-hidden="true">1.</strong> Quick Start</a></li><li class="chapter-item expanded "><a href="../guides/index.html"><strong aria-hidden="true">2.</strong> Guides</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../guides/choose_content_topic.html"><strong aria-hidden="true">2.1.</strong> How to Choose a Content Topic</a></li><li class="chapter-item expanded "><a href="../guides/relay_receive_send_messages.html"><strong aria-hidden="true">2.2.</strong> Receive and Send Messages Using Waku Relay</a></li><li class="chapter-item expanded "><a href="../guides/store_retrieve_messages.html"><strong aria-hidden="true">2.3.</strong> Retrieve Messages Using Waku Store</a></li><li class="chapter-item expanded "><a href="../guides/encrypt_messages_version_1.html"><strong aria-hidden="true">2.4.</strong> Encrypt Messages Using Waku Message Version 1</a></li><li class="chapter-item expanded "><a href="../guides/reactjs_relay.html" class="active"><strong aria-hidden="true">2.5.</strong> Receive and Send Messages Using Waku Relay With ReactJS</a></li><li class="chapter-item expanded "><a href="../guides/reactjs_store.html"><strong aria-hidden="true">2.6.</strong> Retrieve Messages Using Waku Store With ReactJS</a></li><li class="chapter-item expanded "><a href="../guides/light_push_send_messages.html"><strong aria-hidden="true">2.7.</strong> Send Messages Using Waku Light Push</a></li></ol></li><li class="chapter-item expanded "><a href="../examples.html"><strong aria-hidden="true">3.</strong> Examples</a></li><li class="chapter-item expanded affix "><a href="../waku_protocols.html">Implemented Waku Protocols</a></li></ol> </div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">DappConnect Docs</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/vacp2p/docs.dappconnect.dev" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="receive-and-send-messages-using-waku-relay-with-reactjs"><a class="header" href="#receive-and-send-messages-using-waku-relay-with-reactjs">Receive and Send Messages Using Waku Relay With ReactJS</a></h1>
<p>It is easy to use DappConnect with ReactJS.
In this guide, we will demonstrate how your ReactJS dApp can use Waku Relay to send and receive messages. </p>
<p>Before starting, you need to choose a <em>Content Topic</em> for your dApp.
Check out the <a href="./choose_content_topic.html">how to choose a content topic guide</a> to learn more about content topics.
For this guide, we are using a single content topic: <code>/min-react-js-chat/1/chat/proto</code>.</p>
<h1 id="setup"><a class="header" href="#setup">Setup</a></h1>
<p>Create a new React app:</p>
<pre><code class="language-shell">npx create-react-app min-react-js-chat
cd min-react-js-chat
</code></pre>
<p>Then, install <a href="https://npmjs.com/package/js-waku">js-waku</a>:</p>
<pre><code class="language-shell">npm install js-waku
</code></pre>
<p>Start the dev server and open the dApp in your browser:</p>
<pre><code class="language-shell">npm run start
</code></pre>
<p>Note: We have noticed some <a href="https://github.com/status-im/js-waku/issues/165">issues</a> with React bundling due to <code>npm</code> pulling an old version of babel.
If you are getting an error about the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining">optional chaining (?.)</a>
character not being valid, try cleaning up and re-installing your dependencies:</p>
<pre><code class="language-shell">rm -rf node_modules package-lock.json
npm install
</code></pre>
<h1 id="create-waku-instance"><a class="header" href="#create-waku-instance">Create Waku Instance</a></h1>
<p>In order to interact with the Waku network, you first need a Waku instance.
Go to <code>App.js</code> and modify the <code>App</code> function:</p>
<pre><code class="language-js">import { Waku } from 'js-waku';
import * as React from 'react';
function App() {
const [waku, setWaku] = React.useState(undefined);
const [wakuStatus, setWakuStatus] = React.useState('None');
// Start Waku
React.useEffect(() =&gt; {
// If Waku is already assigned, the job is done
if (!!waku) return;
// If Waku status not None, it means we are already starting Waku
if (wakuStatus !== 'None') return;
setWakuStatus('Starting');
// Create Waku
Waku.create({ bootstrap: true }).then((waku) =&gt; {
// Once done, put it in the state
setWaku(waku);
// And update the status
setWakuStatus('Started');
});
}, [waku, wakuStatus]);
return (
&lt;div className='App'&gt;
&lt;header className='App-header'&gt;
// Display the status on the web page
&lt;p&gt;{wakuStatus}&lt;/p&gt;
&lt;/header&gt;
&lt;/div&gt;
);
}
</code></pre>
<h1 id="wait-to-be-connected"><a class="header" href="#wait-to-be-connected">Wait to be connected</a></h1>
<p>When using the <code>bootstrap</code> option, it may take some time to connect to other peers.
To ensure that you have relay peers available to send and receive messages,
use the <code>Waku.waitForConnectedPeer()</code> async function:</p>
<pre><code class="language-js">React.useEffect(() =&gt; {
if (!!waku) return;
if (wakuStatus !== 'None') return;
setWakuStatus('Starting');
Waku.create({ bootstrap: true }).then((waku) =&gt; {
setWaku(waku);
setWakuStatus('Connecting');
waku.waitForConnectedPeer().then(() =&gt; {
setWakuStatus('Ready');
});
});
}, [waku, wakuStatus]);
</code></pre>
<h1 id="define-message-format"><a class="header" href="#define-message-format">Define Message Format</a></h1>
<p>To define the Protobuf message format,
use <a href="https://www.npmjs.com/package/protons">protons</a></p>
<pre><code class="language-shell">npm install protons
</code></pre>
<p>Define <code>SimpleChatMessage</code> with two fields: <code>timestamp</code> and <code>text</code>.</p>
<pre><code class="language-js">import protons from 'protons';
const proto = protons(`
message SimpleChatMessage {
uint64 timestamp = 1;
string text = 2;
}
`);
</code></pre>
<h1 id="send-messages"><a class="header" href="#send-messages">Send Messages</a></h1>
<p>Create a function that takes the Waku instance and a message to send:</p>
<pre><code class="language-js">import { WakuMessage } from 'js-waku';
const ContentTopic = `/min-react-js-chat/1/chat/proto`;
function sendMessage(message, timestamp, waku) {
const time = timestamp.getTime();
// Encode to protobuf
const payload = proto.SimpleChatMessage.encode({
timestamp: time,
text: message
});
// Wrap in a Waku Message
return WakuMessage.fromBytes(payload, ContentTopic).then((wakuMessage) =&gt;
// Send over Waku Relay
waku.relay.send(wakuMessage)
);
}
</code></pre>
<p>Then, add a button to the <code>App</code> function:</p>
<pre><code class="language-js">function App() {
const [waku, setWaku] = React.useState(undefined);
const [wakuStatus, setWakuStatus] = React.useState('None');
// Using a counter just for the messages to be different
const [sendCounter, setSendCounter] = React.useState(0);
React.useEffect(() =&gt; {
// ... creates Waku
}, [waku, wakuStatus]);
const sendMessageOnClick = () =&gt; {
// Check Waku is started and connected first.
if (wakuStatus !== 'Ready') return;
sendMessage(`Here is message #${sendCounter}`, waku, new Date()).then(() =&gt;
console.log('Message sent')
);
// For demonstration purposes.
setSendCounter(sendCounter + 1);
};
return (
&lt;div className=&quot;App&quot;&gt;
&lt;header className=&quot;App-header&quot;&gt;
&lt;p&gt;{wakuStatus}&lt;/p&gt;
&lt;button onClick={sendMessageOnClick} disabled={wakuStatus !== 'Ready'}&gt; // Grey the button is Waku is not yet ready.
Send Message
&lt;/button&gt;
&lt;/header&gt;
&lt;/div&gt;
);
}
</code></pre>
<h1 id="receive-messages"><a class="header" href="#receive-messages">Receive Messages</a></h1>
<p>To process incoming messages, you need to register an observer on Waku Relay.
First, you need to define the observer function.</p>
<p>You will need to remove the observer when the component unmount.
Hence, you need the reference to the function to remain the same.
For that, use <code>React.useCallback</code>:</p>
<pre><code class="language-js">const processIncomingMessage = React.useCallback((wakuMessage) =&gt; {
// Empty message?
if (!wakuMessage.payload) return;
// Decode the protobuf payload
const { timestamp, text } = proto.SimpleChatMessage.decode(
wakuMessage.payload
);
const time = new Date();
time.setTime(timestamp);
// For now, just log new messages on the console
console.log(`message received at ${time.toString()}: ${text}`);
}, []);
</code></pre>
<p>Then, add this observer to Waku Relay.
Do not forget to delete the observer is the component is being unmounted:</p>
<pre><code class="language-js">React.useEffect(() =&gt; {
if (!waku) return;
// Pass the content topic to only process messages related to your dApp
waku.relay.addObserver(processIncomingMessage, [ContentTopic]);
// `cleanUp` is called when the component is unmounted, see ReactJS doc.
return function cleanUp() {
waku.relay.deleteObserver(processIncomingMessage, [ContentTopic]);
};
}, [waku, wakuStatus, processIncomingMessage]);
</code></pre>
<h1 id="display-messages"><a class="header" href="#display-messages">Display Messages</a></h1>
<p>The Waku work is now done.
Your dApp is able to send and receive messages using Waku.
For the sake of completeness, let's display received messages on the page.</p>
<p>First, add incoming messages to the state of the <code>App</code> component:</p>
<pre><code class="language-js">function App() {
//...
const [messages, setMessages] = React.useState([]);
const processIncomingMessage = React.useCallback((wakuMessage) =&gt; {
if (!wakuMessage.payload) return;
const { text, timestamp } = proto.SimpleChatMessage.decode(
wakuMessage.payload
);
const time = new Date();
time.setTime(timestamp);
const message = { text, timestamp: time };
setMessages((messages) =&gt; {
return [message].concat(messages);
});
}, []);
// ...
}
</code></pre>
<p>Then, render the messages:</p>
<pre><code class="language-js">function App() {
// ...
return (
&lt;div className=&quot;App&quot;&gt;
&lt;header className=&quot;App-header&quot;&gt;
&lt;p&gt;{wakuStatus}&lt;/p&gt;
&lt;button onClick={sendMessageOnClick} disabled={wakuStatus !== 'Ready'}&gt;
Send Message
&lt;/button&gt;
&lt;ul&gt;
{messages.map((msg) =&gt; {
return (
&lt;li&gt;
&lt;p&gt;
{msg.timestamp.toString()}: {msg.text}
&lt;/p&gt;
&lt;/li&gt;
);
})}
&lt;/ul&gt;
&lt;/header&gt;
&lt;/div&gt;
);
}
</code></pre>
<p>And Voilà! You should now be able to send and receive messages.
Try out by opening the app from different browsers.</p>
<p>You can see the complete code in the <a href="https://github.com/status-im/js-waku/tree/main/examples/min-react-js-chat">Minimal ReactJS Chat App</a>.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../guides/encrypt_messages_version_1.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../guides/reactjs_store.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../guides/encrypt_messages_version_1.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../guides/reactjs_store.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>

425
guides/reactjs_store.html Normal file
View File

@ -0,0 +1,425 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Retrieve Messages Using Waku Store With ReactJS - DappConnect Docs</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="../custom.css">
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../introduction.html">Introduction</a></li><li class="chapter-item expanded "><a href="../quick_start.html"><strong aria-hidden="true">1.</strong> Quick Start</a></li><li class="chapter-item expanded "><a href="../guides/index.html"><strong aria-hidden="true">2.</strong> Guides</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../guides/choose_content_topic.html"><strong aria-hidden="true">2.1.</strong> How to Choose a Content Topic</a></li><li class="chapter-item expanded "><a href="../guides/relay_receive_send_messages.html"><strong aria-hidden="true">2.2.</strong> Receive and Send Messages Using Waku Relay</a></li><li class="chapter-item expanded "><a href="../guides/store_retrieve_messages.html"><strong aria-hidden="true">2.3.</strong> Retrieve Messages Using Waku Store</a></li><li class="chapter-item expanded "><a href="../guides/encrypt_messages_version_1.html"><strong aria-hidden="true">2.4.</strong> Encrypt Messages Using Waku Message Version 1</a></li><li class="chapter-item expanded "><a href="../guides/reactjs_relay.html"><strong aria-hidden="true">2.5.</strong> Receive and Send Messages Using Waku Relay With ReactJS</a></li><li class="chapter-item expanded "><a href="../guides/reactjs_store.html" class="active"><strong aria-hidden="true">2.6.</strong> Retrieve Messages Using Waku Store With ReactJS</a></li><li class="chapter-item expanded "><a href="../guides/light_push_send_messages.html"><strong aria-hidden="true">2.7.</strong> Send Messages Using Waku Light Push</a></li></ol></li><li class="chapter-item expanded "><a href="../examples.html"><strong aria-hidden="true">3.</strong> Examples</a></li><li class="chapter-item expanded affix "><a href="../waku_protocols.html">Implemented Waku Protocols</a></li></ol> </div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">DappConnect Docs</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/vacp2p/docs.dappconnect.dev" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="retrieve-messages-using-waku-store-with-reactjs"><a class="header" href="#retrieve-messages-using-waku-store-with-reactjs">Retrieve Messages Using Waku Store With ReactJS</a></h1>
<p>It is easy to use DappConnect with ReactJS.
In this guide, we will demonstrate how your ReactJS dApp can use Waku Store to retrieve messages.</p>
<p>DApps running on a phone or in a browser are often offline:
The browser could be closed or mobile app in the background.</p>
<p><a href="https://rfc.vac.dev/spec/18/">Waku Relay</a> is a gossip protocol.
As a user, it means that your peers forward you messages they just received.
If you cannot be reached by your peers, then messages are not relayed;
relay peers do <strong>not</strong> save messages for later.</p>
<p>However, <a href="https://rfc.vac.dev/spec/13/">Waku Store</a> peers do save messages they relay,
allowing you to retrieve them at a later time.
The Waku Store protocol is best-effort and does not guarantee data availability.
Waku Relay should still be preferred when online;
Waku Store can be used after resuming connectivity:
For example, when the dApp starts.</p>
<p>In this guide, we'll review how you can use Waku Store to retrieve messages.</p>
<p>Before starting, you need to choose a <em>Content Topic</em> for your dApp.
Check out the <a href="./choose_content_topic.html">how to choose a content topic guide</a> to learn more about content topics.</p>
<h1 id="setup"><a class="header" href="#setup">Setup</a></h1>
<p>Create a new React app:</p>
<pre><code class="language-shell">npx create-react-app my-app
cd my-app
</code></pre>
<p>Then, install <a href="https://npmjs.com/package/js-waku">js-waku</a>:</p>
<pre><code class="language-shell">npm install js-waku
</code></pre>
<p>Start the dev server and open the dApp in your browser:</p>
<pre><code class="language-shell">npm run start
</code></pre>
<p>Note: We have noticed some <a href="https://github.com/status-im/js-waku/issues/165">issues</a> with React bundling due to <code>npm</code> pulling an old version of babel.
If you are getting an error about the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining">optional chaining (?.)</a>
character not being valid, try cleaning up and re-installing your dependencies:</p>
<pre><code class="language-shell">rm -rf node_modules package-lock.json
npm install
</code></pre>
<h1 id="create-waku-instance"><a class="header" href="#create-waku-instance">Create Waku Instance</a></h1>
<p>In order to interact with the Waku network, you first need a Waku instance.
Go to <code>App.js</code> and modify the <code>App</code> function:</p>
<pre><code class="language-js">import { Waku } from 'js-waku';
import * as React from 'react';
function App() {
const [waku, setWaku] = React.useState(undefined);
const [wakuStatus, setWakuStatus] = React.useState('None');
// Start Waku
React.useEffect(() =&gt; {
// If Waku status not None, it means we are already starting Waku
if (wakuStatus !== 'None') return;
setWakuStatus('Starting');
// Create Waku
Waku.create({ bootstrap: true }).then((waku) =&gt; {
// Once done, put it in the state
setWaku(waku);
// And update the status
setWakuStatus('Connecting');
});
}, [waku, wakuStatus]);
return (
&lt;div className='App'&gt;
&lt;header className='App-header'&gt;
// Display the status on the web page
&lt;p&gt;{wakuStatus}&lt;/p&gt;
&lt;/header&gt;
&lt;/div&gt;
);
}
</code></pre>
<h1 id="wait-to-be-connected"><a class="header" href="#wait-to-be-connected">Wait to be connected</a></h1>
<p>When using the <code>bootstrap</code> option, it may take some time to connect to other peers.
To ensure that you have store peers available to retrieve messages from,
use the <code>Waku.waitForConnectedPeer()</code> async function:</p>
<pre><code class="language-js">React.useEffect(() =&gt; {
if (!waku) return;
if (wakuStatus === 'Connected') return;
waku.waitForConnectedPeer().then(() =&gt; {
setWakuStatus('Connected');
});
}, [waku, wakuStatus]);
</code></pre>
<h1 id="use-protobuf"><a class="header" href="#use-protobuf">Use Protobuf</a></h1>
<p>Waku v2 protocols use <a href="https://developers.google.com/protocol-buffers/">protobuf</a> <a href="https://rfc.vac.dev/spec/10/">by default</a>.</p>
<p>Let's review how you can use protobuf to decode structured data.</p>
<p>First, define a data structure.
For this guide, we will use a simple chat message that contains a timestamp, nick and text:</p>
<pre><code class="language-js">{
timestamp: Date;
nick: string;
text: string;
}
</code></pre>
<p>To encode and decode protobuf payloads, you can use the <a href="https://www.npmjs.com/package/protons">protons</a> package.</p>
<h2 id="install-protobuf-library"><a class="header" href="#install-protobuf-library">Install Protobuf Library</a></h2>
<pre><code class="language-shell">npm install protons
</code></pre>
<h2 id="protobuf-definition"><a class="header" href="#protobuf-definition">Protobuf Definition</a></h2>
<p>Define the data structure with protons:</p>
<pre><code class="language-js">import protons from 'protons';
const proto = protons(`
message ChatMessage {
uint64 timestamp = 1;
string nick = 2;
bytes text = 3;
}
`);
</code></pre>
<p>You can learn about protobuf message definitions here:
<a href="https://developers.google.com/protocol-buffers/docs/proto">Protocol Buffers Language Guide</a>.</p>
<h2 id="decode-messages"><a class="header" href="#decode-messages">Decode Messages</a></h2>
<p>To decode the messages retrieved from a Waku Store node,
you need to extract the protobuf payload and decode it using <code>protons</code>.</p>
<pre><code class="language-js">function decodeMessage(wakuMessage) {
if (!wakuMessage.payload) return;
const { timestamp, nick, text } = proto.ChatMessage.decode(
wakuMessage.payload
);
// All fields in protobuf are optional so be sure to check
if (!timestamp || !text || !nick) return;
const time = new Date();
time.setTime(timestamp);
const utf8Text = Buffer.from(text).toString('utf-8');
return { text: utf8Text, timestamp: time, nick };
}
</code></pre>
<h2 id="retrieve-messages"><a class="header" href="#retrieve-messages">Retrieve messages</a></h2>
<p>You now have all the building blocks to retrieve and decode messages for a store node.</p>
<p>Note that Waku Store queries are paginated.
The API provided by <code>js-waku</code> automatically traverses all pages of the Waku Store response.
By default, the most recent page is retrieved first but this can be changed with the <code>pageDirection</code> option.</p>
<p>First, define a React state to save the messages:</p>
<pre><code class="language-js">function App() {
const [messages, setMessages] = React.useState([]);
/// [..]
}
</code></pre>
<p>Then, define <code>processMessages</code> to decode and then store messages in the React state.
You will pass <code>processMessages</code> as a <code>callback</code> option to <code>WakuStore.queryHistory</code>.
<code>processMessages</code> will be called each time a page is received from the Waku Store.</p>
<pre><code class="language-js">const processMessages = (retrievedMessages) =&gt; {
const messages = retrievedMessages.map(decodeMessage).filter(Boolean);
setMessages((currentMessages) =&gt; {
return currentMessages.concat(messages.reverse());
});
};
</code></pre>
<p>Finally, pass <code>processMessage</code> in <code>WakuStore.queryHistory</code> as the <code>callback</code> value:</p>
<pre><code class="language-js">waku.store
.queryHistory([ContentTopic], { callback: processMessages });
</code></pre>
<p>All together, you should now have:</p>
<pre><code class="language-js">const ContentTopic = '/toy-chat/2/huilong/proto';
function App() {
// [..]
// Store messages in the state
const [messages, setMessages] = React.useState([]);
React.useEffect(() =&gt; {
if (wakuStatus !== 'Connected') return;
const processMessages = (retrievedMessages) =&gt; {
const messages = retrievedMessages.map(decodeMessage).filter(Boolean);
setMessages((currentMessages) =&gt; {
return currentMessages.concat(messages.reverse());
});
};
waku.store
.queryHistory([ContentTopic], { callback: processMessages })
.catch((e) =&gt; {
console.log('Failed to retrieve messages', e);
});
}, [waku, wakuStatus]);
return (
&lt;div className='App'&gt;
&lt;header className='App-header'&gt;
&lt;h2&gt;{wakuStatus}&lt;/h2&gt;
&lt;h3&gt;Messages&lt;/h3&gt;
&lt;ul&gt;
&lt;Messages messages={messages} /&gt;
&lt;/ul&gt;
&lt;/header&gt;
&lt;/div&gt;
);
}
</code></pre>
<p>Note that <code>WakuStore.queryHistory</code> select an available store node for you.
However, it can only select a connected node, which is why the bootstrapping is necessary.
It will throw an error if no store node is available.</p>
<h2 id="filter-messages-by-send-time"><a class="header" href="#filter-messages-by-send-time">Filter messages by send time</a></h2>
<p>By default, Waku Store nodes store messages for 30 days.
Depending on your use case, you may not need to retrieve 30 days worth of messages.</p>
<p><a href="https://rfc.vac.dev/spec/14/">Waku Message</a> defines an optional unencrypted <code>timestamp</code> field.
The timestamp is set by the sender.
By default, js-waku sets the timestamp of outgoing message to the current time.</p>
<p>You can filter messages that include a timestamp within given bounds with the <code>timeFilter</code> option.</p>
<p>Retrieve messages up to a week old:</p>
<pre><code class="language-js">const startTime = new Date();
// 7 days/week, 24 hours/day, 60min/hour, 60secs/min, 100ms/sec
startTime.setTime(startTime.getTime() - 7 * 24 * 60 * 60 * 1000);
waku.store
.queryHistory([ContentTopic], {
callback: processMessages,
timeFilter: { startTime, endTime: new Date() }
});
</code></pre>
<h2 id="end-result"><a class="header" href="#end-result">End result</a></h2>
<p>You can see the complete code in the <a href="https://github.com/status-im/js-waku/tree/main/examples/store-reactjs-chat">Minimal ReactJS Waku Store App</a>.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../guides/reactjs_relay.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../guides/light_push_send_messages.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../guides/reactjs_relay.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../guides/light_push_send_messages.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>

View File

@ -0,0 +1,356 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Receive and Send Messages Using Waku Relay - DappConnect Docs</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="../custom.css">
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../introduction.html">Introduction</a></li><li class="chapter-item expanded "><a href="../quick_start.html"><strong aria-hidden="true">1.</strong> Quick Start</a></li><li class="chapter-item expanded "><a href="../guides/index.html"><strong aria-hidden="true">2.</strong> Guides</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../guides/choose_content_topic.html"><strong aria-hidden="true">2.1.</strong> How to Choose a Content Topic</a></li><li class="chapter-item expanded "><a href="../guides/relay_receive_send_messages.html" class="active"><strong aria-hidden="true">2.2.</strong> Receive and Send Messages Using Waku Relay</a></li><li class="chapter-item expanded "><a href="../guides/store_retrieve_messages.html"><strong aria-hidden="true">2.3.</strong> Retrieve Messages Using Waku Store</a></li><li class="chapter-item expanded "><a href="../guides/encrypt_messages_version_1.html"><strong aria-hidden="true">2.4.</strong> Encrypt Messages Using Waku Message Version 1</a></li><li class="chapter-item expanded "><a href="../guides/reactjs_relay.html"><strong aria-hidden="true">2.5.</strong> Receive and Send Messages Using Waku Relay With ReactJS</a></li><li class="chapter-item expanded "><a href="../guides/reactjs_store.html"><strong aria-hidden="true">2.6.</strong> Retrieve Messages Using Waku Store With ReactJS</a></li><li class="chapter-item expanded "><a href="../guides/light_push_send_messages.html"><strong aria-hidden="true">2.7.</strong> Send Messages Using Waku Light Push</a></li></ol></li><li class="chapter-item expanded "><a href="../examples.html"><strong aria-hidden="true">3.</strong> Examples</a></li><li class="chapter-item expanded affix "><a href="../waku_protocols.html">Implemented Waku Protocols</a></li></ol> </div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">DappConnect Docs</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/vacp2p/docs.dappconnect.dev" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="receive-and-send-messages-using-waku-relay"><a class="header" href="#receive-and-send-messages-using-waku-relay">Receive and Send Messages Using Waku Relay</a></h1>
<p>Waku Relay is a gossip protocol that enables you to send and receive messages.
You can find Waku Relay's specifications on <a href="https://rfc.vac.dev/spec/11/">Vac RFC</a>.</p>
<p>Before starting, you need to choose a <em>Content Topic</em> for your dApp.
Check out the <a href="./choose_content_topic.html">how to choose a content topic guide</a> to learn more about content topics.</p>
<p>For this guide, we are using a single content topic: <code>/relay-guide/1/chat/proto</code>.</p>
<h1 id="installation"><a class="header" href="#installation">Installation</a></h1>
<p>You can install <a href="https://npmjs.com/package/js-waku">js-waku</a> using your favorite package manager:</p>
<pre><code class="language-shell">npm install js-waku
</code></pre>
<h1 id="create-waku-instance"><a class="header" href="#create-waku-instance">Create Waku Instance</a></h1>
<p>In order to interact with the Waku network, you first need a Waku instance:</p>
<pre><code class="language-js">import { Waku } from 'js-waku';
const waku = await Waku.create({ bootstrap: true });
</code></pre>
<p>Passing the <code>bootstrap</code> option will connect your node to predefined Waku nodes.
If you want to bootstrap to your own nodes, you can pass an array of multiaddresses instead:</p>
<pre><code class="language-js">import { Waku } from 'js-waku';
const waku = await Waku.create({
bootstrap: [
'/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm',
'/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ'
]
});
</code></pre>
<h1 id="wait-to-be-connected"><a class="header" href="#wait-to-be-connected">Wait to be connected</a></h1>
<p>When using the <code>bootstrap</code> option, it may take some time to connect to other peers.
To ensure that you have relay peers available to send and receive messages,
use the following function:</p>
<pre><code class="language-js">await waku.waitForConnectedPeer();
</code></pre>
<p>The returned <code>Promise</code> will resolve once you are connected to a Waku Relay peer.</p>
<h1 id="receive-messages"><a class="header" href="#receive-messages">Receive messages</a></h1>
<p>To receive messages for your app,
you need to register an observer on relay for your app's content topic:</p>
<pre><code class="language-js">const processIncomingMessage = (wakuMessage) =&gt; {
console.log(`Message Received: ${wakuMessage.payloadAsUtf8}`);
};
waku.relay.addObserver(processIncomingMessage, ['/relay-guide/1/chat/proto']);
</code></pre>
<h1 id="send-messages"><a class="header" href="#send-messages">Send Messages</a></h1>
<p>You are now ready to send messages.
Let's start by sending simple strings as messages.</p>
<p>To send a message, you need to wrap the message in a <code>WakuMessage</code>.
When using a basic string payload, you can use the <code>WakuMessage.fromUtf8String</code> helper:</p>
<pre><code class="language-js">import { WakuMessage } from 'js-waku';
const wakuMessage = await WakuMessage.fromUtf8String('Here is a message', `/relay-guide/1/chat/proto`);
</code></pre>
<p>Then, use the <code>relay</code> module to send the message to our peers,
the message will then be relayed to the rest of the network thanks to Waku Relay:</p>
<pre><code class="language-js">await waku.relay.send(wakuMessage);
</code></pre>
<h1 id="use-protobuf"><a class="header" href="#use-protobuf">Use Protobuf</a></h1>
<p>Sending strings as messages in unlikely to cover your dApps needs.</p>
<p>Waku v2 protocols use <a href="https://developers.google.com/protocol-buffers/">protobuf</a> <a href="https://rfc.vac.dev/spec/10/">by default</a>.</p>
<p>Let's review how you can use protobuf to include structured objects in Waku Messages.</p>
<p>First, define a data structure.
For this guide, we will use a simple chat message that contains a timestamp and text:</p>
<pre><code class="language-js">{
timestamp: Date;
text: string;
}
</code></pre>
<p>To encode and decode protobuf payloads, you can use the <a href="https://www.npmjs.com/package/protons">protons</a> package.</p>
<h2 id="install-protobuf-library"><a class="header" href="#install-protobuf-library">Install Protobuf Library</a></h2>
<p>First, install protons:</p>
<pre><code class="language-shell">npm install protons
</code></pre>
<h2 id="protobuf-definition"><a class="header" href="#protobuf-definition">Protobuf Definition</a></h2>
<p>Then define the simple chat message:</p>
<pre><code class="language-js">import protons from 'protons';
const proto = protons(`
message SimpleChatMessage {
uint64 timestamp = 1;
string text = 2;
}
`);
</code></pre>
<p>You can learn about protobuf message definitions here:
<a href="https://developers.google.com/protocol-buffers/docs/proto">Protocol Buffers Language Guide</a>.</p>
<h2 id="encode-messages"><a class="header" href="#encode-messages">Encode Messages</a></h2>
<p>Instead of wrapping an utf-8 string in a Waku Message,
you are going to wrap a protobuf payload.</p>
<p>First, encode the object:</p>
<pre><code class="language-js">const payload = proto.SimpleChatMessage.encode({
timestamp: Date.now(),
text: 'Here is a message'
});
</code></pre>
<p>Then, wrap it in a Waku Message:</p>
<pre><code class="language-js">const wakuMessage = await WakuMessage.fromBytes(payload, ContentTopic);
</code></pre>
<p>Now, you can send the message over Waku Relay the same way than before:</p>
<pre><code class="language-js">await waku.relay.send(wakuMessage);
</code></pre>
<h2 id="decode-messages"><a class="header" href="#decode-messages">Decode Messages</a></h2>
<p>To decode the messages received over Waku Relay,
you need to extract the protobuf payload and decode it using <code>protons</code>.</p>
<pre><code class="language-js">const processIncomingMessage = (wakuMessage) =&gt; {
// No need to attempt to decode a message if the payload is absent
if (!wakuMessage.payload) return;
const { timestamp, text } = proto.SimpleChatMessage.decode(
wakuMessage.payload
);
console.log(`Message Received: ${text}, sent at ${timestamp.toString()}`);
};
</code></pre>
<p>Like before, add this callback as an observer to Waku Relay:</p>
<pre><code class="language-js">waku.relay.addObserver(processIncomingMessage, ['/relay-guide/1/chat/proto']);
</code></pre>
<h1 id="conclusion"><a class="header" href="#conclusion">Conclusion</a></h1>
<p>That is it! Now, you know how to send and receive messages over Waku using the Waku Relay protocol.</p>
<p>Feel free to check out other <a href="./">guides</a> or <a href="/examples.html">examples</a>.</p>
<p>Here is the final code:</p>
<pre><code class="language-js">import { getBootstrapNodes, Waku, WakuMessage } from 'js-waku';
import protons from 'protons';
const proto = protons(`
message SimpleChatMessage {
uint64 timestamp = 1;
string text = 2;
}
`);
const wakuNode = await Waku.create();
const nodes = await getBootstrapNodes();
await Promise.all(nodes.map((addr) =&gt; waku.dial(addr)));
const processIncomingMessage = (wakuMessage) =&gt; {
// No need to attempt to decode a message if the payload is absent
if (!wakuMessage.payload) return;
const { timestamp, text } = proto.SimpleChatMessage.decode(
wakuMessage.payload
);
console.log(`Message Received: ${text}, sent at ${timestamp.toString()}`);
};
waku.relay.addObserver(processIncomingMessage, ['/relay-guide/1/chat/proto']);
const payload = proto.SimpleChatMessage.encode({
timestamp: Date.now(),
text: 'Here is a message'
});
const wakuMessage = await WakuMessage.fromBytes(payload, ContentTopic);
await waku.relay.send(wakuMessage);
</code></pre>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../guides/choose_content_topic.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../guides/store_retrieve_messages.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../guides/choose_content_topic.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../guides/store_retrieve_messages.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>

View File

@ -0,0 +1,345 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Retrieve Messages Using Waku Store - DappConnect Docs</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="../custom.css">
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../introduction.html">Introduction</a></li><li class="chapter-item expanded "><a href="../quick_start.html"><strong aria-hidden="true">1.</strong> Quick Start</a></li><li class="chapter-item expanded "><a href="../guides/index.html"><strong aria-hidden="true">2.</strong> Guides</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../guides/choose_content_topic.html"><strong aria-hidden="true">2.1.</strong> How to Choose a Content Topic</a></li><li class="chapter-item expanded "><a href="../guides/relay_receive_send_messages.html"><strong aria-hidden="true">2.2.</strong> Receive and Send Messages Using Waku Relay</a></li><li class="chapter-item expanded "><a href="../guides/store_retrieve_messages.html" class="active"><strong aria-hidden="true">2.3.</strong> Retrieve Messages Using Waku Store</a></li><li class="chapter-item expanded "><a href="../guides/encrypt_messages_version_1.html"><strong aria-hidden="true">2.4.</strong> Encrypt Messages Using Waku Message Version 1</a></li><li class="chapter-item expanded "><a href="../guides/reactjs_relay.html"><strong aria-hidden="true">2.5.</strong> Receive and Send Messages Using Waku Relay With ReactJS</a></li><li class="chapter-item expanded "><a href="../guides/reactjs_store.html"><strong aria-hidden="true">2.6.</strong> Retrieve Messages Using Waku Store With ReactJS</a></li><li class="chapter-item expanded "><a href="../guides/light_push_send_messages.html"><strong aria-hidden="true">2.7.</strong> Send Messages Using Waku Light Push</a></li></ol></li><li class="chapter-item expanded "><a href="../examples.html"><strong aria-hidden="true">3.</strong> Examples</a></li><li class="chapter-item expanded affix "><a href="../waku_protocols.html">Implemented Waku Protocols</a></li></ol> </div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">DappConnect Docs</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/vacp2p/docs.dappconnect.dev" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="retrieve-messages-using-waku-store"><a class="header" href="#retrieve-messages-using-waku-store">Retrieve Messages Using Waku Store</a></h1>
<p>DApps running on a phone or in a browser are often offline:
The browser could be closed or mobile app in the background.</p>
<p><a href="https://rfc.vac.dev/spec/11/">Waku Relay</a> is a gossip protocol.
As a user, it means that your peers forward you messages they just received.
If you cannot be reached by your peers, then messages are not relayed;
relay peers do <strong>not</strong> save messages for later.</p>
<p>However, <a href="https://rfc.vac.dev/spec/13/">Waku Store</a> peers do save messages they relay,
allowing you to retrieve them at a later time.
The Waku Store protocol is best-effort and does not guarantee data availability.
Waku Relay should still be preferred when online;
Waku Store can be used after resuming connectivity:
For example, when the dApp starts.</p>
<p>In this guide, we'll review how you can use Waku Store to retrieve messages.</p>
<p>Before starting, you need to choose a <em>Content Topic</em> for your dApp.
Check out the <a href="./choose_content_topic.html">how to choose a content topic guide</a> to learn more about content topics.</p>
<p>For this guide, we are using a single content topic: <code>/store-guide/1/news/proto</code>.</p>
<h1 id="installation"><a class="header" href="#installation">Installation</a></h1>
<p>You can install <a href="https://npmjs.com/package/js-waku">js-waku</a> using your favorite package manager:</p>
<pre><code class="language-shell">npm install js-waku
</code></pre>
<h1 id="create-waku-instance"><a class="header" href="#create-waku-instance">Create Waku Instance</a></h1>
<p>In order to interact with the Waku network, you first need a Waku instance:</p>
<pre><code class="language-js">import { Waku } from 'js-waku';
const wakuNode = await Waku.create({ bootstrap: true });
</code></pre>
<p>Passing the <code>bootstrap</code> option will connect your node to predefined Waku nodes.
If you want to bootstrap to your own nodes, you can pass an array of multiaddresses instead:</p>
<pre><code class="language-js">import { Waku } from 'js-waku';
const wakuNode = await Waku.create({
bootstrap: [
'/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm',
'/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ'
]
});
</code></pre>
<h1 id="wait-to-be-connected"><a class="header" href="#wait-to-be-connected">Wait to be connected</a></h1>
<p>When using the <code>bootstrap</code> option, it may take some times to connect to other peers.
To ensure that you have store peers available to retrieve historical messages from,
use the following function:</p>
<pre><code class="language-js">await waku.waitForConnectedPeer();
</code></pre>
<p>The returned Promise will resolve once you are connected to a Waku Store peer.</p>
<h1 id="use-protobuf"><a class="header" href="#use-protobuf">Use Protobuf</a></h1>
<p>Waku v2 protocols use <a href="https://developers.google.com/protocol-buffers/">protobuf</a> <a href="https://rfc.vac.dev/spec/10/">by default</a>.</p>
<p>Let's review how you can use protobuf to send structured data.</p>
<p>First, define a data structure.
For this guide, we will use a simple news article that contains a date of publication, title and body:</p>
<pre><code class="language-js">{
date: Date;
title: string;
body: string;
}
</code></pre>
<p>To encode and decode protobuf payloads, you can use the <a href="https://www.npmjs.com/package/protons">protons</a> package.</p>
<h2 id="install-protobuf-library"><a class="header" href="#install-protobuf-library">Install Protobuf Library</a></h2>
<p>First, install protons:</p>
<pre><code class="language-shell">npm install protons
</code></pre>
<h2 id="protobuf-definition"><a class="header" href="#protobuf-definition">Protobuf Definition</a></h2>
<p>Then specify the data structure:</p>
<pre><code class="language-js">import protons from 'protons';
const proto = protons(`
message ArticleMessage {
uint64 date = 1;
string title = 2;
string body = 3;
}
`);
</code></pre>
<p>You can learn about protobuf message definitions here:
<a href="https://developers.google.com/protocol-buffers/docs/proto">Protocol Buffers Language Guide</a>.</p>
<h2 id="decode-messages"><a class="header" href="#decode-messages">Decode Messages</a></h2>
<p>To decode the messages retrieved from a Waku Store node,
you need to extract the protobuf payload and decode it using <code>protons</code>.</p>
<pre><code class="language-js">const decodeWakuMessage = (wakuMessage) =&gt; {
// No need to attempt to decode a message if the payload is absent
if (!wakuMessage.payload) return;
const { date, title, body } = proto.SimpleChatMessage.decode(
wakuMessage.payload
);
// In protobuf, fields are optional so best to check
if (!date || !title || !body) return;
const publishDate = new Date();
publishDate.setTime(date);
return { publishDate, title, body };
};
</code></pre>
<h2 id="retrieve-messages"><a class="header" href="#retrieve-messages">Retrieve messages</a></h2>
<p>You now have all the building blocks to retrieve and decode messages for a store node.</p>
<p>Store node responses are paginated.
The <code>WakuStore.queryHistory</code> API automatically query all the pages in a sequential manner.
To process messages as soon as they received (page by page), use the <code>callback</code> option:</p>
<pre><code class="language-js">const ContentTopic = '/store-guide/1/news/proto';
const callback = (retrievedMessages) =&gt; {
const articles = retrievedMessages
.map(decodeWakuMessage) // Decode messages
.filter(Boolean); // Filter out undefined values
console.log(`${articles.length} articles have been retrieved`);
};
waku.store
.queryHistory([ContentTopic], { callback })
.catch((e) =&gt; {
// Catch any potential error
console.log('Failed to retrieve messages from store', e);
});
</code></pre>
<p>Note that <code>WakuStore.queryHistory</code> select an available store node for you.
However, it can only select a connected node, which is why the bootstrapping is necessary.
It will throw an error if no store node is available.</p>
<h2 id="filter-messages-by-send-time"><a class="header" href="#filter-messages-by-send-time">Filter messages by send time</a></h2>
<p>By default, Waku Store nodes store messages for 30 days.
Depending on your use case, you may not need to retrieve 30 days worth of messages.</p>
<p><a href="https://rfc.vac.dev/spec/14/">Waku Message</a> defines an optional unencrypted <code>timestamp</code> field.
The timestamp is set by the sender.
By default, js-waku sets the timestamp of outgoing message to the current time.</p>
<p>You can filter messages that include a timestamp within given bounds with the <code>timeFilter</code> option.</p>
<p>Retrieve messages up to a week old:</p>
<pre><code class="language-js">// [..] `ContentTopic` and `callback` definitions
const startTime = new Date();
// 7 days/week, 24 hours/day, 60min/hour, 60secs/min, 100ms/sec
startTime.setTime(startTime.getTime() - 7 * 24 * 60 * 60 * 1000);
waku.store
.queryHistory([ContentTopic], {
callback,
timeFilter: { startTime, endTime: new Date() }
})
.catch((e) =&gt; {
console.log('Failed to retrieve messages from store', e);
});
</code></pre>
<h2 id="end-result"><a class="header" href="#end-result">End result</a></h2>
<p>You can see a similar example implemented in ReactJS in the <a href="https://github.com/status-im/js-waku/tree/main/examples/store-reactjs-chat">Minimal ReactJS Waku Store App</a>.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../guides/relay_receive_send_messages.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../guides/encrypt_messages_version_1.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../guides/relay_receive_send_messages.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../guides/encrypt_messages_version_1.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>

View File

@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Chapter 1 - DappConnect Docs</title>
<title>Introduction - DappConnect Docs</title>
<!-- Custom HTML head -->
@ -83,7 +83,7 @@
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded "><a href="chapter_1.html"><strong aria-hidden="true">1.</strong> Chapter 1</a></li></ol> </div>
<ol class="chapter"><li class="chapter-item expanded affix "><a href="introduction.html">Introduction</a></li><li class="chapter-item expanded "><a href="quick_start.html"><strong aria-hidden="true">1.</strong> Quick Start</a></li><li class="chapter-item expanded "><a href="guides/index.html"><strong aria-hidden="true">2.</strong> Guides</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="guides/choose_content_topic.html"><strong aria-hidden="true">2.1.</strong> How to Choose a Content Topic</a></li><li class="chapter-item expanded "><a href="guides/relay_receive_send_messages.html"><strong aria-hidden="true">2.2.</strong> Receive and Send Messages Using Waku Relay</a></li><li class="chapter-item expanded "><a href="guides/store_retrieve_messages.html"><strong aria-hidden="true">2.3.</strong> Retrieve Messages Using Waku Store</a></li><li class="chapter-item expanded "><a href="guides/encrypt_messages_version_1.html"><strong aria-hidden="true">2.4.</strong> Encrypt Messages Using Waku Message Version 1</a></li><li class="chapter-item expanded "><a href="guides/reactjs_relay.html"><strong aria-hidden="true">2.5.</strong> Receive and Send Messages Using Waku Relay With ReactJS</a></li><li class="chapter-item expanded "><a href="guides/reactjs_store.html"><strong aria-hidden="true">2.6.</strong> Retrieve Messages Using Waku Store With ReactJS</a></li><li class="chapter-item expanded "><a href="guides/light_push_send_messages.html"><strong aria-hidden="true">2.7.</strong> Send Messages Using Waku Light Push</a></li></ol></li><li class="chapter-item expanded "><a href="examples.html"><strong aria-hidden="true">3.</strong> Examples</a></li><li class="chapter-item expanded affix "><a href="waku_protocols.html">Implemented Waku Protocols</a></li></ol> </div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
@ -147,13 +147,35 @@
<div id="content" class="content">
<main>
<h1 id="chapter-1"><a class="header" href="#chapter-1">Chapter 1</a></h1>
<h1 id="dappconnect-docs"><a class="header" href="#dappconnect-docs">DappConnect Docs</a></h1>
<p>DappConnect is a suite of libraries, SDKs and documentations to help you use Waku in your dApp.</p>
<p>Waku is a decentralized, censorship-resistant, network and protocol family.
It enables you to add communication features to your dApp in a decentralized manner,
ensuring to your users that they will not be censored or de-platformed.</p>
<p>Waku can be used for chat purposes and for many machine-to-machine use cases.
You can learn more about Waku at <a href="https://waku.vac.dev">waku.vac.dev</a>.</p>
<p>JS-Waku is the TypeScript implementation of the Waku protocol,
built for browser environment.</p>
<p>The <a href="./quick_start.html">quick start</a> presents an easy way to send and receive messages using js-waku.</p>
<p>The <a href="./guides">guides</a> explain specific js-waku features
and how it can be used with popular web frameworks.</p>
<p>The js-waku repository also holds a number of <a href="https://github.com/status-im/js-waku/tree/main/examples">examples</a>.
The examples are working Proof-of-Concepts that demonstrate how to use js-waku.
Check out the <a href="./examples.html">example list</a> to see what usage each example demonstrates. </p>
<p>Finally, if you want to learn how Waku works under the hoods, check the specs at <a href="https://rfc.vac.dev/">rfc.vac.dev</a>.</p>
<h2 id="bugs-questions--support"><a class="header" href="#bugs-questions--support">Bugs, Questions &amp; Support</a></h2>
<p>If you encounter any bug or would like to propose new features, feel free to <a href="https://github.com/status-im/js-waku/issues/new/">open an issue</a>.</p>
<p>To get help, join #dappconnect-support on <a href="https://discord.gg/j5pGbn7MHZ">Vac Discord</a> or <a href="https://t.me/dappconnectsupport">Telegram</a>.
For more general discussion and latest news, join #dappconnect on <a href="https://discord.gg/9DgykdmpZ6">Vac Discord</a> or <a href="https://t.me/dappconnect">Telegram</a>.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="next" href="quick_start.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
@ -162,6 +184,9 @@
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="next" href="quick_start.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>

View File

@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Chapter 1 - DappConnect Docs</title>
<title>Introduction - DappConnect Docs</title>
<!-- Custom HTML head -->
@ -83,7 +83,7 @@
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded "><a href="chapter_1.html" class="active"><strong aria-hidden="true">1.</strong> Chapter 1</a></li></ol> </div>
<ol class="chapter"><li class="chapter-item expanded affix "><a href="introduction.html" class="active">Introduction</a></li><li class="chapter-item expanded "><a href="quick_start.html"><strong aria-hidden="true">1.</strong> Quick Start</a></li><li class="chapter-item expanded "><a href="guides/index.html"><strong aria-hidden="true">2.</strong> Guides</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="guides/choose_content_topic.html"><strong aria-hidden="true">2.1.</strong> How to Choose a Content Topic</a></li><li class="chapter-item expanded "><a href="guides/relay_receive_send_messages.html"><strong aria-hidden="true">2.2.</strong> Receive and Send Messages Using Waku Relay</a></li><li class="chapter-item expanded "><a href="guides/store_retrieve_messages.html"><strong aria-hidden="true">2.3.</strong> Retrieve Messages Using Waku Store</a></li><li class="chapter-item expanded "><a href="guides/encrypt_messages_version_1.html"><strong aria-hidden="true">2.4.</strong> Encrypt Messages Using Waku Message Version 1</a></li><li class="chapter-item expanded "><a href="guides/reactjs_relay.html"><strong aria-hidden="true">2.5.</strong> Receive and Send Messages Using Waku Relay With ReactJS</a></li><li class="chapter-item expanded "><a href="guides/reactjs_store.html"><strong aria-hidden="true">2.6.</strong> Retrieve Messages Using Waku Store With ReactJS</a></li><li class="chapter-item expanded "><a href="guides/light_push_send_messages.html"><strong aria-hidden="true">2.7.</strong> Send Messages Using Waku Light Push</a></li></ol></li><li class="chapter-item expanded "><a href="examples.html"><strong aria-hidden="true">3.</strong> Examples</a></li><li class="chapter-item expanded affix "><a href="waku_protocols.html">Implemented Waku Protocols</a></li></ol> </div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
@ -147,13 +147,35 @@
<div id="content" class="content">
<main>
<h1 id="chapter-1"><a class="header" href="#chapter-1">Chapter 1</a></h1>
<h1 id="dappconnect-docs"><a class="header" href="#dappconnect-docs">DappConnect Docs</a></h1>
<p>DappConnect is a suite of libraries, SDKs and documentations to help you use Waku in your dApp.</p>
<p>Waku is a decentralized, censorship-resistant, network and protocol family.
It enables you to add communication features to your dApp in a decentralized manner,
ensuring to your users that they will not be censored or de-platformed.</p>
<p>Waku can be used for chat purposes and for many machine-to-machine use cases.
You can learn more about Waku at <a href="https://waku.vac.dev">waku.vac.dev</a>.</p>
<p>JS-Waku is the TypeScript implementation of the Waku protocol,
built for browser environment.</p>
<p>The <a href="./quick_start.html">quick start</a> presents an easy way to send and receive messages using js-waku.</p>
<p>The <a href="./guides">guides</a> explain specific js-waku features
and how it can be used with popular web frameworks.</p>
<p>The js-waku repository also holds a number of <a href="https://github.com/status-im/js-waku/tree/main/examples">examples</a>.
The examples are working Proof-of-Concepts that demonstrate how to use js-waku.
Check out the <a href="./examples.html">example list</a> to see what usage each example demonstrates. </p>
<p>Finally, if you want to learn how Waku works under the hoods, check the specs at <a href="https://rfc.vac.dev/">rfc.vac.dev</a>.</p>
<h2 id="bugs-questions--support"><a class="header" href="#bugs-questions--support">Bugs, Questions &amp; Support</a></h2>
<p>If you encounter any bug or would like to propose new features, feel free to <a href="https://github.com/status-im/js-waku/issues/new/">open an issue</a>.</p>
<p>To get help, join #dappconnect-support on <a href="https://discord.gg/j5pGbn7MHZ">Vac Discord</a> or <a href="https://t.me/dappconnectsupport">Telegram</a>.
For more general discussion and latest news, join #dappconnect on <a href="https://discord.gg/9DgykdmpZ6">Vac Discord</a> or <a href="https://t.me/dappconnect">Telegram</a>.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="next" href="quick_start.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
@ -162,6 +184,9 @@
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="next" href="quick_start.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>

1183
print.html

File diff suppressed because it is too large Load Diff

234
quick_start.html Normal file
View File

@ -0,0 +1,234 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Quick Start - DappConnect Docs</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="custom.css">
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="introduction.html">Introduction</a></li><li class="chapter-item expanded "><a href="quick_start.html" class="active"><strong aria-hidden="true">1.</strong> Quick Start</a></li><li class="chapter-item expanded "><a href="guides/index.html"><strong aria-hidden="true">2.</strong> Guides</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="guides/choose_content_topic.html"><strong aria-hidden="true">2.1.</strong> How to Choose a Content Topic</a></li><li class="chapter-item expanded "><a href="guides/relay_receive_send_messages.html"><strong aria-hidden="true">2.2.</strong> Receive and Send Messages Using Waku Relay</a></li><li class="chapter-item expanded "><a href="guides/store_retrieve_messages.html"><strong aria-hidden="true">2.3.</strong> Retrieve Messages Using Waku Store</a></li><li class="chapter-item expanded "><a href="guides/encrypt_messages_version_1.html"><strong aria-hidden="true">2.4.</strong> Encrypt Messages Using Waku Message Version 1</a></li><li class="chapter-item expanded "><a href="guides/reactjs_relay.html"><strong aria-hidden="true">2.5.</strong> Receive and Send Messages Using Waku Relay With ReactJS</a></li><li class="chapter-item expanded "><a href="guides/reactjs_store.html"><strong aria-hidden="true">2.6.</strong> Retrieve Messages Using Waku Store With ReactJS</a></li><li class="chapter-item expanded "><a href="guides/light_push_send_messages.html"><strong aria-hidden="true">2.7.</strong> Send Messages Using Waku Light Push</a></li></ol></li><li class="chapter-item expanded "><a href="examples.html"><strong aria-hidden="true">3.</strong> Examples</a></li><li class="chapter-item expanded affix "><a href="waku_protocols.html">Implemented Waku Protocols</a></li></ol> </div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">DappConnect Docs</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/vacp2p/docs.dappconnect.dev" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="quick-start"><a class="header" href="#quick-start">Quick Start</a></h1>
<p>In this section you will learn how to receive and send messages using Waku Relay.</p>
<p>A more in depth guide for Waku Relay can be found <a href="guides/relay_receive_send_messages.html">here</a>.</p>
<h2 id="install"><a class="header" href="#install">Install</a></h2>
<p>Install the <code>js-waku</code> package:</p>
<pre><code class="language-shell">npm install js-waku
# or with yarn
yarn add js-waku
</code></pre>
<h3 id="start-a-waku-node"><a class="header" href="#start-a-waku-node">Start a waku node</a></h3>
<pre><code class="language-ts">import { Waku } from 'js-waku';
const waku = await Waku.create({ bootstrap: true });
</code></pre>
<h3 id="listen-for-messages"><a class="header" href="#listen-for-messages">Listen for messages</a></h3>
<p>The <code>contentTopic</code> is a metadata <code>string</code> that allows categorization of messages on the waku network.
Depending on your use case, you can either create one (or several) new <code>contentTopic</code>(s)
or look at the <a href="https://rfc.vac.dev/">RFCs</a> and use an existing <code>contentTopic</code>.
See <a href="guides/choose_content_topic.html">How to Choose a Content Topic</a> for more details.</p>
<p>For example, if you were to use a new <code>contentTopic</code> such as <code>/my-cool-app/1/my-use-case/proto</code>,
here is how to listen to new messages received via <a href="https://rfc.vac.dev/spec/11/">Waku v2 Relay</a>:</p>
<pre><code class="language-ts">waku.relay.addObserver((msg) =&gt; {
console.log(&quot;Message received:&quot;, msg.payloadAsUtf8)
}, [&quot;/my-cool-app/1/my-use-case/proto&quot;]);
</code></pre>
<h3 id="send-messages"><a class="header" href="#send-messages">Send messages</a></h3>
<p>Messages are wrapped in a <code>WakuMessage</code> envelop.</p>
<pre><code class="language-ts">import { WakuMessage } from 'js-waku';
const msg = await WakuMessage.fromUtf8String(&quot;Here is a message!&quot;, &quot;/my-cool-app/1/my-use-case/proto&quot;)
await waku.relay.send(msg);
</code></pre>
<h3 id="building-an-app"><a class="header" href="#building-an-app">Building an app</a></h3>
<p>Check out the <a href="./guides/reactjs_relay.html">ReactJS Waku Relay guide</a> to learn how you can use the code above in a React app. </p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="introduction.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="guides/index.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="introduction.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="guides/index.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

222
waku_protocols.html Normal file
View File

@ -0,0 +1,222 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Implemented Waku Protocols - DappConnect Docs</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="custom.css">
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="introduction.html">Introduction</a></li><li class="chapter-item expanded "><a href="quick_start.html"><strong aria-hidden="true">1.</strong> Quick Start</a></li><li class="chapter-item expanded "><a href="guides/index.html"><strong aria-hidden="true">2.</strong> Guides</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="guides/choose_content_topic.html"><strong aria-hidden="true">2.1.</strong> How to Choose a Content Topic</a></li><li class="chapter-item expanded "><a href="guides/relay_receive_send_messages.html"><strong aria-hidden="true">2.2.</strong> Receive and Send Messages Using Waku Relay</a></li><li class="chapter-item expanded "><a href="guides/store_retrieve_messages.html"><strong aria-hidden="true">2.3.</strong> Retrieve Messages Using Waku Store</a></li><li class="chapter-item expanded "><a href="guides/encrypt_messages_version_1.html"><strong aria-hidden="true">2.4.</strong> Encrypt Messages Using Waku Message Version 1</a></li><li class="chapter-item expanded "><a href="guides/reactjs_relay.html"><strong aria-hidden="true">2.5.</strong> Receive and Send Messages Using Waku Relay With ReactJS</a></li><li class="chapter-item expanded "><a href="guides/reactjs_store.html"><strong aria-hidden="true">2.6.</strong> Retrieve Messages Using Waku Store With ReactJS</a></li><li class="chapter-item expanded "><a href="guides/light_push_send_messages.html"><strong aria-hidden="true">2.7.</strong> Send Messages Using Waku Light Push</a></li></ol></li><li class="chapter-item expanded "><a href="examples.html"><strong aria-hidden="true">3.</strong> Examples</a></li><li class="chapter-item expanded affix "><a href="waku_protocols.html" class="active">Implemented Waku Protocols</a></li></ol> </div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">DappConnect Docs</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/vacp2p/docs.dappconnect.dev" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h2 id="waku-protocol-support"><a class="header" href="#waku-protocol-support">Waku Protocol Support</a></h2>
<p>You can track progress on the <a href="https://github.com/status-im/js-waku/projects/1">project board</a>.</p>
<ul>
<li>✔: Supported</li>
<li>🚧: Implementation in progress</li>
<li>⛔: Support is not planned</li>
</ul>
<table><thead><tr><th>Spec</th><th>Implementation Status</th></tr></thead><tbody>
<tr><td><a href="https://rfc.vac.dev/spec/6">6/WAKU1</a></td><td></td></tr>
<tr><td><a href="https://rfc.vac.dev/spec/7">7/WAKU-DATA</a></td><td></td></tr>
<tr><td><a href="https://rfc.vac.dev/spec/8">8/WAKU-MAIL</a></td><td></td></tr>
<tr><td><a href="https://rfc.vac.dev/spec/9">9/WAKU-RPC</a></td><td></td></tr>
<tr><td><a href="https://rfc.vac.dev/spec/10">10/WAKU2</a></td><td>🚧</td></tr>
<tr><td><a href="https://rfc.vac.dev/spec/11">11/WAKU2-RELAY</a></td><td></td></tr>
<tr><td><a href="https://rfc.vac.dev/spec/12">12/WAKU2-FILTER</a></td><td></td></tr>
<tr><td><a href="https://rfc.vac.dev/spec/13">13/WAKU2-STORE</a></td><td>✔ (querying node only)</td></tr>
<tr><td><a href="https://rfc.vac.dev/spec/14">14/WAKU2-MESSAGE</a></td><td></td></tr>
<tr><td><a href="https://rfc.vac.dev/spec/15">15/WAKU2-BRIDGE</a></td><td></td></tr>
<tr><td><a href="https://rfc.vac.dev/spec/16">16/WAKU2-RPC</a></td><td></td></tr>
<tr><td><a href="https://rfc.vac.dev/spec/17">17/WAKU2-RLNRELAY</a></td><td></td></tr>
<tr><td><a href="https://rfc.vac.dev/spec/18">18/WAKU2-SWAP</a></td><td></td></tr>
<tr><td><a href="https://rfc.vac.dev/spec/19/">19/WAKU2-LIGHTPUSH</a></td><td></td></tr>
<tr><td><a href="https://rfc.vac.dev/spec/20/">20/TOY-ETH-PM</a></td><td>✔ (as example)</td></tr>
<tr><td><a href="https://rfc.vac.dev/spec/21/">21/WAKU2-FTSTORE</a></td><td></td></tr>
<tr><td><a href="https://rfc.vac.dev/spec/22/">22/TOY-CHAT</a></td><td>✔ (as example)</td></tr>
<tr><td><a href="https://rfc.vac.dev/spec/25/">25/LIBP2P-DNS-DISCOVERY</a></td><td>🚧</td></tr>
<tr><td><a href="https://rfc.vac.dev/spec/26/">26/WAKU2-PAYLOAD</a></td><td></td></tr>
</tbody></table>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="examples.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="examples.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>