mirror of
https://github.com/vacp2p/rfc-index.git
synced 2026-01-09 22:08:07 -05:00
1208 lines
78 KiB
HTML
1208 lines
78 KiB
HTML
<!DOCTYPE HTML>
|
|
<html lang="en" class="ayu" dir="ltr">
|
|
<head>
|
|
<!-- Book generated using mdBook -->
|
|
<meta charset="UTF-8">
|
|
<title>62/Payloads - Vac RFC</title>
|
|
|
|
|
|
<!-- Custom HTML head -->
|
|
|
|
<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 class="sidebar-visible no-js">
|
|
<div id="body-container">
|
|
<!-- Provide site root to javascript -->
|
|
<script>
|
|
var path_to_root = "../../";
|
|
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "ayu";
|
|
</script>
|
|
|
|
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
|
<script>
|
|
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>
|
|
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('ayu')
|
|
html.classList.add(theme);
|
|
var body = document.querySelector('body');
|
|
body.classList.remove('no-js')
|
|
body.classList.add('js');
|
|
</script>
|
|
|
|
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
|
|
|
<!-- Hide / unhide sidebar before it is displayed -->
|
|
<script>
|
|
var body = document.querySelector('body');
|
|
var sidebar = null;
|
|
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
|
if (document.body.clientWidth >= 1080) {
|
|
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
|
sidebar = sidebar || 'visible';
|
|
} else {
|
|
sidebar = 'hidden';
|
|
}
|
|
sidebar_toggle.checked = sidebar === 'visible';
|
|
body.classList.remove('sidebar-visible');
|
|
body.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="../../index.html">Introduction</a></li><li class="chapter-item expanded "><a href="../../vac/index.html"><strong aria-hidden="true">1.</strong> Vac</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../vac/1/coss.html"><strong aria-hidden="true">1.1.</strong> 1/COSS</a></li><li class="chapter-item expanded "><a href="../../vac/2/mvds.html"><strong aria-hidden="true">1.2.</strong> 2/MVDS</a></li><li class="chapter-item expanded "><a href="../../vac/3/remote-log.html"><strong aria-hidden="true">1.3.</strong> 3/Remote Log</a></li><li class="chapter-item expanded "><a href="../../vac/4/mvds-meta.html"><strong aria-hidden="true">1.4.</strong> 4/MVDS Meta</a></li><li class="chapter-item expanded "><a href="../../vac/25/libp2p-dns-discovery.html"><strong aria-hidden="true">1.5.</strong> 25/Libp2p DNS Discovery</a></li><li class="chapter-item expanded "><a href="../../vac/32/rln-v1.html"><strong aria-hidden="true">1.6.</strong> 32/RLN-V1</a></li><li class="chapter-item expanded "><a href="../../vac/raw/index.html"><strong aria-hidden="true">1.7.</strong> Raw</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../vac/raw/consensus-hashgraphlike.html"><strong aria-hidden="true">1.7.1.</strong> Consensus Hashgraphlike</a></li><li class="chapter-item expanded "><a href="../../vac/raw/decentralized-messaging-ethereum.html"><strong aria-hidden="true">1.7.2.</strong> Decentralized Messaging Ethereum</a></li><li class="chapter-item expanded "><a href="../../vac/raw/eth-mls-offchain.html"><strong aria-hidden="true">1.7.3.</strong> ETH MLS Offchain</a></li><li class="chapter-item expanded "><a href="../../vac/raw/eth-mls-onchain.html"><strong aria-hidden="true">1.7.4.</strong> ETH MLS Onchain</a></li><li class="chapter-item expanded "><a href="../../vac/raw/deleted/eth-secpm.html"><strong aria-hidden="true">1.7.5.</strong> ETH SecPM</a></li><li class="chapter-item expanded "><a href="../../vac/raw/gossipsub-tor-push.html"><strong aria-hidden="true">1.7.6.</strong> Gossipsub Tor Push</a></li><li class="chapter-item expanded "><a href="../../vac/raw/logos-capability-discovery.html"><strong aria-hidden="true">1.7.7.</strong> Logos Capability Discovery</a></li><li class="chapter-item expanded "><a href="../../vac/raw/mix.html"><strong aria-hidden="true">1.7.8.</strong> Mix</a></li><li class="chapter-item expanded "><a href="../../vac/raw/noise-x3dh-double-ratchet.html"><strong aria-hidden="true">1.7.9.</strong> Noise X3DH Double Ratchet</a></li><li class="chapter-item expanded "><a href="../../vac/raw/rln-interep-spec.html"><strong aria-hidden="true">1.7.10.</strong> RLN Interep Spec</a></li><li class="chapter-item expanded "><a href="../../vac/raw/rln-stealth-commitments.html"><strong aria-hidden="true">1.7.11.</strong> RLN Stealth Commitments</a></li><li class="chapter-item expanded "><a href="../../vac/raw/rln-v2.html"><strong aria-hidden="true">1.7.12.</strong> RLN-V2</a></li><li class="chapter-item expanded "><a href="../../vac/raw/sds.html"><strong aria-hidden="true">1.7.13.</strong> SDS</a></li></ol></li><li class="chapter-item expanded "><a href="../../vac/template.html"><strong aria-hidden="true">1.8.</strong> Template</a></li></ol></li><li class="chapter-item expanded "><a href="../../waku/index.html"><strong aria-hidden="true">2.</strong> Waku</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../waku/standards/core/index.html"><strong aria-hidden="true">2.1.</strong> Standards - Core</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../waku/standards/core/10/waku2.html"><strong aria-hidden="true">2.1.1.</strong> 10/Waku2</a></li><li class="chapter-item expanded "><a href="../../waku/standards/core/11/relay.html"><strong aria-hidden="true">2.1.2.</strong> 11/Relay</a></li><li class="chapter-item expanded "><a href="../../waku/standards/core/12/filter.html"><strong aria-hidden="true">2.1.3.</strong> 12/Filter</a></li><li class="chapter-item expanded "><a href="../../waku/standards/core/13/store.html"><strong aria-hidden="true">2.1.4.</strong> 13/Store</a></li><li class="chapter-item expanded "><a href="../../waku/standards/core/14/message.html"><strong aria-hidden="true">2.1.5.</strong> 14/Message</a></li><li class="chapter-item expanded "><a href="../../waku/standards/core/15/bridge.html"><strong aria-hidden="true">2.1.6.</strong> 15/Bridge</a></li><li class="chapter-item expanded "><a href="../../waku/standards/core/17/rln-relay.html"><strong aria-hidden="true">2.1.7.</strong> 17/RLN Relay</a></li><li class="chapter-item expanded "><a href="../../waku/standards/core/19/lightpush.html"><strong aria-hidden="true">2.1.8.</strong> 19/Lightpush</a></li><li class="chapter-item expanded "><a href="../../waku/standards/core/31/enr.html"><strong aria-hidden="true">2.1.9.</strong> 31/ENR</a></li><li class="chapter-item expanded "><a href="../../waku/standards/core/33/discv5.html"><strong aria-hidden="true">2.1.10.</strong> 33/Discv5</a></li><li class="chapter-item expanded "><a href="../../waku/standards/core/34/peer-exchange.html"><strong aria-hidden="true">2.1.11.</strong> 34/Peer Exchange</a></li><li class="chapter-item expanded "><a href="../../waku/standards/core/36/bindings-api.html"><strong aria-hidden="true">2.1.12.</strong> 36/Bindings API</a></li><li class="chapter-item expanded "><a href="../../waku/standards/core/64/network.html"><strong aria-hidden="true">2.1.13.</strong> 64/Network</a></li><li class="chapter-item expanded "><a href="../../waku/standards/core/66/metadata.html"><strong aria-hidden="true">2.1.14.</strong> 66/Metadata</a></li></ol></li><li class="chapter-item expanded "><a href="../../waku/standards/application/index.html"><strong aria-hidden="true">2.2.</strong> Standards - Application</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../waku/standards/application/20/toy-eth-pm.html"><strong aria-hidden="true">2.2.1.</strong> 20/Toy ETH PM</a></li><li class="chapter-item expanded "><a href="../../waku/standards/application/26/payload.html"><strong aria-hidden="true">2.2.2.</strong> 26/Payload</a></li><li class="chapter-item expanded "><a href="../../waku/standards/application/53/x3dh.html"><strong aria-hidden="true">2.2.3.</strong> 53/X3DH</a></li><li class="chapter-item expanded "><a href="../../waku/standards/application/54/x3dh-sessions.html"><strong aria-hidden="true">2.2.4.</strong> 54/X3DH Sessions</a></li></ol></li><li class="chapter-item expanded "><a href="../../waku/standards/legacy/index.html"><strong aria-hidden="true">2.3.</strong> Standards - Legacy</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../waku/standards/legacy/6/waku1.html"><strong aria-hidden="true">2.3.1.</strong> 6/Waku1</a></li><li class="chapter-item expanded "><a href="../../waku/standards/legacy/7/data.html"><strong aria-hidden="true">2.3.2.</strong> 7/Data</a></li><li class="chapter-item expanded "><a href="../../waku/standards/legacy/8/mail.html"><strong aria-hidden="true">2.3.3.</strong> 8/Mail</a></li><li class="chapter-item expanded "><a href="../../waku/standards/legacy/9/rpc.html"><strong aria-hidden="true">2.3.4.</strong> 9/RPC</a></li></ol></li><li class="chapter-item expanded "><a href="../../waku/informational/index.html"><strong aria-hidden="true">2.4.</strong> Informational</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../waku/informational/22/toy-chat.html"><strong aria-hidden="true">2.4.1.</strong> 22/Toy Chat</a></li><li class="chapter-item expanded "><a href="../../waku/informational/23/topics.html"><strong aria-hidden="true">2.4.2.</strong> 23/Topics</a></li><li class="chapter-item expanded "><a href="../../waku/informational/27/peers.html"><strong aria-hidden="true">2.4.3.</strong> 27/Peers</a></li><li class="chapter-item expanded "><a href="../../waku/informational/29/config.html"><strong aria-hidden="true">2.4.4.</strong> 29/Config</a></li><li class="chapter-item expanded "><a href="../../waku/informational/30/adaptive-nodes.html"><strong aria-hidden="true">2.4.5.</strong> 30/Adaptive Nodes</a></li></ol></li><li class="chapter-item expanded "><a href="../../waku/deprecated/index.html"><strong aria-hidden="true">2.5.</strong> Deprecated</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../waku/deprecated/5/waku0.html"><strong aria-hidden="true">2.5.1.</strong> 5/Waku0</a></li><li class="chapter-item expanded "><a href="../../waku/deprecated/16/rpc.html"><strong aria-hidden="true">2.5.2.</strong> 16/RPC</a></li><li class="chapter-item expanded "><a href="../../waku/deprecated/18/swap.html"><strong aria-hidden="true">2.5.3.</strong> 18/Swap</a></li><li class="chapter-item expanded "><a href="../../waku/deprecated/fault-tolerant-store.html"><strong aria-hidden="true">2.5.4.</strong> Fault Tolerant Store</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="../../nomos/index.html"><strong aria-hidden="true">3.</strong> Nomos</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../nomos/raw/index.html"><strong aria-hidden="true">3.1.</strong> Raw</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../nomos/raw/nomosda-encoding.html"><strong aria-hidden="true">3.1.1.</strong> NomosDA Encoding</a></li><li class="chapter-item expanded "><a href="../../nomos/raw/nomosda-network.html"><strong aria-hidden="true">3.1.2.</strong> NomosDA Network</a></li><li class="chapter-item expanded "><a href="../../nomos/raw/p2p-hardware-requirements.html"><strong aria-hidden="true">3.1.3.</strong> P2P Hardware Requirements</a></li><li class="chapter-item expanded "><a href="../../nomos/raw/p2p-nat-solution.html"><strong aria-hidden="true">3.1.4.</strong> P2P NAT Solution</a></li><li class="chapter-item expanded "><a href="../../nomos/raw/p2p-network-bootstrapping.html"><strong aria-hidden="true">3.1.5.</strong> P2P Network Bootstrapping</a></li><li class="chapter-item expanded "><a href="../../nomos/raw/p2p-network.html"><strong aria-hidden="true">3.1.6.</strong> P2P Network</a></li><li class="chapter-item expanded "><a href="../../nomos/raw/sdp.html"><strong aria-hidden="true">3.1.7.</strong> SDP</a></li></ol></li><li class="chapter-item expanded "><a href="../../nomos/deprecated/index.html"><strong aria-hidden="true">3.2.</strong> Deprecated</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../nomos/deprecated/claro.html"><strong aria-hidden="true">3.2.1.</strong> Claro</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="../../codex/index.html"><strong aria-hidden="true">4.</strong> Codex</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../codex/raw/index.html"><strong aria-hidden="true">4.1.</strong> Raw</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../codex/raw/codex-block-exchange.html"><strong aria-hidden="true">4.1.1.</strong> Block Exchange</a></li><li class="chapter-item expanded "><a href="../../codex/raw/codex-marketplace.html"><strong aria-hidden="true">4.1.2.</strong> Marketplace</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="../../status/index.html"><strong aria-hidden="true">5.</strong> Status</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../status/24/curation.html"><strong aria-hidden="true">5.1.</strong> 24/Curation</a></li><li class="chapter-item expanded "><a href="../../status/28/featuring.html"><strong aria-hidden="true">5.2.</strong> 28/Featuring</a></li><li class="chapter-item expanded "><a href="../../status/55/1to1-chat.html"><strong aria-hidden="true">5.3.</strong> 55/1-to-1 Chat</a></li><li class="chapter-item expanded "><a href="../../status/56/communities.html"><strong aria-hidden="true">5.4.</strong> 56/Communities</a></li><li class="chapter-item expanded "><a href="../../status/61/community-history-service.html"><strong aria-hidden="true">5.5.</strong> 61/Community History Service</a></li><li class="chapter-item expanded "><a href="../../status/62/payloads.html" class="active"><strong aria-hidden="true">5.6.</strong> 62/Payloads</a></li><li class="chapter-item expanded "><a href="../../status/63/keycard-usage.html"><strong aria-hidden="true">5.7.</strong> 63/Keycard Usage</a></li><li class="chapter-item expanded "><a href="../../status/65/account-address.html"><strong aria-hidden="true">5.8.</strong> 65/Account Address</a></li><li class="chapter-item expanded "><a href="../../status/71/push-notification-server.html"><strong aria-hidden="true">5.9.</strong> 71/Push Notification Server</a></li><li class="chapter-item expanded "><a href="../../status/raw/index.html"><strong aria-hidden="true">5.10.</strong> Raw</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../status/raw/simple-scaling.html"><strong aria-hidden="true">5.10.1.</strong> Simple Scaling</a></li><li class="chapter-item expanded "><a href="../../status/raw/status-app-protocols.html"><strong aria-hidden="true">5.10.2.</strong> Status App Protocols</a></li><li class="chapter-item expanded "><a href="../../status/raw/status-mvds.html"><strong aria-hidden="true">5.10.3.</strong> Status MVDS</a></li><li class="chapter-item expanded "><a href="../../status/raw/url-data.html"><strong aria-hidden="true">5.10.4.</strong> URL Data</a></li><li class="chapter-item expanded "><a href="../../status/raw/url-scheme.html"><strong aria-hidden="true">5.10.5.</strong> URL Scheme</a></li></ol></li><li class="chapter-item expanded "><a href="../../status/deprecated/index.html"><strong aria-hidden="true">5.11.</strong> Deprecated</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../status/deprecated/3rd-party.html"><strong aria-hidden="true">5.11.1.</strong> 3rd Party</a></li><li class="chapter-item expanded "><a href="../../status/deprecated/account.html"><strong aria-hidden="true">5.11.2.</strong> Account</a></li><li class="chapter-item expanded "><a href="../../status/deprecated/client.html"><strong aria-hidden="true">5.11.3.</strong> Client</a></li><li class="chapter-item expanded "><a href="../../status/deprecated/dapp-browser-API-usage.html"><strong aria-hidden="true">5.11.4.</strong> Dapp Browser API Usage</a></li><li class="chapter-item expanded "><a href="../../status/deprecated/eips.html"><strong aria-hidden="true">5.11.5.</strong> EIPs</a></li><li class="chapter-item expanded "><a href="../../status/deprecated/ethereum-usage.html"><strong aria-hidden="true">5.11.6.</strong> Ethereum Usage</a></li><li class="chapter-item expanded "><a href="../../status/deprecated/group-chat.html"><strong aria-hidden="true">5.11.7.</strong> Group Chat</a></li><li class="chapter-item expanded "><a href="../../status/deprecated/IPFS-gateway-for-sticker-Pack.html"><strong aria-hidden="true">5.11.8.</strong> IPFS Gateway for Sticker Pack</a></li><li class="chapter-item expanded "><a href="../../status/deprecated/keycard-usage-for-wallet-and-chat-keys.html"><strong aria-hidden="true">5.11.9.</strong> Keycard Usage for Wallet and Chat Keys</a></li><li class="chapter-item expanded "><a href="../../status/deprecated/notifications.html"><strong aria-hidden="true">5.11.10.</strong> Notifications</a></li><li class="chapter-item expanded "><a href="../../status/deprecated/payloads.html"><strong aria-hidden="true">5.11.11.</strong> Payloads</a></li><li class="chapter-item expanded "><a href="../../status/deprecated/push-notification-server.html"><strong aria-hidden="true">5.11.12.</strong> Push Notification Server</a></li><li class="chapter-item expanded "><a href="../../status/deprecated/secure-transport.html"><strong aria-hidden="true">5.11.13.</strong> Secure Transport</a></li><li class="chapter-item expanded "><a href="../../status/deprecated/waku-mailserver.html"><strong aria-hidden="true">5.11.14.</strong> Waku Mailserver</a></li><li class="chapter-item expanded "><a href="../../status/deprecated/waku-usage.html"><strong aria-hidden="true">5.11.15.</strong> Waku Usage</a></li><li class="chapter-item expanded "><a href="../../status/deprecated/whisper-mailserver.html"><strong aria-hidden="true">5.11.16.</strong> Whisper Mailserver</a></li><li class="chapter-item expanded "><a href="../../status/deprecated/whisper-usage.html"><strong aria-hidden="true">5.11.17.</strong> Whisper Usage</a></li></ol></li></ol></li></ol>
|
|
</div>
|
|
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
|
<div class="sidebar-resize-indicator"></div>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- Track and set sidebar scroll position -->
|
|
<script>
|
|
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
|
sidebarScrollbox.addEventListener('click', function(e) {
|
|
if (e.target.tagName === 'A') {
|
|
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
|
}
|
|
}, { passive: true });
|
|
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
|
sessionStorage.removeItem('sidebar-scroll');
|
|
if (sidebarScrollTop) {
|
|
// preserve sidebar scroll position when navigating via links within sidebar
|
|
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
|
} else {
|
|
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
|
var activeSection = document.querySelector('#sidebar .active');
|
|
if (activeSection) {
|
|
activeSection.scrollIntoView({ block: 'center' });
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<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">
|
|
<div class="left-buttons">
|
|
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
|
<i class="fa fa-bars"></i>
|
|
</label>
|
|
<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</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">Vac RFC</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/rfc-index" 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>
|
|
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="62status-payloads"><a class="header" href="#62status-payloads">62/STATUS-PAYLOADS</a></h1>
|
|
<div class="rfc-meta">
|
|
<table>
|
|
<tr><th>Name</th><td>Status Message Payloads</td></tr>
|
|
<tr><th>Slug</th><td>62</td></tr>
|
|
<tr><th>Status</th><td>draft</td></tr>
|
|
<tr><th>Editor</th><td>r4bbit <r4bbit@status.im></td></tr>
|
|
<tr><th>Contributors</th><td>Adam Babik <adam@status.im><br>Andrea Maria Piana <andreap@status.im><br>Oskar Thoren <oskarth@titanproxy.com><br>Samuel Hawksby-Robinson <samuel@status.im></td></tr>
|
|
</table>
|
|
</div>
|
|
<!-- timeline:start -->
|
|
<h2 id="timeline"><a class="header" href="#timeline">Timeline</a></h2>
|
|
<ul>
|
|
<li><strong>2025-12-22</strong> — <a href="https://github.com/vacp2p/rfc-index/blob/b1a578393edf8487ccc97a5f25b25af9bf41efb3/docs/status/62/payloads.md"><code>b1a5783</code></a> — Chore/mdbook updates (#237)</li>
|
|
<li><strong>2025-12-18</strong> — <a href="https://github.com/vacp2p/rfc-index/blob/d03e699084774ebecef9c6d4662498907c5e2080/docs/status/62/payloads.md"><code>d03e699</code></a> — ci: add mdBook configuration (#233)</li>
|
|
<li><strong>2024-09-16</strong> — <a href="https://github.com/vacp2p/rfc-index/blob/ad80a59e2ba8f18c179158973d31e7fac2cb714a/status/62/payloads.md"><code>ad80a59</code></a> — 62/STATUS-PAYLOAD: Add Description (#95)</li>
|
|
<li><strong>2024-09-13</strong> — <a href="https://github.com/vacp2p/rfc-index/blob/3ab314d87d4525ff1296bf3d9ec634d570777b91/status/62/payloads.md"><code>3ab314d</code></a> — Fix Files for Linting (#94)</li>
|
|
<li><strong>2024-02-07</strong> — <a href="https://github.com/vacp2p/rfc-index/blob/1abf2c9c7bbef07b75637d8f897d25108b984dc2/status/62/payloads.md"><code>1abf2c9</code></a> — Rename payload.md to payloads.md</li>
|
|
<li><strong>2024-02-07</strong> — <a href="https://github.com/vacp2p/rfc-index/blob/e2b9e32028c91650310e786c377c938510ba229a/status/62/payload.md"><code>e2b9e32</code></a> — Update payload.md</li>
|
|
<li><strong>2024-02-05</strong> — <a href="https://github.com/vacp2p/rfc-index/blob/20e9a66cf80cbc565ccff914a0d97f87b8fcbe2e/status/62/payload.md"><code>20e9a66</code></a> — Rename payloads.md to payload.md</li>
|
|
<li><strong>2024-02-05</strong> — <a href="https://github.com/vacp2p/rfc-index/blob/488ce9b72cc0b670cbbdcbacedc3a92dc8295a24/status/62/payloads.md"><code>488ce9b</code></a> — Create payloads.md</li>
|
|
</ul>
|
|
<!-- timeline:end -->
|
|
<h2 id="abstract"><a class="header" href="#abstract">Abstract</a></h2>
|
|
<p>This specification describes how the payload of each message in Status looks
|
|
like.
|
|
It is primarily centered around chat and chat-related use cases.</p>
|
|
<p>The payloads aims to be flexible enough to support messaging but also cases
|
|
described in the <a href="https://status.im/whitepaper.pdf">Status Whitepaper</a> as well
|
|
as various clients created using different technologies.</p>
|
|
<h2 id="wire-format-specification"><a class="header" href="#wire-format-specification">Wire Format Specification</a></h2>
|
|
<h3 id="payload-wrapper"><a class="header" href="#payload-wrapper">Payload wrapper</a></h3>
|
|
<p>The node wraps all payloads in a <a href="https://developers.google.com/protocol-buffers/">protobuf record</a>
|
|
record:</p>
|
|
<pre><code class="language-protobuf">message StatusProtocolMessage {
|
|
bytes signature = 4001;
|
|
bytes payload = 4002;
|
|
}
|
|
</code></pre>
|
|
<p><code>signature</code> is the bytes of the signed <code>SHA3-256</code> of the payload,
|
|
signed with the key of the author of the message.
|
|
The node needs the signature to validate authorship of the message,
|
|
so that the message can be relayed to third parties.
|
|
If a signature is not present, but an author is provided by a layer below,
|
|
the message is not to be relayed to third parties,
|
|
and it is considered plausibly deniable.</p>
|
|
<h3 id="encoding"><a class="header" href="#encoding">Encoding</a></h3>
|
|
<p>The node encodes the payload using <a href="https://developers.google.com/protocol-buffers">Protobuf</a></p>
|
|
<h3 id="types-of-messages"><a class="header" href="#types-of-messages">Types of messages</a></h3>
|
|
<h4 id="chatmessage"><a class="header" href="#chatmessage">ChatMessage</a></h4>
|
|
<p>The type <code>ChatMessage</code> represents a chat message exchanged between clients.</p>
|
|
<p>Payload</p>
|
|
<p>The protobuf description is:</p>
|
|
<pre><code class="language-protobuf">message ChatMessage {
|
|
// Lamport timestamp of the chat message
|
|
uint64 clock = 1;
|
|
// Unix timestamps in milliseconds, currently not used as we use whisper as
|
|
// more reliable, but here so that we don't rely on it
|
|
uint64 timestamp = 2;
|
|
// Text of the message
|
|
string text = 3;
|
|
// Id of the message that we are replying to
|
|
string response_to = 4;
|
|
// Ens name of the sender
|
|
string ens_name = 5;
|
|
// Chat id, this field is symmetric for public-chats and private group chats,
|
|
// but asymmetric in case of one-to-ones, as the sender will use the chat-id
|
|
// of the received, while the receiver will use the chat-id of the sender.
|
|
// Probably should be the concatenation of sender-pk & receiver-pk in
|
|
// alphabetical order
|
|
string chat_id = 6;
|
|
|
|
// The type of message (public/one-to-one/private-group-chat)
|
|
MessageType message_type = 7;
|
|
// The type of the content of the message
|
|
ContentType content_type = 8;
|
|
|
|
oneof payload {
|
|
StickerMessage sticker = 9;
|
|
ImageMessage image = 10;
|
|
AudioMessage audio = 11;
|
|
bytes community = 12;
|
|
DiscordMessage discord_message = 99;
|
|
}
|
|
|
|
// Grant for community chat messages
|
|
bytes grant = 13;
|
|
|
|
// Message author's display name, introduced in version 1
|
|
string display_name = 14;
|
|
|
|
ContactRequestPropagatedState contact_request_propagated_state = 15;
|
|
|
|
repeated UnfurledLink unfurled_links = 16;
|
|
|
|
enum ContentType {
|
|
UNKNOWN_CONTENT_TYPE = 0;
|
|
TEXT_PLAIN = 1;
|
|
STICKER = 2;
|
|
STATUS = 3;
|
|
EMOJI = 4;
|
|
TRANSACTION_COMMAND = 5;
|
|
// Only local
|
|
SYSTEM_MESSAGE_CONTENT_PRIVATE_GROUP = 6;
|
|
IMAGE = 7;
|
|
AUDIO = 8;
|
|
COMMUNITY = 9;
|
|
// Only local
|
|
SYSTEM_MESSAGE_GAP = 10;
|
|
CONTACT_REQUEST = 11;
|
|
DISCORD_MESSAGE = 12;
|
|
IDENTITY_VERIFICATION = 13;
|
|
// Only local
|
|
SYSTEM_MESSAGE_PINNED_MESSAGE = 14;
|
|
// Only local
|
|
SYSTEM_MESSAGE_MUTUAL_EVENT_SENT = 15;
|
|
// Only local
|
|
SYSTEM_MESSAGE_MUTUAL_EVENT_ACCEPTED = 16;
|
|
// Only local
|
|
SYSTEM_MESSAGE_MUTUAL_EVENT_REMOVED = 17;
|
|
}
|
|
}
|
|
</code></pre>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>The clock of the chat</td></tr>
|
|
<tr><td>2</td><td>timestamp</td><td><code>uint64</code></td><td>The sender timestamp at message creation</td></tr>
|
|
<tr><td>3</td><td>text</td><td><code>string</code></td><td>The content of the message</td></tr>
|
|
<tr><td>4</td><td>response_to</td><td><code>string</code></td><td>The ID of the message replied to</td></tr>
|
|
<tr><td>5</td><td>ens_name</td><td><code>string</code></td><td>The ENS name of the user sending the message</td></tr>
|
|
<tr><td>6</td><td>chat_id</td><td><code>string</code></td><td>The local ID of the chat the message is sent to</td></tr>
|
|
<tr><td>7</td><td>message_type</td><td><code>MessageType</code></td><td>The type of message, different for one-to-one, public or group chats</td></tr>
|
|
<tr><td>8</td><td>content_type</td><td><code>ContentType</code></td><td>The type of the content of the message</td></tr>
|
|
<tr><td>9</td><td>payload</td><td><code>Sticker</code> I <code>Image</code> I <code>Audio</code> I <code>DiscordMessage</code> I <code>bytes</code> I nil`</td><td>The payload of the message based on the content type</td></tr>
|
|
<tr><td>13</td><td>grant</td><td><code>bytes</code></td><td>Grant for community chat messages</td></tr>
|
|
<tr><td>14</td><td>display_name</td><td><code>string</code></td><td>The message author's display name</td></tr>
|
|
<tr><td>15</td><td>contact_request_propagated_state</td><td><code>ContactRequestPropagatedState</code></td><td>Contact request clock values</td></tr>
|
|
<tr><td>16</td><td>unfurled_links</td><td><code>UnfurledLink[]</code></td><td>Unfurled links and their metadata that have been attached to the message</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h4 id="content-types"><a class="header" href="#content-types">Content types</a></h4>
|
|
<p>A node requires content types for a proper interpretation of incoming messages.
|
|
Not each message is plain text but may carry different information.</p>
|
|
<p>The following content types MUST be supported:</p>
|
|
<ul>
|
|
<li><code>TEXT_PLAIN</code> identifies a message which content is a plaintext.</li>
|
|
</ul>
|
|
<p>There are other content types that MAY be implemented by the client:</p>
|
|
<ul>
|
|
<li><code>STICKER</code></li>
|
|
<li><code>STATUS</code></li>
|
|
<li><code>EMOJI</code></li>
|
|
<li><code>TRANSACTION_COMMAND</code></li>
|
|
<li><code>IMAGE</code></li>
|
|
<li><code>AUDIO</code></li>
|
|
<li><code>COMMUNITY</code></li>
|
|
<li><code>CONTACT_REQUEST</code></li>
|
|
<li><code>DISCORD_MESSAGE</code></li>
|
|
<li><code>IDENTITY_VERIFICATION</code></li>
|
|
</ul>
|
|
<h5 id="mentions"><a class="header" href="#mentions">Mentions</a></h5>
|
|
<p>A mention MUST be represented as a string with the <code>@0xpk</code> format,
|
|
where <code>pk</code> is the public key of the
|
|
<a href="https://specs.status.im/spec/2">user account</a> to be mentioned,
|
|
within the <code>text</code> field of a message with content_type <code>TEXT_PLAIN</code>.
|
|
A message MAY contain more than one mention.
|
|
This specification RECOMMENDs that the application
|
|
does not require the user to enter the entire pk.
|
|
This specification RECOMMENDs that the application
|
|
allows the user to create a mention by typing @ followed by the related ENS or
|
|
3-word pseudonym.
|
|
This specification RECOMMENDs that the application
|
|
provides the user auto-completion functionality to create a mention.
|
|
For better user experience,
|
|
the client SHOULD display a known
|
|
<a href="https://specs.status.im/spec/2#contact-verification">ens name or the 3-word pseudonym corresponding to the key</a>
|
|
instead of the <code>pk</code>.</p>
|
|
<h5 id="sticker-content-type"><a class="header" href="#sticker-content-type">Sticker content type</a></h5>
|
|
<p>A <code>ChatMessage</code> with <code>STICKER</code> <code>Content/Type</code> MUST also specify the ID of the <code>Pack</code>
|
|
and the <code>Hash</code> of the pack, in the <code>Sticker</code> field of <code>ChatMessage</code></p>
|
|
<pre><code class="language-protobuf">message StickerMessage {
|
|
string hash = 1;
|
|
int32 pack = 2;
|
|
}
|
|
</code></pre>
|
|
<h5 id="image-content-type"><a class="header" href="#image-content-type">Image content type</a></h5>
|
|
<p>A <code>ChatMessage</code> with <code>IMAGE</code> <code>Content/Type</code> MUST also
|
|
specify the <code>payload</code> of the image and the <code>type</code>.</p>
|
|
<p>Clients MUST sanitize the payload before accessing its content, in particular:</p>
|
|
<ul>
|
|
<li>Clients MUST choose a secure decoder</li>
|
|
<li>Clients SHOULD strip metadata if present without parsing/decoding it</li>
|
|
<li>Clients SHOULD NOT add metadata/exif when sending an image file for privacy
|
|
and security reasons</li>
|
|
<li>Clients MUST make sure that the transport layer constraints the size of the payload
|
|
to limit they are able to handle securely</li>
|
|
</ul>
|
|
<pre><code class="language-protobuf">message ImageMessage {
|
|
bytes payload = 1;
|
|
ImageType type = 2;
|
|
enum ImageType {
|
|
UNKNOWN_IMAGE_TYPE = 0;
|
|
PNG = 1;
|
|
JPEG = 2;
|
|
WEBP = 3;
|
|
GIF = 4;
|
|
}
|
|
}
|
|
</code></pre>
|
|
<h5 id="audio-content-type"><a class="header" href="#audio-content-type">Audio content type</a></h5>
|
|
<p>A <code>ChatMessage</code> with <code>AUDIO</code>,
|
|
<code>Content/Type</code> MUST also specify the <code>payload</code> of the audio,
|
|
the <code>type</code> and the duration in milliseconds (<code>duration_ms</code>).</p>
|
|
<p>Clients MUST sanitize the payload before accessing its content, in particular:</p>
|
|
<ul>
|
|
<li>Clients MUST choose a secure decoder</li>
|
|
<li>Clients SHOULD strip metadata if present without parsing/decoding it</li>
|
|
<li>Clients SHOULD NOT add metadata/exif when sending an audio file for privacy
|
|
and security reasons</li>
|
|
<li>Clients MUST make sure that the transport layer constraints the size
|
|
of the payload to limit they are able to handle securely</li>
|
|
</ul>
|
|
<pre><code class="language-protobuf">message AudioMessage {
|
|
bytes payload = 1;
|
|
AudioType type = 2;
|
|
uint64 duration_ms = 3;
|
|
enum AudioType {
|
|
UNKNOWN_AUDIO_TYPE = 0;
|
|
AAC = 1;
|
|
AMR = 2;
|
|
</code></pre>
|
|
<h5 id="community-content-type"><a class="header" href="#community-content-type">Community content type</a></h5>
|
|
<p>A <code>ChatMessage</code> with <code>COMMUNITY</code> <code>Content/Type</code>,
|
|
MUST also specify the <code>payload</code> of the community as bytes from a <a href="#communitydescription">CommunityDescription</a>.</p>
|
|
<h5 id="discordmessage-content-type"><a class="header" href="#discordmessage-content-type">DiscordMessage content type</a></h5>
|
|
<p>A <code>ChatMessage</code> with <code>DISCORD_MESSAGE</code> <code>Content/Type</code>,
|
|
MUST also specify the <code>payload</code> of the <code>DiscordMessage</code>.</p>
|
|
<pre><code class="language-protobuf">message DiscordMessage {
|
|
string id = 1;
|
|
string type = 2;
|
|
string timestamp = 3;
|
|
string timestampEdited = 4;
|
|
string content = 5;
|
|
DiscordMessageAuthor author = 6;
|
|
DiscordMessageReference reference = 7;
|
|
repeated DiscordMessageAttachment attachments = 8;
|
|
}
|
|
|
|
message DiscordMessageAuthor {
|
|
string id = 1;
|
|
string name = 2;
|
|
string discriminator = 3;
|
|
string nickname = 4;
|
|
string avatarUrl = 5;
|
|
bytes avatarImagePayload = 6;
|
|
string localUrl = 7;
|
|
}
|
|
|
|
message DiscordMessageReference {
|
|
string messageId = 1;
|
|
string channelId = 2;
|
|
string guildId = 3;
|
|
}
|
|
|
|
message DiscordMessageAttachment {
|
|
string id = 1;
|
|
string messageId = 2;
|
|
string url = 3;
|
|
string fileName = 4;
|
|
uint64 fileSizeBytes = 5;
|
|
string contentType = 6;
|
|
bytes payload = 7;
|
|
string localUrl = 8;
|
|
}
|
|
</code></pre>
|
|
<h4 id="message-types"><a class="header" href="#message-types">Message types</a></h4>
|
|
<p>A node requires message types to decide how to encrypt a particular message and
|
|
what metadata needs to be attached when passing a message to the transport layer.
|
|
For more on this, see <a href="../../waku/standards/core/10/waku2.html">10/WAKU2</a>.</p>
|
|
<!-- TODO: This reference is a bit odd,
|
|
considering the layer payloads should interact with is Secure Transport, and
|
|
not Whisper/Waku. This requires more detail -->
|
|
<p>The following messages types MUST be supported:</p>
|
|
<ul>
|
|
<li><code>ONE_TO_ONE</code> is a message to the public group</li>
|
|
<li><code>PUBLIC_GROUP</code> is a private message</li>
|
|
<li><code>PRIVATE_GROUP</code> is a message to the private group.</li>
|
|
<li><code>COMMUNITY_CHAT</code> is a message to a community channe.</li>
|
|
</ul>
|
|
<pre><code class="language-protobuf">enum MessageType {
|
|
UNKNOWN_MESSAGE_TYPE = 0;
|
|
ONE_TO_ONE = 1;
|
|
PUBLIC_GROUP = 2;
|
|
PRIVATE_GROUP = 3;
|
|
// Only local
|
|
SYSTEM_MESSAGE_PRIVATE_GROUP = 4;
|
|
COMMUNITY_CHAT = 5;
|
|
// Only local
|
|
SYSTEM_MESSAGE_GAP = 6;
|
|
}
|
|
</code></pre>
|
|
<h4 id="clock-vs-timestamp-and-message-ordering"><a class="header" href="#clock-vs-timestamp-and-message-ordering">Clock vs Timestamp and message ordering</a></h4>
|
|
<p>If a user sends a new message,
|
|
before the messages sent while the user was offline are received,
|
|
the new message is supposed to be displayed last in a chat.
|
|
This is where the basic algorithm of Lamport timestamp would fall short as
|
|
it's only meant to order causally related events.</p>
|
|
<p>The status client therefore makes a "bid",
|
|
speculating that it will beat the current chat-timestamp,
|
|
s.t. the status client's Lamport timestamp format is:
|
|
<code>clock = max({timestamp}, chat_clock + 1)</code></p>
|
|
<p>This will satisfy the Lamport requirement, namely: a -> b then T(a) < T(b)</p>
|
|
<p><code>timestamp</code> MUST be Unix time calculated, when the node creates the message,
|
|
in milliseconds.
|
|
This field SHOULD not be relied upon for message ordering.</p>
|
|
<p><code>clock</code> SHOULD be calculated using the algorithm of
|
|
<a href="https://en.wikipedia.org/wiki/Lamport_timestamps">Lamport timestamps</a>.
|
|
When there are messages available in a chat,
|
|
the node calculates <code>clock</code>'s value
|
|
based on the last received message in a particular chat:
|
|
<code>max(timeNowInMs, last-message-clock-value + 1)</code>.
|
|
If there are no messages, <code>clock</code> is initialized with <code>timestamp</code>'s value.</p>
|
|
<p>Messages with a <code>clock</code> greater than <code>120</code> seconds over the Whisper/Waku timestamp
|
|
SHOULD be discarded,
|
|
in order to avoid malicious users to increase the <code>clock</code> of a chat arbitrarily.</p>
|
|
<p>Messages with a <code>clock</code> less than <code>120</code> seconds under the Whisper/Waku timestamp
|
|
might indicate an attempt to insert messages in the chat history,
|
|
which is not distinguishable from a <code>datasync</code> layer re-transit event.
|
|
A client MAY mark this messages with a warning to the user, or discard them.</p>
|
|
<p>The node uses <code>clock</code> value for the message ordering.
|
|
The algorithm used, and
|
|
the distributed nature of the system produces casual ordering,
|
|
which might produce counter-intuitive results in some edge cases.
|
|
For example, when a user joins a public chat and
|
|
sends a message before receiving the exist messages,
|
|
their message <code>clock</code> value might be lower and
|
|
the message will end up in the past when the historical messages are fetched.</p>
|
|
<h4 id="chats"><a class="header" href="#chats">Chats</a></h4>
|
|
<p>Chat is a structure that helps organize messages.
|
|
It's usually desired to display messages only from a single recipient,
|
|
or a group of recipients at a time and chats help to achieve that.</p>
|
|
<p>All incoming messages can be matched against a chat.
|
|
The below table describes how to calculate a chat ID for each message type.</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Message Type</th><th>Chat ID Calculation</th><th>Direction</th><th>Comment</th></tr></thead><tbody>
|
|
<tr><td>PUBLIC_GROUP</td><td>chat ID is equal to a public channel name; it should equal <code>chatId</code> from the message</td><td>Incoming/Outgoing</td><td></td></tr>
|
|
<tr><td>ONE_TO_ONE</td><td>let <code>P</code> be a public key of the recipient; <code>hex-encode(P)</code> is a chat ID; use it as <code>chatId</code> value in the message</td><td>Outgoing</td><td></td></tr>
|
|
<tr><td>user-message</td><td>let <code>P</code> be a public key of message's signature; <code>hex-encode(P)</code> is a chat ID; discard <code>chat-id</code> from message</td><td>Incoming</td><td>if there is no matched chat, it might be the first message from public key <code>P</code>; the node MAY discard the message or MAY create a new chat; Status official clients create a new chat</td></tr>
|
|
<tr><td>PRIVATE_GROUP</td><td>use <code>chatId</code> from the message</td><td>Incoming/Outgoing</td><td>find an existing chat by <code>chatId</code>; if none is found, the user is not a member of that chat or the user hasn't joined that chat, the message MUST be discarded</td></tr>
|
|
<tr><td>COMMUNITY_CHAT</td><td>use <code>chatId</code> from the message</td><td>Incoming/Outgoing</td><td>find existing community chat within a community based on <code>chatId</code>; the <code>chatId</code> includes a community id prefix</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="contactupdate"><a class="header" href="#contactupdate">ContactUpdate</a></h3>
|
|
<p><code>ContactUpdate</code> is a message exchange to notify peers
|
|
that either the user has been added as a contact, or
|
|
that information about the sending user have changed.</p>
|
|
<pre><code class="language-protobuf">message ContactUpdate {
|
|
uint64 clock = 1;
|
|
string ens_name = 2;
|
|
string profile_image = 3;
|
|
string display_name = 4;
|
|
uint64 contact_request_clock = 5;
|
|
ContactRequestPropagatedState contact_request_propagated_state = 6;
|
|
string public_key = 7;
|
|
}
|
|
|
|
message ContactRequestPropagatedState {
|
|
uint64 local_clock = 1;
|
|
uint64 local_state = 2;
|
|
uint64 remote_clock = 3;
|
|
uint64 remote_state = 4;
|
|
}
|
|
</code></pre>
|
|
<h4 id="payload-fields"><a class="header" href="#payload-fields">Payload Fields</a></h4>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>The clock of the chat with the user</td></tr>
|
|
<tr><td>2</td><td>ens_name</td><td><code>string</code></td><td>The ENS name if set</td></tr>
|
|
<tr><td>3</td><td>profile_image</td><td><code>string</code></td><td>The base64 encoded profile picture of the user</td></tr>
|
|
<tr><td>4</td><td>display_name</td><td><code>string</code></td><td>The display name of the user</td></tr>
|
|
<tr><td>5</td><td>contact_request_clock</td><td><code>uint64</code></td><td>The clock at which a contact request was sent</td></tr>
|
|
<tr><td>6</td><td>contact_request_propagated_state</td><td><code>ContactRequestPropagatedState</code></td><td>Additional propagation clock values</td></tr>
|
|
<tr><td>7</td><td>public_key</td><td><code>string</code></td><td>The public key of the user</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h4 id="contact-update"><a class="header" href="#contact-update">Contact update</a></h4>
|
|
<p>A client SHOULD send a <code>ContactUpdate</code> to all the contacts each time:</p>
|
|
<ul>
|
|
<li>The ens_name has changed</li>
|
|
<li>A user edits the profile image</li>
|
|
</ul>
|
|
<p>A client SHOULD also periodically send a <code>ContactUpdate</code> to all the contacts,
|
|
the interval is up to the client,
|
|
the Status official client sends these updates every 48 hours.</p>
|
|
<h3 id="emojireaction"><a class="header" href="#emojireaction">EmojiReaction</a></h3>
|
|
<p><code>EmojiReaction</code>s represents a user's "reaction" to a specific chat message.
|
|
For more information about the concept of emoji reactions see <a href="https://en.wikipedia.org/wiki/Facebook_like_button#Use_on_Facebook">Facebook Reactions</a>.</p>
|
|
<p>This specification RECOMMENDS that the UI/UX implementation of sending <code>EmojiReactions</code>
|
|
requires only a single click operation,
|
|
as users have an expectation that emoji reactions are effortless
|
|
and simple to perform.</p>
|
|
<pre><code class="language-protobuf">message EmojiReaction {
|
|
// clock Lamport timestamp of the chat message
|
|
uint64 clock = 1;
|
|
|
|
// chat_id the ID of the chat the message belongs to, for query efficiency the
|
|
// chat_id is stored in the db even though the
|
|
// target message also stores the chat_id
|
|
string chat_id = 2;
|
|
|
|
// message_id the ID of the target message that the user wishes to react to
|
|
string message_id = 3;
|
|
|
|
// message_type
|
|
// is (somewhat confusingly) the ID of the type of chat the message belongs to
|
|
MessageType message_type = 4;
|
|
|
|
// type the ID of the emoji the user wishes to react with
|
|
Type type = 5;
|
|
|
|
enum Type {
|
|
UNKNOWN_EMOJI_REACTION_TYPE = 0;
|
|
LOVE = 1;
|
|
THUMBS_UP = 2;
|
|
THUMBS_DOWN = 3;
|
|
LAUGH = 4;
|
|
SAD = 5;
|
|
ANGRY = 6;
|
|
}
|
|
|
|
// whether this is a retraction of a previously sent emoji
|
|
bool retracted = 6;
|
|
}
|
|
</code></pre>
|
|
<p>Clients MUST specify <code>clock</code>, <code>chat_id</code>, <code>message_id</code>, <code>type</code> and <code>message_type</code>.</p>
|
|
<p>This specification RECOMMENDS that the UI/UX implementation of retracting an <code>EmojiReaction</code>s
|
|
requires only a single click operation,
|
|
as users have an expectation that emoji reaction removals are effortless and
|
|
simple to perform.</p>
|
|
<h3 id="membershipupdatemessage-and-membershipupdateevent"><a class="header" href="#membershipupdatemessage-and-membershipupdateevent">MembershipUpdateMessage and MembershipUpdateEvent</a></h3>
|
|
<p><code>MembershipUpdateEvent</code> is a message used to propagate information
|
|
about group membership changes in a group chat.
|
|
The details are in the <a href="../56/communities.html">Group chats specs</a>.</p>
|
|
<pre><code class="language-protobuf">message MembershipUpdateMessage {
|
|
// The chat id of the private group chat
|
|
string chat_id = 1;
|
|
// A list of events for this group chat, first x bytes are the signature,
|
|
// then is a protobuf encoded MembershipUpdateEvent
|
|
repeated bytes events = 2;
|
|
|
|
// An optional chat message
|
|
oneof chat_entity {
|
|
ChatMessage message = 3;
|
|
EmojiReaction emoji_reaction = 4;
|
|
}
|
|
}
|
|
|
|
message MembershipUpdateEvent {
|
|
// Lamport timestamp of the event
|
|
uint64 clock = 1;
|
|
// List of public keys of objects of the action
|
|
repeated string members = 2;
|
|
// Name of the chat for the CHAT_CREATED/NAME_CHANGED event types
|
|
string name = 3;
|
|
// The type of the event
|
|
EventType type = 4;
|
|
// Color of the chat for the CHAT_CREATED/COLOR_CHANGED event types
|
|
string color = 5;
|
|
// Chat image
|
|
bytes image = 6;
|
|
|
|
enum EventType {
|
|
UNKNOWN = 0;
|
|
CHAT_CREATED = 1;
|
|
NAME_CHANGED = 2;
|
|
MEMBERS_ADDED = 3;
|
|
MEMBER_JOINED = 4;
|
|
MEMBER_REMOVED = 5;
|
|
ADMINS_ADDED = 6;
|
|
ADMIN_REMOVED = 7;
|
|
COLOR_CHANGED = 8;
|
|
IMAGE_CHANGED = 9;
|
|
}
|
|
}
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>chat_id</td><td><code>string</code></td><td>The chat id of the private group chat</td></tr>
|
|
<tr><td>2</td><td>events</td><td><code>bytes[]</code></td><td>The list of events for this group chat</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h4 id="chat-entities"><a class="header" href="#chat-entities">Chat entities</a></h4>
|
|
<p>A <code>MembershipUpdateMessage</code> includes either a <code>ChatMessage</code> or <code>EmojiReaction</code>.</p>
|
|
<h3 id="syncinstallationcontactv2"><a class="header" href="#syncinstallationcontactv2">SyncInstallationContactV2</a></h3>
|
|
<p>The node uses <code>SyncInstallationContact</code> messages to synchronize
|
|
in a best-effort the contacts to other devices.</p>
|
|
<pre><code class="language-protobuf">message SyncInstallationContactV2 {
|
|
uint64 last_updated_locally = 1;
|
|
string id = 2;
|
|
string profile_image = 3;
|
|
string ens_name = 4;
|
|
uint64 last_updated = 5;
|
|
repeated string system_tags = 6;
|
|
string local_nickname = 7;
|
|
bool added = 9;
|
|
bool blocked = 10;
|
|
bool muted = 11;
|
|
bool removed = 12;
|
|
bool has_added_us = 13;
|
|
int64 verification_status = 14;
|
|
int64 trust_status = 15;
|
|
int64 contact_request_local_state = 16;
|
|
int64 contact_request_local_clock = 17;
|
|
int64 contact_request_remote_state = 18;
|
|
int64 contact_request_remote_clock = 19;
|
|
string display_name = 20;
|
|
}
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>last_updated_locally</td><td><code>uint64</code></td><td>Timestamp of last local update</td></tr>
|
|
<tr><td>2</td><td>id</td><td><code>string</code></td><td>id of the contact synced</td></tr>
|
|
<tr><td>3</td><td>profile_image</td><td><code>string</code></td><td><code>base64</code> encoded profile picture of the user</td></tr>
|
|
<tr><td>4</td><td>ens_name</td><td><code>string</code></td><td>ENS name of the contact</td></tr>
|
|
<tr><td>5</td><td></td><td><code>array[string]</code></td><td>Array of <code>system_tags</code> for the user, this can currently be: <code>":contact/added", ":contact/blocked", ":contact/request-received"</code></td></tr>
|
|
<tr><td>7</td><td>local_nickname</td><td><code>string</code></td><td>Local display name of the contact</td></tr>
|
|
<tr><td>9</td><td>added</td><td><code>bool</code></td><td>Wether the contact is added</td></tr>
|
|
<tr><td>10</td><td>blocked</td><td><code>bool</code></td><td>Wether the contact is blocked</td></tr>
|
|
<tr><td>11</td><td>muted</td><td><code>bool</code></td><td>Wether the contact is muted</td></tr>
|
|
<tr><td>12</td><td>removed</td><td><code>bool</code></td><td>Wether the contact is removed</td></tr>
|
|
<tr><td>13</td><td>has_added_us</td><td><code>bool</code></td><td>Wether the contact has added us</td></tr>
|
|
<tr><td>14</td><td>verification_status</td><td><code>int64</code></td><td>The verification status of the contact</td></tr>
|
|
<tr><td>15</td><td>trust_status</td><td><code>int64</code></td><td>The trust status of the contact</td></tr>
|
|
<tr><td>16</td><td>contact_request_local_state</td><td><code>int64</code></td><td>The local contact request state</td></tr>
|
|
<tr><td>17</td><td>contact_request_local_clock</td><td><code>int64</code></td><td>The local contact request clock</td></tr>
|
|
<tr><td>18</td><td>contact_request_remote_state</td><td><code>int64</code></td><td>The remote contact request state</td></tr>
|
|
<tr><td>19</td><td>contact_request_remote_clock</td><td><code>int64</code></td><td>The remote contact request clock</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="syncinstallationpublicchat"><a class="header" href="#syncinstallationpublicchat">SyncInstallationPublicChat</a></h3>
|
|
<p>The node uses <code>SyncInstallationPublicChat</code> message to synchronize
|
|
in a best-effort the public chats to other devices.</p>
|
|
<pre><code class="language-protobuf">message SyncInstallationPublicChat {
|
|
uint64 clock = 1;
|
|
string id = 2;
|
|
}
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>clock value of the chat</td></tr>
|
|
<tr><td>2</td><td>id</td><td><code>string</code></td><td>id of the chat synced</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="syncpairinstallation"><a class="header" href="#syncpairinstallation">SyncPairInstallation</a></h3>
|
|
<p>The node uses <code>PairInstallation</code> messages to propagate information
|
|
about a device to its paired devices.</p>
|
|
<pre><code class="language-protobuf">message SyncPairInstallation {
|
|
uint64 clock = 1;
|
|
string installation_id = 2;
|
|
string device_type = 3;
|
|
string name = 4;
|
|
// following fields used for local pairing
|
|
uint32 version = 5;
|
|
}
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>clock value of the chat</td></tr>
|
|
<tr><td>2</td><td>installation_id</td><td><code>string</code></td><td>A randomly generated id that identifies this device</td></tr>
|
|
<tr><td>3</td><td>device_type</td><td><code>string</code></td><td>The OS of the device <code>ios</code>,<code>android</code> or <code>desktop</code></td></tr>
|
|
<tr><td>4</td><td>name</td><td><code>string</code></td><td>The self-assigned name of the device</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="chatidentity"><a class="header" href="#chatidentity">ChatIdentity</a></h3>
|
|
<p><code>ChatIdentity</code> represents the user defined identity associated
|
|
with their public chat key.</p>
|
|
<pre><code class="language-protobuf">message ChatIdentity {
|
|
uint64 clock = 1;
|
|
string ens_name = 2;
|
|
map<string, IdentityImage> images = 3;
|
|
string display_name = 4;
|
|
string description = 5;
|
|
string color = 6;
|
|
string emoji = 7;
|
|
repeated SocialLink social_links = 8;
|
|
// first known message timestamp in seconds
|
|
// (valid only for community chats for now)
|
|
// 0 - unknown
|
|
// 1 - no messages
|
|
uint32 first_message_timestamp = 9;
|
|
}
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>Clock value of the message</td></tr>
|
|
<tr><td>2</td><td>ens_name</td><td><code>string</code></td><td>A valid ENS associated with the chat key</td></tr>
|
|
<tr><td>3</td><td>images</td><td><code>map<string, IdentityImage></code></td><td>Image data associated with the chat key</td></tr>
|
|
<tr><td>4</td><td>display_name</td><td><code>string</code></td><td>The self-assigned display_name of the chat key</td></tr>
|
|
<tr><td>5</td><td>description</td><td><code>string</code></td><td>The description of the chat</td></tr>
|
|
<tr><td>6</td><td>color</td><td><code>string</code></td><td>The color of the chat</td></tr>
|
|
<tr><td>7</td><td>emoji</td><td><code>string</code></td><td>The emoji of the chat</td></tr>
|
|
<tr><td>8</td><td>social_links</td><td><code>array<SocialLink></code></td><td>A list of links to social platforms</td></tr>
|
|
<tr><td>9</td><td>first_message_timestamp</td><td><code>uint32</code></td><td>First known message timestamp in seconds</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="communitydescription"><a class="header" href="#communitydescription">CommunityDescription</a></h3>
|
|
<p><code>CommunityDescription</code> represents a community metadata
|
|
that is used to discover communities and share community updates.</p>
|
|
<pre><code class="language-protobuf">message CommunityDescription {
|
|
uint64 clock = 1;
|
|
map<string,CommunityMember> members = 2;
|
|
CommunityPermissions permissions = 3;
|
|
ChatIdentity identity = 5;
|
|
map<string,CommunityChat> chats = 6;
|
|
repeated string ban_list = 7;
|
|
map<string,CommunityCategory> categories = 8;
|
|
uint64 archive_magnetlink_clock = 9;
|
|
CommunityAdminSettings admin_settings = 10;
|
|
string intro_message = 11;
|
|
string outro_message = 12;
|
|
bool encrypted = 13;
|
|
repeated string tags = 14;
|
|
map<string, CommunityTokenPermission> token_permissions = 15;
|
|
repeated CommunityTokenMetadata community_tokens_metadata = 16;
|
|
uint64 active_members_count = 17;
|
|
}
|
|
|
|
message CommunityMember {
|
|
enum Roles {
|
|
reserved 2, 3;
|
|
reserved "ROLE_MANAGE_USERS", "ROLE_MODERATE_CONTENT";
|
|
ROLE_NONE = 0;
|
|
ROLE_OWNER = 1;
|
|
ROLE_ADMIN = 4;
|
|
ROLE_TOKEN_MASTER = 5;
|
|
}
|
|
repeated Roles roles = 1;
|
|
repeated RevealedAccount revealed_accounts = 2 [deprecated = true];
|
|
uint64 last_update_clock = 3;
|
|
}
|
|
|
|
message CommunityPermissions {
|
|
enum Access {
|
|
UNKNOWN_ACCESS = 0;
|
|
NO_MEMBERSHIP = 1;
|
|
INVITATION_ONLY = 2;
|
|
ON_REQUEST = 3;
|
|
}
|
|
|
|
bool ens_only = 1;
|
|
// https://gitlab.matrix.org/matrix-org/olm/blob/master/docs/megolm.md is a
|
|
// candidate for the algorithm to be used in case we want to have private
|
|
// communityal chats, lighter than pairwise encryption using the DR, less secure,
|
|
// but more efficient for large number of participants
|
|
bool private = 2;
|
|
Access access = 3;
|
|
}
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>Clock value of the message</td></tr>
|
|
<tr><td>2</td><td>members</td><td><code>map<string, CommunityMember></code></td><td>The members of the community</td></tr>
|
|
<tr><td>3</td><td>permissions</td><td><code>CommunityPermissions</code></td><td>Image data associated with the chat key</td></tr>
|
|
<tr><td>4</td><td>display_name</td><td><code>string</code></td><td>The self-assigned display_name of the chat key</td></tr>
|
|
<tr><td>5</td><td>description</td><td><code>string</code></td><td>The description of the chat</td></tr>
|
|
<tr><td>6</td><td>color</td><td><code>string</code></td><td>The color of the chat</td></tr>
|
|
<tr><td>7</td><td>emoji</td><td><code>string</code></td><td>The emoji of the chat</td></tr>
|
|
<tr><td>8</td><td>social_links</td><td><code>array<SocialLink></code></td><td>A list of links to social platforms</td></tr>
|
|
<tr><td>9</td><td>first_message_timestamp</td><td><code>uint32</code></td><td>First known message timestamp in seconds</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="communityrequesttojoin"><a class="header" href="#communityrequesttojoin">CommunityRequestToJoin</a></h3>
|
|
<p>A <code>CommunityRequestToJoin</code> represents a request to join a community,
|
|
sent by a user that is not yet a member of that community.
|
|
A request to join a community includes a list of <code>RevealedAccount</code>.
|
|
These are wallet addresses that users are willing to reveal
|
|
with the community's control node and admins.</p>
|
|
<pre><code class="language-protobuf">message CommunityRequestToJoin {
|
|
uint64 clock = 1;
|
|
string ens_name = 2;
|
|
string chat_id = 3;
|
|
bytes community_id = 4;
|
|
string display_name = 5;
|
|
repeated RevealedAccount revealed_accounts = 6;
|
|
}
|
|
|
|
message RevealedAccount {
|
|
string address = 1;
|
|
bytes signature = 2;
|
|
repeated uint64 chain_ids = 3;
|
|
bool isAirdropAddress = 4;
|
|
}
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>Clock value of the message</td></tr>
|
|
<tr><td>2</td><td>ens_name</td><td><code>string</code></td><td>The ENS of the user sending the request</td></tr>
|
|
<tr><td>3</td><td>chat_id</td><td><code>string</code></td><td>The id of the chat to request access to</td></tr>
|
|
<tr><td>4</td><td>community_id</td><td><code>bytes</code></td><td>The public key of the community</td></tr>
|
|
<tr><td>5</td><td>display_name</td><td><code>string</code></td><td>The display name of the usre sending the request</td></tr>
|
|
<tr><td>6</td><td>revealed_accounts</td><td><code>array<RevealedAccount></code></td><td>A list of accounts to reveal to the control node</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="pinmessage"><a class="header" href="#pinmessage">PinMessage</a></h3>
|
|
<p>A <code>PinMessage</code> is a signal that tells a client that a specific message
|
|
has to be marked as pinned.</p>
|
|
<pre><code class="language-protobuf">message PinMessage {
|
|
uint64 clock = 1;
|
|
string message_id = 2;
|
|
string chat_id = 3;
|
|
bool pinned = 4;
|
|
MessageType message_type = 5;
|
|
}
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>Clock value of the message</td></tr>
|
|
<tr><td>2</td><td>message_id</td><td><code>string</code></td><td>The id of the message to be pinned</td></tr>
|
|
<tr><td>3</td><td>chat_id</td><td><code>string</code></td><td>The id of the chat of the message to be pinned</td></tr>
|
|
<tr><td>4</td><td>pinned</td><td><code>bool</code></td><td>Whether the message should be pinned or unpinned</td></tr>
|
|
<tr><td>5</td><td>message_type</td><td><code>MessageType</code></td><td>The type of message (public/one-to-one/private-group-chat)</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="editmessage"><a class="header" href="#editmessage">EditMessage</a></h3>
|
|
<p>A <code>EditMessage</code> represents an update to an existing message.</p>
|
|
<pre><code class="language-protobuf">message EditMessage {
|
|
uint64 clock = 1;
|
|
string text = 2;
|
|
|
|
string chat_id = 3;
|
|
string message_id = 4;
|
|
|
|
bytes grant = 5;
|
|
|
|
MessageType message_type = 6;
|
|
|
|
ChatMessage.ContentType content_type = 7;
|
|
repeated UnfurledLink unfurled_links = 8;
|
|
}
|
|
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>Clock value of the message</td></tr>
|
|
<tr><td>2</td><td>text</td><td><code>string</code></td><td>The updated message text</td></tr>
|
|
<tr><td>3</td><td>chat_id</td><td><code>string</code></td><td>The id of the chat of the message</td></tr>
|
|
<tr><td>4</td><td>message_id</td><td><code>string</code></td><td>The id of the message to be edited</td></tr>
|
|
<tr><td>5</td><td>grant</td><td><code>bytes</code></td><td>A grant for a community edit messages</td></tr>
|
|
<tr><td>6</td><td>message_type</td><td><code>MessageType</code></td><td>The type of message</td></tr>
|
|
<tr><td>7</td><td>content_type</td><td><code>ChatMessage.ContentType</code></td><td>The updated content type of the message</td></tr>
|
|
<tr><td>8</td><td>unfurled_links</td><td><code>array<UnfurledLink></code></td><td>Updated link metadata</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="deletemessage"><a class="header" href="#deletemessage">DeleteMessage</a></h3>
|
|
<p>A <code>DeleteMessage</code> represents a signal to delete a message
|
|
from the local database of a client.</p>
|
|
<pre><code class="language-protobuf">message DeleteMessage {
|
|
uint64 clock = 1;
|
|
|
|
string chat_id = 2;
|
|
string message_id = 3;
|
|
|
|
// Grant for community delete messages
|
|
bytes grant = 4;
|
|
|
|
// The type of message (public/one-to-one/private-group-chat)
|
|
MessageType message_type = 5;
|
|
|
|
string deleted_by = 6;
|
|
}
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>Clock value of the message</td></tr>
|
|
<tr><td>2</td><td>chat_id</td><td><code>string</code></td><td>The id of the chat of the message</td></tr>
|
|
<tr><td>3</td><td>message_id</td><td><code>string</code></td><td>The id of the message to delete</td></tr>
|
|
<tr><td>4</td><td>grant</td><td><code>bytes</code></td><td>A grant for a community edit messages</td></tr>
|
|
<tr><td>5</td><td>message_type</td><td><code>MessageType</code></td><td>The type of message</td></tr>
|
|
<tr><td>6</td><td>deleted_by</td><td><code>string</code></td><td>The public key of the user who deleted the message</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="communitymessagearchivelink"><a class="header" href="#communitymessagearchivelink">CommunityMessageArchiveLink</a></h3>
|
|
<p>A <code>CommunityMessageArchiveLink</code> contains a magnet uri for a community's message archive,
|
|
created using <a href="../61/community-history-service.html">61/STATUS-Community-History-Archives</a>.</p>
|
|
<pre><code class="language-protobuf">message CommunityMessageArchiveMagnetlink {
|
|
uint64 clock = 1;
|
|
string magnet_uri = 2;
|
|
}
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>Clock value of the message</td></tr>
|
|
<tr><td>2</td><td>magnet_uri</td><td><code>string</code></td><td>The magnet uri of the community archive torrent</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="acceptcontactrequest"><a class="header" href="#acceptcontactrequest">AcceptContactRequest</a></h3>
|
|
<p>A <code>AcceptContractRequest</code> message signals to the requester that the request was accepted.</p>
|
|
<pre><code class="language-protobuf">message AcceptContactRequest {
|
|
string id = 1;
|
|
uint64 clock = 2;
|
|
}
|
|
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>id</td><td><code>string</code></td><td>The id of the contact request</td></tr>
|
|
<tr><td>2</td><td>clock</td><td><code>uint64</code></td><td>Clock value of the message</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="retractcontactrequest"><a class="header" href="#retractcontactrequest">RetractContactRequest</a></h3>
|
|
<p>A <code>RetractContractRequest</code> message signals to the reiver, of a request,
|
|
that the request was retracted.</p>
|
|
<pre><code class="language-protobuf">message RetractContactRequest {
|
|
string id = 1;
|
|
uint64 clock = 2;
|
|
}
|
|
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>id</td><td><code>string</code></td><td>The id of the contact request</td></tr>
|
|
<tr><td>2</td><td>clock</td><td><code>uint64</code></td><td>Clock value of the message</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="communityrequesttojoinresponse"><a class="header" href="#communityrequesttojoinresponse">CommunityRequestToJoinResponse</a></h3>
|
|
<p>A <code>CommunityRequestToJoinResponse</code> represents a response to a request to join a community.</p>
|
|
<pre><code class="language-protobuf">message CommunityRequestToJoinResponse {
|
|
uint64 clock = 1;
|
|
CommunityDescription community = 2;
|
|
bool accepted = 3;
|
|
bytes grant = 4;
|
|
bytes community_id = 5;
|
|
string magnet_uri = 6;
|
|
}
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>Clock value of the message</td></tr>
|
|
<tr><td>2</td><td>community</td><td><code>CommunityDescription</code></td><td>The community metadata</td></tr>
|
|
<tr><td>3</td><td>accepted</td><td><code>bool</code></td><td>Whether the request was accepted</td></tr>
|
|
<tr><td>4</td><td>grant</td><td><code>bytes</code></td><td>The grant</td></tr>
|
|
<tr><td>5</td><td>community_id</td><td><code>bytes</code></td><td>The id of the community</td></tr>
|
|
<tr><td>6</td><td>magnet_uri</td><td><code>string</code></td><td>The latest magnet uri of the community's archive torrent</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="communityrequesttoleave"><a class="header" href="#communityrequesttoleave">CommunityRequestToLeave</a></h3>
|
|
<p>A <code>CommunityRequestToLeave</code> represents a signal to a community
|
|
that a user wants to be removed from the community's member list.</p>
|
|
<pre><code class="language-protobuf">message CommunityRequestToLeave {
|
|
uint64 clock = 1;
|
|
bytes community_id = 2;
|
|
}
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>Clock value of the message</td></tr>
|
|
<tr><td>2</td><td>community_id</td><td><code>bytes</code></td><td>The id of the community</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="requestcontactverification"><a class="header" href="#requestcontactverification">RequestContactVerification</a></h3>
|
|
<p>A <code>RequestContactVerification</code> is a request to verify a contact using a "challenge",
|
|
which can by any string message and
|
|
typically involves questions that only the contact should know.</p>
|
|
<pre><code class="language-protobuf">message RequestContactVerification {
|
|
uint64 clock = 1;
|
|
string challenge = 3;
|
|
}
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>Clock value of the message</td></tr>
|
|
<tr><td>2</td><td>challenge</td><td><code>string</code></td><td>The challenge message used for verification</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="acceptcontactverification"><a class="header" href="#acceptcontactverification">AcceptContactVerification</a></h3>
|
|
<p>A <code>AcceptContactVerification</code> signals that a verification request was accepted and
|
|
includes a response to the challenge.</p>
|
|
<pre><code class="language-protobuf">message AcceptContactVerification {
|
|
uint64 clock = 1;
|
|
string id = 2;
|
|
string response = 3;
|
|
}
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>Clock value of the message</td></tr>
|
|
<tr><td>2</td><td>id</td><td><code>string</code></td><td>The verification request id</td></tr>
|
|
<tr><td>3</td><td>response</td><td><code>string</code></td><td>The response for the challenge</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="declinecontactverification"><a class="header" href="#declinecontactverification">DeclineContactVerification</a></h3>
|
|
<p>A <code>DeclineContactVerification</code> declines a contact verification request.</p>
|
|
<pre><code class="language-protobuf">message DeclineContactVerification {
|
|
uint64 clock = 1;
|
|
string id = 2;
|
|
}
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>Clock value of the message</td></tr>
|
|
<tr><td>2</td><td>id</td><td><code>string</code></td><td>The verification request id</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="cancelcontactverification"><a class="header" href="#cancelcontactverification">CancelContactVerification</a></h3>
|
|
<p>A <code>CancelContactVerification</code> cancels a contact verification request.</p>
|
|
<pre><code class="language-protobuf">message CancelContactVerification {
|
|
uint64 clock = 1;
|
|
string id = 2;
|
|
}
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>Clock value of the message</td></tr>
|
|
<tr><td>2</td><td>id</td><td><code>string</code></td><td>The verification request id</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="communitycancelrequesttojoin"><a class="header" href="#communitycancelrequesttojoin">CommunityCancelRequestToJoin</a></h3>
|
|
<p>A <code>CommunityCancelRequestToJoin</code> cancels a pending request to join.</p>
|
|
<pre><code class="language-protobuf">message CommunityCancelRequestToJoin {
|
|
uint64 clock = 1;
|
|
string ens_name = 2;
|
|
string chat_id = 3;
|
|
bytes community_id = 4;
|
|
string display_name = 5;
|
|
}
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>Clock value of the message</td></tr>
|
|
<tr><td>2</td><td>ens_name</td><td><code>string</code></td><td>The ENS name of the account cancelling the request</td></tr>
|
|
<tr><td>3</td><td>chat_id</td><td><code>string</code></td><td>The id of the chat</td></tr>
|
|
<tr><td>4</td><td>community_id</td><td><code>bytes</code></td><td>The id of the community</td></tr>
|
|
<tr><td>5</td><td>display_name</td><td><code>string</code></td><td>The display name of the account cancelling the request</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="communityeditsharedaddresses"><a class="header" href="#communityeditsharedaddresses">CommunityEditSharedAddresses</a></h3>
|
|
<p>A <code>CommunityEditSharedAddresses</code> message allows users to edit the shared accounts
|
|
they've revealed when requesting to join a community.</p>
|
|
<pre><code class="language-protobuf">message CommunityEditSharedAddresses {
|
|
uint64 clock = 1;
|
|
bytes community_id = 2;
|
|
repeated RevealedAccount revealed_accounts = 3;
|
|
}
|
|
</code></pre>
|
|
<p>Payload</p>
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|
<tr><td>1</td><td>clock</td><td><code>uint64</code></td><td>Clock value of the message</td></tr>
|
|
<tr><td>2</td><td>community_id</td><td><code>bytes</code></td><td>The id of the community</td></tr>
|
|
<tr><td>3</td><td>revealed_accounts</td><td><code>array<RevealedAccount></code></td><td>A list of revealed accounts</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h2 id="upgradability"><a class="header" href="#upgradability">Upgradability</a></h2>
|
|
<p>There are two ways to upgrade the protocol without breaking compatibility:</p>
|
|
<ul>
|
|
<li>A node always supports accretion</li>
|
|
<li>A node does not support deletion of existing fields or messages,
|
|
which might break compatibility</li>
|
|
</ul>
|
|
<h2 id="security-considerations"><a class="header" href="#security-considerations">Security Considerations</a></h2>
|
|
<h2 id="changelog"><a class="header" href="#changelog">Changelog</a></h2>
|
|
<h3 id="version-05"><a class="header" href="#version-05">Version 0.5</a></h3>
|
|
<p>Released <a href="https://github.com/status-im/specs/commit/968fafff23cdfc67589b34dd64015de29aaf41f0">August 25, 2020</a></p>
|
|
<ul>
|
|
<li>Added support for emoji reactions</li>
|
|
</ul>
|
|
<h3 id="version-04"><a class="header" href="#version-04">Version 0.4</a></h3>
|
|
<p>Released <a href="https://github.com/status-im/specs/commit/ad45cd5fed3c0f79dfa472253a404f670dd47396">July 16, 2020</a></p>
|
|
<ul>
|
|
<li>Added support for images</li>
|
|
<li>Added support for audio</li>
|
|
</ul>
|
|
<h3 id="version-03"><a class="header" href="#version-03">Version 0.3</a></h3>
|
|
<p>Released <a href="https://github.com/status-im/specs/commit/664dd1c9df6ad409e4c007fefc8c8945b8d324e8">May 22, 2020</a></p>
|
|
<ul>
|
|
<li>Added language to include Waku in all relevant places</li>
|
|
</ul>
|
|
<h2 id="copyright"><a class="header" href="#copyright">Copyright</a></h2>
|
|
<p>Copyright and related rights waived via <a href="https://creativecommons.org/publicdomain/zero/1.0/">CC0</a>.</p>
|
|
|
|
</main>
|
|
|
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
|
<!-- Mobile navigation buttons -->
|
|
<a rel="prev" href="../../status/61/community-history-service.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 prefetch" href="../../status/63/keycard-usage.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="../../status/61/community-history-service.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 prefetch" href="../../status/63/keycard-usage.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>
|
|
window.playground_copyable = true;
|
|
</script>
|
|
|
|
|
|
<script src="../../elasticlunr.min.js"></script>
|
|
<script src="../../mark.min.js"></script>
|
|
<script src="../../searcher.js"></script>
|
|
|
|
<script src="../../clipboard.min.js"></script>
|
|
<script src="../../highlight.js"></script>
|
|
<script src="../../book.js"></script>
|
|
|
|
<!-- Custom JS scripts -->
|
|
<script src="../../scripts/rfc-index.js"></script>
|
|
|
|
|
|
</div>
|
|
</body>
|
|
</html>
|