mirror of
https://github.com/vacp2p/rfc-index.git
synced 2026-01-09 23:58:02 -05:00
Compare commits
15 Commits
wallet-tec
...
9-ethereum
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6108ca6f4b | ||
|
|
20a9d653c7 | ||
|
|
58e0b67013 | ||
|
|
87568c6107 | ||
|
|
d5b99bce11 | ||
|
|
371fb4fb0e | ||
|
|
d469d90702 | ||
|
|
a2ec64c91d | ||
|
|
e5590e56c2 | ||
|
|
45a35c3a02 | ||
|
|
814a40d72a | ||
|
|
cf00dffc8f | ||
|
|
41fb2db7ca | ||
|
|
a4c23879d2 | ||
|
|
8cfb5e5b19 |
120
status/deprecated/3rd-party.md
Normal file
120
status/deprecated/3rd-party.md
Normal file
@@ -0,0 +1,120 @@
|
||||
---
|
||||
title: 3RD-PARTY
|
||||
name: 3rd party
|
||||
status: deprecated
|
||||
description: This specification discusses 3rd party APIs that Status relies on.
|
||||
editor: Filip Dimitrijevic <filip@status.im>
|
||||
contributors:
|
||||
- Volodymyr Kozieiev <volodymyr@status.im>
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
This specification discusses 3rd party APIs that Status relies on.
|
||||
These APIs provide various capabilities, including:
|
||||
|
||||
- communicating with the Ethereum network,
|
||||
- allowing users to view address and transaction details on external websites,
|
||||
- retrieving fiat/crypto exchange rates,
|
||||
- obtaining information about collectibles,
|
||||
- hosting the privacy policy.
|
||||
|
||||
## Definitions
|
||||
|
||||
| Term | Description |
|
||||
|-------------------|-------------------------------------------------------------------------------------------------------|
|
||||
| Fiat money | Currency established as money, often by government regulation, but without intrinsic value. |
|
||||
| Full node | A computer, connected to the Ethereum network, that enforces all Ethereum consensus rules. |
|
||||
| Crypto-collectible| A unique, non-fungible digital asset, distinct from cryptocurrencies where tokens are identical. |
|
||||
|
||||
## Why 3rd Party APIs Can Be a Problem
|
||||
|
||||
Relying on 3rd party APIs conflicts with Status’s censorship-resistance principle.
|
||||
Since Status aims to avoid suppression of information,
|
||||
it is important to minimize reliance on 3rd parties that are critical to app functionality.
|
||||
|
||||
## 3rd Party APIs Used by the Current Status App
|
||||
|
||||
### Infura
|
||||
|
||||
**What is it?**
|
||||
Infura hosts a collection of Ethereum full nodes and provides an API
|
||||
to access the Ethereum and IPFS networks without requiring a full node.
|
||||
|
||||
**How Status Uses It**
|
||||
Since Status operates on mobile devices,
|
||||
it cannot rely on a local node.
|
||||
Therefore, all Ethereum network communication happens via Infura.
|
||||
|
||||
**Concerns**
|
||||
Making an HTTP request can reveal user metadata,
|
||||
which could be exploited in attacks if Infura is compromised.
|
||||
Infura uses centralized hosting providers;
|
||||
if these providers fail or cut off service,
|
||||
Ethereum-dependent features in Status would be affected.
|
||||
|
||||
### Etherscan
|
||||
|
||||
**What is it?**
|
||||
Etherscan is a service that allows users to explore the Ethereum blockchain
|
||||
for transactions, addresses, tokens, prices,
|
||||
and other blockchain activities.
|
||||
|
||||
**How Status Uses It**
|
||||
The Status Wallet allows users to view address and transaction details on Etherscan.
|
||||
|
||||
**Concerns**
|
||||
If Etherscan becomes unavailable,
|
||||
users won’t be able to view address or transaction details through Etherscan.
|
||||
However, in-app information will still be accessible.
|
||||
|
||||
### CryptoCompare
|
||||
|
||||
**What is it?**
|
||||
CryptoCompare provides live crypto prices, charts, and analysis from major exchanges.
|
||||
|
||||
**How Status Uses It**
|
||||
Status regularly fetches crypto prices from CryptoCompare,
|
||||
using this information to calculate fiat values
|
||||
for transactions or wallet assets.
|
||||
|
||||
**Concerns**
|
||||
HTTP requests can reveal metadata,
|
||||
which could be exploited if CryptoCompare is compromised.
|
||||
If CryptoCompare becomes unavailable,
|
||||
Status won’t be able to show fiat equivalents for crypto in the wallet.
|
||||
|
||||
### Collectibles
|
||||
|
||||
Various services provide information on collectibles:
|
||||
|
||||
- [Service 1](https://api.pixura.io/graphql)
|
||||
- [Service 2](https://www.etheremon.com/api)
|
||||
- [Service 3](https://us-central1-cryptostrikers-prod.cloudfunctions.net/cards/)
|
||||
- [Service 4](https://api.cryptokitties.co/)
|
||||
|
||||
**Concerns**
|
||||
HTTP requests can reveal metadata,
|
||||
which could be exploited if these services are compromised.
|
||||
|
||||
### Iubenda
|
||||
|
||||
**What is it?**
|
||||
Iubenda helps create compliance documents for websites and apps across jurisdictions.
|
||||
|
||||
**How Status Uses It**
|
||||
Status’s privacy policy is hosted on Iubenda.
|
||||
|
||||
**Concerns**
|
||||
If Iubenda becomes unavailable,
|
||||
users will be unable to view the app's privacy policy.
|
||||
|
||||
## Changelog
|
||||
|
||||
| Version | Comment |
|
||||
|---------|-----------------|
|
||||
| 0.1.0 | Initial release |
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
||||
262
status/deprecated/EIPS.md
Normal file
262
status/deprecated/EIPS.md
Normal file
@@ -0,0 +1,262 @@
|
||||
---
|
||||
title: EIPS
|
||||
name: EIPS
|
||||
status: deprecated
|
||||
description: Status relation with the EIPs
|
||||
editor: Ricardo Guilherme Schmidt <ricardo3@status.im>
|
||||
contributors:
|
||||
-
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
This specification describes how Status relates with EIPs.
|
||||
|
||||
## Introduction
|
||||
|
||||
Status should follow standards as much as possible.
|
||||
Whenever the Status app needs a feature,
|
||||
it should first check if a standard exists.
|
||||
If not, Status should propose a new standard.
|
||||
|
||||
## Support Table
|
||||
|
||||
| | Status v0 | Status v1 | Other | State |
|
||||
| ---------- | --------- | --------- | ----- | ------ |
|
||||
| BIP32 | N | Y | N | stable |
|
||||
| BIP39 | Y | Y | Y | stable |
|
||||
| BIP43 | N | Y | N | stable |
|
||||
| BIP44 | N | Y | N | stable |
|
||||
| EIP20 | Y | Y | Y | stable |
|
||||
| EIP55 | Y | Y | Y | stable |
|
||||
| EIP67 | P | P | N | stable |
|
||||
| EIP137 | P | P | N | stable |
|
||||
| EIP155 | Y | Y | Y | stable |
|
||||
| EIP165 | P | N | N | stable |
|
||||
| EIP181 | P | N | N | stable |
|
||||
| EIP191 | Y? | N | Y | stable |
|
||||
| EIP627 | Y | Y | N | stable |
|
||||
| EIP681 | Y | N | Y | stable |
|
||||
| EIP712 | P | P | Y | stable |
|
||||
| EIP721 | P | P | Y | stable |
|
||||
| EIP831 | N | Y | N | stable |
|
||||
| EIP945 | Y | Y | N | stable |
|
||||
| EIP1102 | Y | Y | Y | stable |
|
||||
| EIP1193 | Y | Y | Y | stable |
|
||||
| EIP1577 | Y | P | N | stable |
|
||||
| EIP1581 | N | Y | N | stable |
|
||||
| EIP1459 | N | - | N | raw |
|
||||
|
||||
## Components
|
||||
|
||||
### BIP32 - Hierarchical Deterministic Wallets
|
||||
|
||||
- **Support**: Dependency.
|
||||
- **Reference**:
|
||||
[BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
|
||||
- **Description**: Enable wallets to derive multiple private keys from the same
|
||||
seed.
|
||||
- **Used for**: Dependency of BIP39 and BIP43.
|
||||
|
||||
### BIP39 - Mnemonic Code for Generating Deterministic Keys
|
||||
|
||||
- **Support**: Dependency.
|
||||
- **Reference**:
|
||||
[BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)
|
||||
- **Description**: Enable wallet to create private key based on a safe seed
|
||||
phrase.
|
||||
- **Used for**: Security and user experience.
|
||||
|
||||
### BIP43 - Purpose Field for Deterministic Wallets
|
||||
|
||||
- **Support**: Dependency.
|
||||
- **Reference**:
|
||||
[BIP43](https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki)
|
||||
- **Description**: Enable wallet to create private keys branched for a specific
|
||||
purpose.
|
||||
- **Used for**: Dependency of BIP44, uses “ethereum” coin.
|
||||
|
||||
### BIP44 - Multi-Account Hierarchy for Deterministic Wallets
|
||||
|
||||
- **Support**: Dependency.
|
||||
- **Reference**:
|
||||
[BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki)
|
||||
- **Description**: Enable wallet to derive multiple accounts on top of BIP39.
|
||||
- **Used for**: Privacy.
|
||||
- **Source code**:
|
||||
[BIP44](https://github.com/status-im/status-mobile/blob/develop/src/status_im/constants.cljs#L240)
|
||||
|
||||
_Observation_: BIP44 doesn’t solve privacy issues regarding transaction
|
||||
transparency. Connected addresses through transactions can be identified via
|
||||
“network reconnaissance attacks” on transaction history, which may expose user
|
||||
privacy despite BIP44.
|
||||
|
||||
### EIP20 - Fungible Token
|
||||
|
||||
- **Support**: Full.
|
||||
- **Reference**: [EIP20](https://eips.ethereum.org/EIPS/eip-20)
|
||||
- **Description**: Enable wallets to use tokens based on smart contracts
|
||||
compliant with this standard.
|
||||
- **Used for**: Wallet feature.
|
||||
- **Source code**:
|
||||
[EIP20](https://github.com/status-im/status-mobile/blob/develop/src/status_im/ethereum/tokens.cljs)
|
||||
|
||||
### EIP55 - Mixed-case Checksum Address Encoding
|
||||
|
||||
- **Support**: Full.
|
||||
- **Reference**: [EIP55](https://eips.ethereum.org/EIPS/eip-55)
|
||||
- **Description**: Checksum standard that uses lowercase and uppercase inside
|
||||
address hex value.
|
||||
- **Used for**: Sanity check of forms using Ethereum addresses.
|
||||
- **Source code**:
|
||||
[EIP55](https://github.com/status-im/status-mobile/blob/develop/src/status_im/ethereum/eip55.cljs)
|
||||
|
||||
### EIP67 - Standard URI Scheme with Metadata, Value, and Byte Code
|
||||
|
||||
- **Support**: Partial.
|
||||
- **Reference**: [EIP67](https://github.com/ethereum/EIPs/issues/67)
|
||||
- **Description**: A standard way of creating Ethereum URIs for various use-
|
||||
cases.
|
||||
- **Used for**: Legacy support.
|
||||
|
||||
### EIP137 - Ethereum Domain Name Service
|
||||
|
||||
- **Support**: Partial.
|
||||
- **Reference**: [EIP137](https://eips.ethereum.org/EIPS/eip-137)
|
||||
- **Description**: Enable wallets to lookup ENS names.
|
||||
- **Used for**: User experience, as a wallet and identity feature.
|
||||
- **Source code**:
|
||||
[EIP137](https://github.com/status-im/status-mobile/blob/develop/src/status_im/ethereum/ens.cljs#L86)
|
||||
|
||||
### EIP155 - Simple Replay Attack Protection
|
||||
|
||||
- **Support**: Full.
|
||||
- **Reference**: [EIP155](https://eips.ethereum.org/EIPS/eip-155)
|
||||
- **Description**: Defined chainId parameter in the signed Ethereum transaction
|
||||
payload.
|
||||
- **Used for**: Signing transactions, crucial for user safety against replay
|
||||
attacks.
|
||||
- **Source code**:
|
||||
[EIP155](https://github.com/status-im/status-mobile/blob/develop/src/status_im/ethereum/core.cljs)
|
||||
|
||||
### EIP165 - Standard Interface Detection
|
||||
|
||||
- **Support**: Dependency/Partial.
|
||||
- **Reference**: [EIP165](https://eips.ethereum.org/EIPS/eip-165)
|
||||
- **Description**: Standard interface for contracts to answer if they support
|
||||
other interfaces.
|
||||
- **Used for**: Dependency of ENS and EIP721.
|
||||
- **Source code**:
|
||||
[EIP165](https://github.com/status-im/status-mobile/blob/develop/src/status_im/ethereum/eip165.cljs)
|
||||
|
||||
### EIP181 - ENS Support for Reverse Resolution of Ethereum Addresses
|
||||
|
||||
- **Support**: Partial.
|
||||
- **Reference**: [EIP181](https://eips.ethereum.org/EIPS/eip-181)
|
||||
- **Description**: Enable wallets to render reverse resolution of Ethereum
|
||||
addresses.
|
||||
- **Used for**: Wallet feature.
|
||||
- **Source code**:
|
||||
[EIP181](https://github.com/status-im/status-mobile/blob/develop/src/status_im/ethereum/ens.cljs#L86)
|
||||
|
||||
### EIP191 - Signed Message
|
||||
|
||||
- **Support**: Full.
|
||||
- **Reference**: [EIP191](https://eips.ethereum.org/EIPS/eip-191)
|
||||
- **Description**: Contract signature standard, adds padding to signed messages
|
||||
to differentiate from Ethereum transaction messages.
|
||||
- **Used for**: DApp support, security, dependency of EIP712.
|
||||
|
||||
### EIP627 - Whisper Specification
|
||||
|
||||
- **Support**: Full.
|
||||
- **Reference**: [EIP627](https://eips.ethereum.org/EIPS/eip-627)
|
||||
- **Description**: Format of Whisper messages within the ÐΞVp2p Wire Protocol.
|
||||
- **Used for**: Chat protocol.
|
||||
|
||||
### EIP681 - URL Format for Transaction Requests
|
||||
|
||||
- **Support**: Partial.
|
||||
- **Reference**: [EIP681](https://eips.ethereum.org/EIPS/eip-681)
|
||||
- **Description**: A link that pops up a transaction in the wallet.
|
||||
- **Used for**: QR code data for transaction requests, chat transaction requests,
|
||||
and DApp links to transaction requests.
|
||||
- **Source code**:
|
||||
[EIP681](https://github.com/status-im/status-mobile/blob/develop/src/status_im/ethereum/eip681.cljs)
|
||||
|
||||
### EIP712 - Typed Signed Message
|
||||
|
||||
- **Support**: Partial.
|
||||
- **Reference**: [EIP712](https://eips.ethereum.org/EIPS/eip-712)
|
||||
- **Description**: Standardize types for contract signatures, allowing users to
|
||||
inspect what’s being signed.
|
||||
- **Used for**: User experience, security.
|
||||
|
||||
### EIP721 - Non-Fungible Token
|
||||
|
||||
- **Support**: Partial.
|
||||
- **Reference**: [EIP721](https://eips.ethereum.org/EIPS/eip-721)
|
||||
- **Description**: Enable wallets to use tokens based on smart contracts
|
||||
compliant with this standard.
|
||||
- **Used for**: Wallet feature.
|
||||
|
||||
### EIP945 - Web3 QR Code Scanning API
|
||||
|
||||
- **Support**: Full.
|
||||
- **Reference**: [EIP945](https://github.com/ethereum/EIPs/issues/945)
|
||||
- **Used for**: Sharing contact code, reading transaction requests.
|
||||
- **Related**:
|
||||
[Issue](https://github.com/status-im/status-mobile/issues/5870)
|
||||
|
||||
### EIP1102 - Opt-in Account Exposure
|
||||
|
||||
- **Support**: Full.
|
||||
- **Reference**: [EIP1102](https://eips.ethereum.org/EIPS/eip-1102)
|
||||
- **Description**: Allow users to opt-in to expose their Ethereum address to dapps.
|
||||
- **Used for**: Privacy, DApp support.
|
||||
- **Related**:
|
||||
[Issue](https://github.com/status-im/status-mobile/issues/7985)
|
||||
|
||||
### EIP1193 - Ethereum Provider JavaScript API
|
||||
|
||||
- **Support**: Full.
|
||||
- **Reference**: [EIP1193](https://eips.ethereum.org/EIPS/eip-1193)
|
||||
- **Description**: Allows dapps to recognize event changes on wallet.
|
||||
- **Used for**: DApp support.
|
||||
- **Related**:
|
||||
[PR](https://github.com/status-im/status-mobile/pull/7246)
|
||||
|
||||
### EIP1577 - Contenthash Field for ENS
|
||||
|
||||
- **Support**: Partial.
|
||||
- **Reference**: [EIP1577](https://eips.ethereum.org/EIPS/eip-1577)
|
||||
- **Description**: Allows users to browse ENS domains using the contenthash standard.
|
||||
- **Used for**: Browser, DApp support.
|
||||
- **Related**:
|
||||
[Issue](https://github.com/status-im/status-mobile/issues/6688)
|
||||
- **Source code**:
|
||||
[Contenthash](https://github.com/status-im/status-mobile/blob/develop/src/status_im/utils/contenthash.cljs)
|
||||
|
||||
### EIP1581 - Non-wallet Usage of Keys Derived from BIP-32 Trees
|
||||
|
||||
- **Support**: Partial.
|
||||
- **Reference**: [EIP1581](https://eips.ethereum.org/EIPS/eip-1581)
|
||||
- **Description**: Allow wallets to derive less sensitive keys (non-wallet).
|
||||
- **Used for**: Security (don’t reuse wallet key), user experience (no keycard).
|
||||
- **Related**:
|
||||
[Issue](https://github.com/status-im/status-mobile/issues/9088)
|
||||
- **Source code**:
|
||||
[Constants](https://github.com/status-im/status-mobile/blob/develop/src/status_im/constants.cljs#L242)
|
||||
|
||||
### EIP1459 - Node Discovery via DNS
|
||||
|
||||
- **Support**: N/A.
|
||||
- **Reference**: [EIP1459](https://eips.ethereum.org/EIPS/eip-1459)
|
||||
- **Description**: Storing and retrieving nodes via merkle trees in TXT domain records.
|
||||
- **Used for**: Finding Waku nodes.
|
||||
|
||||
---
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
||||
139
status/deprecated/IPFS-gateway-for-sticker-Pack.md
Normal file
139
status/deprecated/IPFS-gateway-for-sticker-Pack.md
Normal file
@@ -0,0 +1,139 @@
|
||||
---
|
||||
title: IPFS-gateway-for-Sticker-Pack
|
||||
name: IPFS gateway for Sticker Pack
|
||||
status: deprecated
|
||||
description: This specification describes how Status uses the IPFS gateway to store stickers.
|
||||
editor: Filip Dimitrijevic <filip@status.im>
|
||||
contributors:
|
||||
- Gheorghe Pinzaru <gheorghe@status.im>
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
This specification describes how Status uses the IPFS gateway
|
||||
to store stickers.
|
||||
The specification explores image format,
|
||||
how a user uploads stickers,
|
||||
and how an end user can see them inside the Status app.
|
||||
|
||||
## Definition
|
||||
|
||||
| Term | Description |
|
||||
|---------------|------------------------------------------------------------------|
|
||||
| Stickers | A set of images used to express emotions |
|
||||
| Sticker Pack | ERC721 token including the set of stickers |
|
||||
| IPFS | P2P network used to store and share data, e.g., sticker images |
|
||||
|
||||
## Specification
|
||||
|
||||
### Image Format
|
||||
|
||||
Accepted image file types are PNG, JPG/JPEG, and GIF,
|
||||
with a maximum allowed size of 300kb.
|
||||
The minimum sticker image resolution is 512x512,
|
||||
and its background SHOULD be transparent.
|
||||
|
||||
### Distribution
|
||||
|
||||
The node implements sticker packs as ERC721 tokens,
|
||||
which contain a set of stickers.
|
||||
The node stores these stickers inside the sticker pack
|
||||
as a set of hyperlinks pointing to IPFS storage.
|
||||
These hyperlinks are publicly available
|
||||
and can be accessed by any user inside the Status chat.
|
||||
Stickers can be sent in chat only by accounts that own the sticker pack.
|
||||
|
||||
### IPFS Gateway
|
||||
|
||||
The current main Status app uses the Infura gateway,
|
||||
but clients may choose a different gateway or run their own IPFS node.
|
||||
Infura gateway is an HTTPS gateway,
|
||||
which based on an HTTP GET request with the multihash block
|
||||
will return the stored content at that block address.
|
||||
|
||||
The node requires the use of a gateway
|
||||
to enable easy access to resources over HTTP.
|
||||
The node stores each sticker image in IPFS
|
||||
using a unique address derived from the hash of the file,
|
||||
ensuring the file cannot be overridden.
|
||||
An end-user will receive the same file at a given address.
|
||||
|
||||
### Security
|
||||
|
||||
The IPFS gateway acts as an end-user of IPFS,
|
||||
allowing gateway users to access IPFS without connecting to the P2P network.
|
||||
Using a gateway introduces potential risks for its users.
|
||||
In case of a security compromise,
|
||||
metadata such as IP address and User-Agent may be leaked.
|
||||
If provider servers are unavailable,
|
||||
the node loses access to the IPFS network through the gateway.
|
||||
|
||||
### Status Sticker Usage
|
||||
|
||||
When the app shows a sticker,
|
||||
Status makes an HTTP GET request to the IPFS gateway
|
||||
using the hyperlink.
|
||||
|
||||
To send a sticker in chat,
|
||||
a Status user must buy or install a sticker pack.
|
||||
|
||||
For a Sticker Pack to be available for installation,
|
||||
it should be submitted to the Sticker Market by an author.
|
||||
|
||||
### Submit a Sticker
|
||||
|
||||
To submit a sticker pack,
|
||||
the author should upload all assets to IPFS.
|
||||
Then, generate a payload including name, author, thumbnail, preview,
|
||||
and a list of stickers in the EDN format, following this structure:
|
||||
|
||||
```edn
|
||||
{meta {:name "Sticker pack name"
|
||||
:author "Author Name"
|
||||
:thumbnail "e30101701220602163b4f56c747333f43775fdcbe4e62d6a3e147b22aaf6097ce0143a6b2373"
|
||||
:preview "e30101701220ef54a5354b78ef82e542bd468f58804de71c8ec268da7968a1422909357f2456"
|
||||
:stickers [{:hash "e301017012207737b75367b8068e5bdd027d7b71a25138c83e155d1f0c9bc5c48ff158724495"}
|
||||
{:hash "e301017012201a9cdea03f27cda1aede7315f79579e160c7b2b6a2eb51a66e47a96f47fe5284"}]}}
|
||||
```
|
||||
|
||||
All asset fields are contenthash fields as per EIP 1577.
|
||||
The node also uploads this payload to IPFS
|
||||
and uses the IPFS address in the content field of the Sticker Market contract.
|
||||
See Sticker Market spec for a detailed contract description.
|
||||
|
||||
### Install a Sticker Pack
|
||||
|
||||
To install a sticker pack,
|
||||
the node fetches all sticker packs available in Sticker Market
|
||||
by following these steps:
|
||||
|
||||
1. **Get Total Number of Sticker Packs**
|
||||
Call `packCount()` on the sticker market contract,
|
||||
which returns the number of registered sticker packs as `uint256`.
|
||||
|
||||
2. **Get Sticker Pack by ID**
|
||||
IDs are represented as `uint256` and are incremental
|
||||
from 0 to the total number of sticker packs.
|
||||
Call `getPackData(sticker-pack-id)`,
|
||||
which returns fields: `[category, owner, mintable, timestamp, price, contenthash]`.
|
||||
|
||||
3. **Get Owned Sticker Packs**
|
||||
When opening any sticker view,
|
||||
the Status app fetches owned sticker packs.
|
||||
Call `balanceOf(address)` with the current account address,
|
||||
returning the count of available tokens.
|
||||
Use `tokenOfOwnerByIndex(address, uint256)`
|
||||
to get the token id, and call `tokenPackId(uint256)`
|
||||
to get the owned sticker pack id.
|
||||
|
||||
4. **Buy a Sticker Pack**
|
||||
To buy a sticker pack,
|
||||
call `approveAndCall(address, uint256, bytes)`
|
||||
with the address of the buyer, price,
|
||||
and callback parameters. In the callback,
|
||||
call `buyToken(uint256, address, uint256)`
|
||||
with sticker pack id, buyer's address, and price.
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
||||
235
status/deprecated/account.md
Normal file
235
status/deprecated/account.md
Normal file
@@ -0,0 +1,235 @@
|
||||
---
|
||||
title: ACCOUNT
|
||||
name: Account
|
||||
status: deprecated
|
||||
description: This specification explains what a Status account is, and how a node establishes trust.
|
||||
editor: Filip Dimitrijevic <filip@status.im>
|
||||
contributors:
|
||||
- Corey Petty <corey@status.im>
|
||||
- Oskar Thorén <oskar@status.im>
|
||||
- Samuel Hawksby-Robinson <samuel@status.im>
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
This specification explains what a Status account is,
|
||||
and how a node establishes trust.
|
||||
|
||||
## Introduction
|
||||
|
||||
The core concept of an account in Status is a set of cryptographic keypairs,
|
||||
namely:
|
||||
|
||||
- a Whisper/Waku chat identity keypair
|
||||
- a set of cryptocurrency wallet keypairs
|
||||
|
||||
The node verifies or derives everything else associated with the contact
|
||||
from the above items, including:
|
||||
|
||||
- Ethereum address (future verification, currently the same base keypair)
|
||||
- 3-word mnemonic name
|
||||
- identicon
|
||||
- message signatures
|
||||
|
||||
## Initial Key Generation
|
||||
|
||||
### Public/Private Keypairs
|
||||
|
||||
An ECDSA (secp256k1 curve) public/private keypair **MUST** be generated via
|
||||
a BIP43-derived path from a BIP39 mnemonic seed phrase.
|
||||
|
||||
The default paths are defined as:
|
||||
|
||||
- Whisper/Waku Chat Key (IK): `m/43'/60'/1581'/0'/0` (post Multiaccount
|
||||
integration), following EIP1581
|
||||
- Status Wallet paths: `m/44'/60'/0'/0/i` starting at `i=0`, following BIP44
|
||||
|
||||
### X3DH Prekey bundle creation
|
||||
|
||||
Status follows the X3DH prekey bundle scheme outlined by Open Whisper Systems,
|
||||
with the following exceptions:
|
||||
|
||||
- Status does not publish one-time keys (OPK) or perform DH including them,
|
||||
as there are no central servers.
|
||||
|
||||
A client **MUST** create X3DH prekey bundles, defined by:
|
||||
|
||||
- **Identity Key (IK)**
|
||||
- **Signed prekey (SPK)**
|
||||
- **Prekey signature**: Sig(IK, Encode(SPK))
|
||||
- **Timestamp**
|
||||
|
||||
## Account Broadcasting
|
||||
|
||||
A user broadcasts certain information publicly so others may contact them.
|
||||
|
||||
### X3DH Prekey bundles
|
||||
|
||||
A client **SHOULD** regenerate a new X3DH prekey bundle every 24 hours.
|
||||
This **MAY** be done lazily, so that a client offline for longer
|
||||
does not regenerate or broadcast bundles.
|
||||
|
||||
The current bundle **SHOULD** be broadcast on a Whisper/Waku topic
|
||||
specific to its Identity Key, `{IK}-contact-code`, every six hours.
|
||||
|
||||
A bundle **SHOULD** accompany every message sent.
|
||||
|
||||
## Optional Account Additions
|
||||
|
||||
### ENS Username
|
||||
|
||||
A user **MAY** register a public username on the Ethereum Name System (ENS).
|
||||
This username is a subdomain of `stateofus.eth` that maps to their
|
||||
Whisper/Waku identity key (IK).
|
||||
|
||||
## Trust Establishment
|
||||
|
||||
Trust establishment involves users verifying they are communicating
|
||||
with who they think they are.
|
||||
|
||||
## Terms Glossary
|
||||
|
||||
| Term | Description |
|
||||
|----------------|---------------------------------------------------------|
|
||||
| privkey | ECDSA secp256k1 private key |
|
||||
| pubkey | ECDSA secp256k1 public key |
|
||||
| Whisper/Waku key | pubkey for chat with HD derivation path `m/43’/60’/1581’/0’/0` |
|
||||
|
||||
## Contact Discovery
|
||||
|
||||
### Public Channels
|
||||
|
||||
Public group channels in Status are a broadcast/subscription system.
|
||||
All public messages are encrypted with a symmetric key derived from
|
||||
the channel name, `K_{pub,sym}`, which is publicly known.
|
||||
|
||||
A public group channel’s symmetric key **MUST** follow the
|
||||
`web3.ssh.generateSymKeyFromPassword` function.
|
||||
|
||||
To post to a public group channel, a client **MUST** have a valid account.
|
||||
To listen, a client **MUST** subscribe to the channel name.
|
||||
The sender is derived from the message’s signature.
|
||||
|
||||
Discovery of channel names is out of band.
|
||||
If a new channel name is used, it will be created.
|
||||
|
||||
A client **MUST** sign the message; otherwise, recipients discard it.
|
||||
|
||||
### Private 1:1 Messages
|
||||
|
||||
1:1 messaging **MAY** be achieved by:
|
||||
|
||||
- scanning a user-generated QR code
|
||||
- discovering through the Status app
|
||||
- asynchronous X3DH key exchange
|
||||
- public key via public channel listening
|
||||
|
||||
The message’s sender derives from the message’s signature.
|
||||
|
||||
## Initial Key Exchange
|
||||
|
||||
### Bundles
|
||||
|
||||
An X3DH prekey bundle is defined by:
|
||||
|
||||
- **Identity Key (IK)**
|
||||
- **SignedPreKeys**: map of installation ID to signed prekeys
|
||||
- **Signature**: prekey signature
|
||||
- **Timestamp**: last local creation time
|
||||
|
||||
A new bundle **SHOULD** be created every 12 hours,
|
||||
generated only when in use,
|
||||
and **SHOULD** be distributed on the contact code channel.
|
||||
|
||||
## Contact Verification
|
||||
|
||||
To verify contact key information:
|
||||
|
||||
### Identicon
|
||||
|
||||
A low-poly identicon is generated deterministically from the Whisper/Waku chat
|
||||
public key.
|
||||
This can be compared out of band for verification.
|
||||
|
||||
### 3-Word Pseudonym / Whisper/Waku Key Fingerprint
|
||||
|
||||
Status generates a 3-word pseudonym from the Whisper/Waku chat public key.
|
||||
This pseudonym is a human-readable fingerprint
|
||||
and appears in contact profiles and chat UI.
|
||||
|
||||
### ENS Name
|
||||
|
||||
Status allows registering a subdomain of `stateofus.eth` mapped to the
|
||||
Whisper/Waku chat public key, for a stake of 10 SNT.
|
||||
|
||||
## Public Key Serialization
|
||||
|
||||
The node **SHOULD** provide public key serialization
|
||||
and deserialization for chat keys.
|
||||
|
||||
For flexibility, the node **MUST** support public keys encoded in various
|
||||
formats.
|
||||
|
||||
### Basic Serialization Example
|
||||
|
||||
A typical secp256k1 public key, hex-encoded:
|
||||
|
||||
0x04261c55675e55ff25edb50b345cfb3a3f35f60712d251cbaaab97bd50054c6ebc3cd4e22200c68daf7493e1f8da6a190a68a671e2d3977809612424c7c3888bc6
|
||||
|
||||
For compatibility, the key is modified as:
|
||||
|
||||
fe70104261c55675e55ff25edb50b345cfb3a3f35f60712d251cbaaab97bd50054c6ebc3cd4e22200c68daf7493e1f8da6a190a68a671e2d3977809612424c7c3888bc6
|
||||
|
||||
### Public Key “Compression” Rationale
|
||||
|
||||
Compressed keys have UI/UX advantages.
|
||||
They are smaller and less intimidating,
|
||||
with a character length reduction of up to 64%.
|
||||
|
||||
For example:
|
||||
|
||||
- Uncompressed: 136 characters
|
||||
- Compressed: 49 characters
|
||||
|
||||
### Key Encoding
|
||||
|
||||
The node **MUST** use `multiformats/multibase` encoding
|
||||
to interpret incoming key data and return encoded data.
|
||||
Supported formats include `base2`, `base10`, `base16`, `base58btc`, and others.
|
||||
|
||||
## Public Key Types
|
||||
|
||||
The node **MUST** support `multicodec` key type identifiers:
|
||||
|
||||
| Name | Tag | Code | Description |
|
||||
|----------------|-----|-------|-------------------------|
|
||||
| secp256k1-pub | key | 0xe7 | Secp256k1 public key |
|
||||
|
||||
The public key **MUST** be prepended with the relevant `multiformats/uvarint`
|
||||
formatted code.
|
||||
|
||||
## De/Serialization Process Flow
|
||||
|
||||
The node **MUST** be passed a `multicodec` identified public key,
|
||||
encoded with a valid `multibase` identifier.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
Refer to the security section for additional considerations.
|
||||
|
||||
## Changelog
|
||||
|
||||
### Version 0.4
|
||||
|
||||
- Released June 24, 2020
|
||||
- Added details of public key serialization and deserialization
|
||||
|
||||
### Version 0.3
|
||||
|
||||
- Released May 22, 2020
|
||||
- Added Waku inclusion language
|
||||
- Clarified Open Whisper Systems
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
||||
229
status/deprecated/client.md
Normal file
229
status/deprecated/client.md
Normal file
@@ -0,0 +1,229 @@
|
||||
---
|
||||
title: CLIENT
|
||||
name: Client
|
||||
status: deprecated
|
||||
description: This specification describes how to write a Status client for communicating with other Status clients.
|
||||
editor: Filip Dimitrijevic <filip@status.im>
|
||||
contributors:
|
||||
- Adam Babik <adam@status.im>
|
||||
- Andrea Maria Piana <andreap@status.im>
|
||||
- Dean Eigenmann <dean@status.im>
|
||||
- Corey Petty <corey@status.im>
|
||||
- Oskar Thorén <oskar@status.im>
|
||||
- Samuel Hawksby-Robinson <samuel@status.im>
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
This specification describes how to write a Status client for communicating
|
||||
with other Status clients.
|
||||
This specification presents a reference implementation of the protocol
|
||||
used in a command-line client and a mobile app.
|
||||
|
||||
This document consists of two parts.
|
||||
The first outlines the specifications required to be a full Status client.
|
||||
The second provides a design rationale and answers some common questions.
|
||||
|
||||
## Introduction
|
||||
|
||||
Implementing a Status client means implementing multiple layers.
|
||||
This includes specifications for key management and account lifecycle.
|
||||
|
||||
Other aspects, such as how a node uses IPFS for stickers or how the browser
|
||||
works, are currently underspecified.
|
||||
These specifications support implementing a Status client for basic private
|
||||
communication.
|
||||
|
||||
| Layer | Purpose | Technology |
|
||||
|-----------------|------------------------|------------------------|
|
||||
| Data and payloads | End user functionality | 1:1, group chat, public chat |
|
||||
| Data sync | Data consistency | MVDS |
|
||||
| Secure transport | Confidentiality, PFS | Double Ratchet |
|
||||
| Transport privacy | Routing, Metadata protection | Waku / Whisper |
|
||||
| P2P Overlay | Overlay routing, NAT traversal | devp2p |
|
||||
|
||||
## Protobuf
|
||||
|
||||
`protobuf` is used in different layers, with `proto3` as the default version
|
||||
unless otherwise specified.
|
||||
|
||||
## Components
|
||||
|
||||
### P2P Overlay
|
||||
|
||||
Status clients run on a public, permissionless peer-to-peer network,
|
||||
as specified by the devP2P network protocols.
|
||||
devP2P provides a protocol for node discovery,
|
||||
and the RLPx Transport Protocol v5 is used for TCP-based communication.
|
||||
|
||||
The client **SHOULD NOT** use Whisper V6.
|
||||
Instead, the client **SHOULD** use Waku V1 for privacy-preserving messaging
|
||||
and efficient bandwidth usage.
|
||||
|
||||
### Node Discovery and Roles
|
||||
|
||||
There are four types of node roles:
|
||||
|
||||
- Bootstrap node
|
||||
- Whisper/Waku relayer
|
||||
- Mailserver (servers and clients)
|
||||
- Mobile node (Status Clients)
|
||||
|
||||
A standard Status client **MUST** implement both Whisper/Waku relayer
|
||||
and Mobile node node types.
|
||||
Implementing a Mailserver client mode is **RECOMMENDED** for user experience.
|
||||
|
||||
### Bootstrapping
|
||||
|
||||
Bootstrap nodes allow Status nodes to discover and connect to other nodes.
|
||||
Status GmbH provides the main bootstrap nodes,
|
||||
but anyone connected to the Whisper/Waku network can run one.
|
||||
|
||||
The current list of production bootstrap nodes is available
|
||||
at locations in Hong Kong, Amsterdam, and Central US.
|
||||
These nodes **MAY** change as needed.
|
||||
|
||||
### Discovery
|
||||
|
||||
A Status client **MUST** discover or have a list of peers to connect to.
|
||||
Status uses a light discovery mechanism
|
||||
based on Discovery v5 and Rendezvous Protocol.
|
||||
Static nodes **MAY** also be used.
|
||||
|
||||
Discovery V5 is kademlia-based and may consume significant network traffic.
|
||||
The Rendezvous protocol is request-response and uses ENR to report peers.
|
||||
|
||||
Both discovery mechanisms use topics
|
||||
to provide peers with specific capabilities.
|
||||
Status nodes wanting discovery **MUST** register with the `whisper` topic,
|
||||
and Mailservers **MUST** additionally register with `whispermail`.
|
||||
|
||||
Using both mechanisms is **RECOMMENDED**, alongside a `PeerPool` structure
|
||||
for optimal peer count management.
|
||||
|
||||
### Mobile Nodes
|
||||
|
||||
A Mobile node is a Whisper and/or Waku node connecting to the network.
|
||||
Mobile nodes **MAY** relay messages.
|
||||
See WHISPER-USAGE and WAKU-USAGE for more details.
|
||||
|
||||
For an offline inbox, see WHISPER-MAILSERVER and WAKU-MAILSERVER.
|
||||
|
||||
## Transport Privacy and Whisper/Waku Usage
|
||||
|
||||
After a Whisper/Waku node is active,
|
||||
specific settings are required for communication with other Status nodes.
|
||||
|
||||
## Secure Transport
|
||||
|
||||
To provide confidentiality, integrity, authentication,
|
||||
and forward secrecy, secure transport is implemented on top of Whisper/Waku.
|
||||
This applies to 1:1 and group chats, but not public chats.
|
||||
See SECURE-TRANSPORT for more.
|
||||
|
||||
## Data Sync
|
||||
|
||||
MVDS is used for 1:1 and group chats but is currently unused for public chats.
|
||||
Status payloads are serialized, wrapped in an MVDS message,
|
||||
and encrypted if needed for secure chats before sending.
|
||||
|
||||
## Payloads and Clients
|
||||
|
||||
On top of secure transport, Status uses various data sync clients
|
||||
and payload formats for chat types.
|
||||
Refer to PAYLOADS for details.
|
||||
|
||||
## BIPs and EIPs Standards Support
|
||||
|
||||
For EIPs and BIPs **SHOULD** supported by Status clients, see EIPS.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
See Appendix A for detailed security considerations.
|
||||
|
||||
## Design Rationale
|
||||
|
||||
P2P Overlay
|
||||
|
||||
### Why devp2p? Why not use libp2p?
|
||||
|
||||
At Status's start, devp2p was the most mature option.
|
||||
In the future, libp2p may be used for multiple transports,
|
||||
NAT traversal, and better protocol negotiation.
|
||||
|
||||
#### Why do you use Whisper?
|
||||
|
||||
Whisper was part of Ethereum's vision for a "world computer" alongside Swarm.
|
||||
|
||||
#### Why do you use Waku?
|
||||
|
||||
Waku is an upgraded, optimized version of Whisper,
|
||||
addressing resource-restricted device limitations.
|
||||
Waku standardizes messages for compatibility and scalability.
|
||||
|
||||
Data Sync
|
||||
|
||||
### Why is MVDS not used for public chats?
|
||||
|
||||
Public chats are broadcast-based,
|
||||
and MVDS is not optimized for large group contexts.
|
||||
This is an active research area.
|
||||
|
||||
## Footnotes
|
||||
|
||||
1. [Footnote 1](https://github.com/status-im/status-protocol-go/)
|
||||
2. [Footnote 2](https://github.com/status-im/status-console-client/)
|
||||
3. [Footnote 3](https://github.com/status-im/status-mobile/)
|
||||
|
||||
## Appendix A: Security Considerations
|
||||
|
||||
Chief considerations include scalability, DDoS resistance,
|
||||
and privacy depending on the capabilities used.
|
||||
|
||||
### Scalability and UX
|
||||
|
||||
- **Bandwidth usage**: High in version 1.
|
||||
- **Mailserver High Availability**:
|
||||
Mailserver needs to be online for receiving messages.
|
||||
- **Gossip-based routing**:
|
||||
Propagation probability may be low with too many light nodes.
|
||||
- **Lack of incentives**:
|
||||
Centralized choke points can form without node-running incentives.
|
||||
|
||||
### Privacy
|
||||
|
||||
- **Light node privacy**:
|
||||
Connected peers know message origin.
|
||||
- **Bloom filter privacy**:
|
||||
Interests reveal topics in bloom filters.
|
||||
- **Mailserver client privacy**:
|
||||
Trusted Mailservers reveal topic, IP, and peerID.
|
||||
- **Privacy guarantees not rigorous**:
|
||||
Privacy not rigorously studied like Tor or mixnets.
|
||||
|
||||
### Spam Resistance
|
||||
|
||||
Proof of work is ineffective for heterogeneous devices,
|
||||
and a Mailserver can overwhelm a node with traffic.
|
||||
|
||||
### Censorship Resistance
|
||||
|
||||
Devp2p runs on port 30303, making it susceptible to censorship.
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
- Jacek Sieka
|
||||
|
||||
## Changelog
|
||||
|
||||
### Version 0.3
|
||||
|
||||
- Released May 22, 2020
|
||||
- Added that Waku **SHOULD** be used
|
||||
- Added that Whisper **SHOULD NOT** be used
|
||||
- Updated Mailserver term consistency
|
||||
- Added language for Waku in all relevant places
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
||||
125
status/deprecated/dapp-browser-API-usage.md
Normal file
125
status/deprecated/dapp-browser-API-usage.md
Normal file
@@ -0,0 +1,125 @@
|
||||
---
|
||||
title: Dapp browser API usage
|
||||
name: Dapp browser API usage
|
||||
status: deprecated
|
||||
description: This document describes requirements that an application must fulfill in order to provide a proper environment for Dapps running inside a browser.
|
||||
editor: Filip Dimitrijevic <filip@status.im>
|
||||
contributors:
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
This document describes requirements for applications to support Dapps
|
||||
running inside a browser.
|
||||
It includes a description of the Status Dapp API,
|
||||
an overview of the bidirectional communication underlying the API,
|
||||
and a list of EIPs implemented by this API.
|
||||
|
||||
## Definitions
|
||||
|
||||
| Term | Description |
|
||||
|-------------------|-------------------------------------------------------------------------------------------|
|
||||
| Webview | Platform-specific browser core implementation. |
|
||||
| Ethereum Provider | JS object (`window.ethereum`) injected into each web page opened in the browser, providing a web3-compatible provider. |
|
||||
| Bridge | Facilities allowing bidirectional communication between JS code and the application. |
|
||||
|
||||
## Overview
|
||||
|
||||
The application should expose an Ethereum Provider object (`window.ethereum`)
|
||||
to JavaScript running inside the browser.
|
||||
The `window.ethereum` object must be available before the page loads,
|
||||
as Dapps may not function correctly otherwise.
|
||||
|
||||
The browser component should also enable bidirectional communication
|
||||
between JavaScript code and the application.
|
||||
|
||||
## Usage in Dapps
|
||||
|
||||
Dapps can use the following properties and methods of the `window.ethereum` object.
|
||||
|
||||
### Properties
|
||||
|
||||
- **isStatus**
|
||||
Returns `true`. Indicates if the Dapp is running inside Status.
|
||||
|
||||
- **status**
|
||||
Returns a `StatusAPI` object.
|
||||
Currently, it supports one method: `getContactCode`,
|
||||
which sends a contact-code request to Status.
|
||||
|
||||
### Methods
|
||||
|
||||
- **isConnected**
|
||||
Similar to the Ethereum JS API documentation, it checks if a node connection exists.
|
||||
In Status, this function always returns `true` since the node is automatically started.
|
||||
|
||||
- **scanQRCode**
|
||||
Sends a QR code request to the Status API.
|
||||
|
||||
- **request**
|
||||
Implements the `request` method as defined by EIP-1193.
|
||||
|
||||
### Unused (Legacy)
|
||||
|
||||
Below are deprecated methods that some Dapps may still use.
|
||||
|
||||
- **enable** *(DEPRECATED)*
|
||||
Sends a web3 Status API request
|
||||
and returns the first account in the list of available accounts.
|
||||
Follows the legacy `enable` method from EIP-1102.
|
||||
|
||||
- **send** *(DEPRECATED)*
|
||||
Legacy `send` method as per EIP-1193.
|
||||
|
||||
- **sendAsync** *(DEPRECATED)*
|
||||
Legacy `sendAsync` method as per EIP-1193.
|
||||
|
||||
- **sendSync** *(DEPRECATED)*
|
||||
Legacy `send` method.
|
||||
|
||||
## Implementation
|
||||
|
||||
Status uses a forked version of `react-native-webview` to display web or Dapp content.
|
||||
This fork provides an Android implementation of JavaScript injection
|
||||
before the page loads,
|
||||
which is required to inject the Ethereum Provider object correctly.
|
||||
|
||||
Status injects two JavaScript scripts:
|
||||
|
||||
1. **provider.js**: Injects the `window.ethereum` object.
|
||||
2. **webview.js**: Overrides `history.pushState` for internal use.
|
||||
|
||||
Dapps in the browser communicate with the Status Ethereum node
|
||||
via a bridge provided by `react-native-webview`,
|
||||
allowing bidirectional communication between the browser and Status.
|
||||
A special `ReactNativeWebView` object is injected into each loaded page.
|
||||
|
||||
On the Status (React Native) end, `react-native-webview` provides
|
||||
the `WebView.injectJavascript` function,
|
||||
which enables execution of arbitrary code inside the webview.
|
||||
This allows injecting a function call to pass Status node responses back to the Dapp.
|
||||
|
||||
| Direction | Side | Method |
|
||||
|------------------|------|-----------------------------|
|
||||
| Browser -> Status| JS | `ReactNativeWebView.postMessage()` |
|
||||
| Browser -> Status| RN | `WebView.onMessage()` |
|
||||
| Status -> Browser| JS | `ReactNativeWebView.onMessage()` |
|
||||
| Status -> Browser| RN | `WebView.injectJavascript()`|
|
||||
|
||||
## Compatibility
|
||||
|
||||
Status browser supports the following EIPs:
|
||||
|
||||
- **EIP-1102**: `eth_requestAccounts` support.
|
||||
- **EIP-1193**: `connect`, `disconnect`, `chainChanged`,
|
||||
and `accountsChanged` event support are not implemented.
|
||||
|
||||
## Changelog
|
||||
|
||||
| Version | Comment |
|
||||
|---------|-------------------|
|
||||
| 0.1.0 | Initial release. |
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
||||
198
status/deprecated/ethereum-usage.md
Normal file
198
status/deprecated/ethereum-usage.md
Normal file
@@ -0,0 +1,198 @@
|
||||
---
|
||||
title: ETHEREUM-USAGE
|
||||
name: Status interactions with the Ethereum blockchain
|
||||
status: deprecated
|
||||
description: All interactions that the Status client has with the Ethereum blockchain.
|
||||
editor: Andrea Maria Piana <andreap@status.im>
|
||||
contributors:
|
||||
-
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
This specification details all interactions
|
||||
that the Status client has with the Ethereum blockchain.
|
||||
|
||||
## Background
|
||||
|
||||
This specification documents all interactions
|
||||
that the Status client has with the Ethereum blockchain.
|
||||
All interactions are made through JSON-RPC.
|
||||
Currently, Infura is used.
|
||||
The client assumes high availability;
|
||||
otherwise, it will not be able to interact with the Ethereum blockchain.
|
||||
Status nodes rely on these Infura nodes
|
||||
to validate transaction integrity and report consistent history.
|
||||
|
||||
[Key handling is described here](https://rfc.vac.dev/status/deprecated/ethereum-usage.md)
|
||||
|
||||
1 [Wallet]
|
||||
2 [ENS]
|
||||
|
||||
## Wallet
|
||||
|
||||
The wallet in Status has two main components:
|
||||
|
||||
1. Sending transactions
|
||||
2. Fetching balance
|
||||
|
||||
Below are the RPC calls made by the nodes,
|
||||
with brief descriptions of their functionality and how Status
|
||||
uses them.
|
||||
|
||||
### Sending Transactions
|
||||
|
||||
#### EstimateGas
|
||||
|
||||
`EstimateGas` tries to estimate the gas needed
|
||||
to execute a transaction based on the current pending state of the blockchain.
|
||||
There’s no guarantee this is the actual gas limit, but it provides a reasonable default.
|
||||
|
||||
```go
|
||||
func (ec *Client) EstimateGas(ctx context.Context, msg ethereum.CallMsg)(uint64, error)
|
||||
```
|
||||
|
||||
[Source](https://github.com/ethereum/go-ethereum/blob/26d271dfbba1367326dec38068f9df828d462c61/ethclient/ethclient.go#L499)
|
||||
|
||||
#### PendingNonceAt
|
||||
|
||||
`PendingNonceAt` returns the account nonce of the given account in the pending state.
|
||||
This should be used for the next transaction.
|
||||
|
||||
```go
|
||||
func (ec *Client) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error)
|
||||
```
|
||||
|
||||
[Source](https://github.com/ethereum/go-ethereum/blob/26d271dfbba1367326dec38068f9df828d462c61/ethclient/ethclient.go#L440)
|
||||
|
||||
#### SuggestGasPrice
|
||||
|
||||
`SuggestGasPrice` retrieves the suggested gas price for timely transaction execution.
|
||||
|
||||
```go
|
||||
func (ec *Client) SuggestGasPrice(ctx context.Context) (*big.Int, error)
|
||||
```
|
||||
|
||||
[Source](https://github.com/ethereum/go-ethereum/blob/26d271dfbba1367326dec38068f9df828d462c61/ethclient/ethclient.go#L487)
|
||||
|
||||
#### SendTransaction
|
||||
|
||||
`SendTransaction` injects a signed transaction into the pending pool for execution.
|
||||
If it's a contract creation, use `TransactionReceipt`
|
||||
to get the contract address after it's mined.
|
||||
|
||||
```go
|
||||
func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) error
|
||||
```
|
||||
|
||||
[Source](https://github.com/ethereum/go-ethereum/blob/26d271dfbba1367326dec38068f9df828d462c61/ethclient/ethclient.go#L512)
|
||||
|
||||
### Fetching Balance
|
||||
|
||||
A Status node fetches current and historical [ERC-20](https://eips.ethereum.org/EIPS/eip-20)
|
||||
and ETH balances for the user wallet address.
|
||||
It supports default tokens, with custom tokens added
|
||||
by specifying the address, symbol, and decimals.
|
||||
|
||||
#### BlockByHash
|
||||
|
||||
`BlockByHash` returns the full block,
|
||||
used to fetch transfers to the user address (ETH and tokens).
|
||||
|
||||
```go
|
||||
func (ec *Client) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error)
|
||||
```
|
||||
|
||||
[Source](https://github.com/ethereum/go-ethereum/blob/26d271dfbba1367326dec38068f9df828d462c61/ethclient/ethclient.go#L78)
|
||||
|
||||
#### BlockByNumber
|
||||
|
||||
`BlockByNumber` returns a block from the canonical chain. If `number` is nil,
|
||||
it returns the latest known block.
|
||||
|
||||
```go
|
||||
func (ec *Client) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error)
|
||||
```
|
||||
|
||||
[Source](https://github.com/ethereum/go-ethereum/blob/26d271dfbba1367326dec38068f9df828d462c61/ethclient/ethclient.go#L82)
|
||||
|
||||
#### FilterLogs
|
||||
|
||||
`FilterLogs` executes a filter query.
|
||||
Status uses it to filter logs using the block hash and address ofinterest.
|
||||
|
||||
```go
|
||||
func (ec *Client) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error)
|
||||
```
|
||||
|
||||
[Source](https://github.com/ethereum/go-ethereum/blob/26d271dfbba1367326dec38068f9df828d462c61/ethclient/ethclient.go#L377)
|
||||
|
||||
#### NonceAt
|
||||
|
||||
`NonceAt` returns the account nonce at a given block number.
|
||||
|
||||
```go
|
||||
func (ec *Client) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error)
|
||||
```
|
||||
|
||||
[Source](https://github.com/ethereum/go-ethereum/blob/26d271dfbba1367326dec38068f9df828d462c61/ethclient/ethclient.go#L366)
|
||||
|
||||
#### TransactionByHash
|
||||
|
||||
`TransactionByHash` returns the transaction with the given hash,
|
||||
used to inspect transactions made or received by the user.
|
||||
|
||||
```go
|
||||
func (ec *Client) TransactionByHash(ctx context.Context, hash common.Hash) (tx *types.Transaction, isPending bool, err error)
|
||||
```
|
||||
|
||||
[Source](https://github.com/ethereum/go-ethereum/blob/26d271dfbba1367326dec38068f9df828d462c61/ethclient/ethclient.go#L202)
|
||||
|
||||
#### HeaderByNumber
|
||||
|
||||
`HeaderByNumber` returns a block header from the canonical chain.
|
||||
|
||||
```go
|
||||
func (ec *Client) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error)
|
||||
```
|
||||
|
||||
[Source](https://github.com/ethereum/go-ethereum/blob/26d271dfbba1367326dec38068f9df828d462c61/ethclient/ethclient.go#L172)
|
||||
|
||||
#### TransactionReceipt
|
||||
|
||||
`TransactionReceipt` returns the receipt of a transaction by its hash,
|
||||
used to check if a token transfer was made to the user address.
|
||||
|
||||
```go
|
||||
func (ec *Client) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)
|
||||
```
|
||||
|
||||
[Source](https://github.com/ethereum/go-ethereum/blob/26d271dfbba1367326dec38068f9df828d462c61/ethclient/ethclient.go#L270)
|
||||
|
||||
### ENS
|
||||
|
||||
All interactions with ENS are made through the ENS contract.
|
||||
|
||||
#### Registering, Releasing, and Updating
|
||||
|
||||
- **Registering a Username**
|
||||
- **Releasing a Username**
|
||||
- **Updating a Username**
|
||||
- **Slashing**
|
||||
- Usernames MUST:
|
||||
- Contain only alphanumeric characters.
|
||||
- Not be in the form `0x[0-9a-f]{5}.*` and must have more than 12 characters.
|
||||
- Not be reserved or too short (checked against the contract).
|
||||
- **Slash a Username**:
|
||||
- Reserved
|
||||
- Invalid
|
||||
- Too similar to an address
|
||||
- Too short
|
||||
|
||||
ENS names are propagated through `ChatMessage` and `ContactUpdate` payloads.
|
||||
A client SHOULD verify ENS names against the sender's public key
|
||||
on message receipt, using the ENS contract.
|
||||
|
||||
## Copyright
|
||||
|
||||
Waived via CC0.
|
||||
186
status/deprecated/group-chat.md
Normal file
186
status/deprecated/group-chat.md
Normal file
@@ -0,0 +1,186 @@
|
||||
---
|
||||
title: GROUP-CHAT
|
||||
name: Group Chat
|
||||
status: deprecated
|
||||
description: This document describes the group chat protocol used by the Status application.
|
||||
editor: Filip Dimitrijevic <filip@status.im>
|
||||
contributors:
|
||||
- Andrea Piana <andreap@status.im>
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
This document describes the group chat protocol used by the Status application.
|
||||
The node uses pairwise encryption among members so a message is exchanged
|
||||
between each participant, similarly to a one-to-one message.
|
||||
|
||||
## Membership Updates
|
||||
|
||||
The node uses membership updates messages
|
||||
to propagate group chat membership changes.
|
||||
The protobuf format is described in the PAYLOADS.
|
||||
Below describes each specific field.
|
||||
|
||||
The protobuf messages are:
|
||||
|
||||
```protobuf
|
||||
// MembershipUpdateMessage is a message used to propagate information
|
||||
// about group membership changes.
|
||||
message MembershipUpdateMessage {
|
||||
// The chat id of the private group chat
|
||||
string chat_id = 1;
|
||||
// A list of events for this group chat, first 65 bytes are the signature,
|
||||
// then is a protobuf encoded MembershipUpdateEvent
|
||||
repeated bytes events = 2;
|
||||
// An optional chat message
|
||||
ChatMessage message = 3;
|
||||
}
|
||||
|
||||
message MembershipUpdateEvent {
|
||||
// Lamport timestamp of the event as described in [Status Payload Specs]
|
||||
uint64 clock = 1;
|
||||
// List of public keys of the targets 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;
|
||||
|
||||
enum EventType {
|
||||
UNKNOWN = 0;
|
||||
CHAT_CREATED = 1; // See [CHAT_CREATED](#chat-created)
|
||||
NAME_CHANGED = 2; // See [NAME_CHANGED](#name-changed)
|
||||
MEMBERS_ADDED = 3; // See [MEMBERS_ADDED](#members-added)
|
||||
MEMBER_JOINED = 4; // See [MEMBER_JOINED](#member-joined)
|
||||
MEMBER_REMOVED = 5; // See [MEMBER_REMOVED](#member-removed)
|
||||
ADMINS_ADDED = 6; // See [ADMINS_ADDED](#admins-added)
|
||||
ADMIN_REMOVED = 7; // See [ADMIN_REMOVED](#admin-removed)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Payload
|
||||
|
||||
**MembershipUpdateMessage:**
|
||||
|
||||
| Field | Name | Type | Description |
|
||||
|-------|---------|-----------|-----------------------------------------------------------------------------|
|
||||
| 1 | chat-id | string | The chat id of the chat where the change is to take place |
|
||||
| 2 | events | See details | A list of events that describe the membership changes, in their encoded protobuf form |
|
||||
| 3 | message | ChatMessage | An optional message, described in Message |
|
||||
|
||||
**MembershipUpdateEvent:**
|
||||
|
||||
| Field | Name | Type | Description |
|
||||
|-------|---------|--------------|---------------------------------------------------------------------------|
|
||||
| 1 | clock | uint64 | The clock value of the event |
|
||||
| 2 | members | []string | An optional list of hex encoded (prefixed with 0x) public keys, the targets of the action |
|
||||
| 3 | name | name | An optional name, for those events that make use of it |
|
||||
| 4 | type | EventType | The type of event sent, described below |
|
||||
|
||||
### Chat ID
|
||||
|
||||
Each membership update **MUST** be sent with a corresponding `chatId`.
|
||||
The format of this `chatId` **MUST** be a string of UUID, concatenated
|
||||
with the hex-encoded public key of the creator of the chat, joined by `-`.
|
||||
This `chatId` **MUST** be validated by all clients,
|
||||
and **MUST** be discarded if it does not follow these rules.
|
||||
|
||||
### Signature
|
||||
|
||||
The node calculates the signature for each event
|
||||
by encoding each `MembershipUpdateEvent` in its protobuf representation,
|
||||
and prepending the bytes of the `chatID`.
|
||||
Lastly, the node signs the Keccak256 of the bytes
|
||||
using the private key by the author
|
||||
and adds it to the `events` field of `MembershipUpdateMessage`.
|
||||
|
||||
### Group Membership Event
|
||||
|
||||
Any group membership event received **MUST** be verified
|
||||
by calculating the signature as per the method described above.
|
||||
The author **MUST** be extracted from it,
|
||||
and if the verification fails the event **MUST** be discarded.
|
||||
|
||||
### CHAT_CREATED
|
||||
|
||||
A `CHAT_CREATED` event is the first event that needs to be sent.
|
||||
Any event with a clock value lower than this **MUST** be discarded.
|
||||
Upon receiving this event, a client **MUST** validate the `chatId`
|
||||
provided with the updates
|
||||
and create a chat identified by `chatId` and named `name`.
|
||||
|
||||
### NAME_CHANGED
|
||||
|
||||
Admins use a `NAME_CHANGED` event to change the name of the group chat.
|
||||
Upon receiving this event,
|
||||
a client **MUST** validate the `chatId` provided with the updates
|
||||
and **MUST** ensure the author of the event is an admin of the chat,
|
||||
otherwise the event **MUST** be ignored.
|
||||
If the event is valid, the chat name **SHOULD** be changed to `name`.
|
||||
|
||||
### MEMBERS_ADDED
|
||||
|
||||
Admins use a `MEMBERS_ADDED` event to add members to the chat.
|
||||
Upon receiving this event,
|
||||
a client **MUST** validate the `chatId` provided with the updates
|
||||
and **MUST** ensure the author of the event is an admin of the chat,
|
||||
otherwise the event **MUST** be ignored.
|
||||
If the event is valid,
|
||||
a client **MUST** update the list of members of the chat who have not joined,
|
||||
adding the members received.
|
||||
`members` is an array of hex-encoded public keys.
|
||||
|
||||
### MEMBER_JOINED
|
||||
|
||||
Members use a `MEMBER_JOINED` event to signal that they want to start receiving
|
||||
messages from this chat.
|
||||
Upon receiving this event,
|
||||
a client **MUST** validate the `chatId` provided with the updates.
|
||||
If the event is valid,
|
||||
a client **MUST** update the list of members of the chat who joined,
|
||||
adding the signer.
|
||||
Any message sent to the group chat should now include the newly joined member.
|
||||
|
||||
### ADMINS_ADDED
|
||||
|
||||
Admins use an `ADMINS_ADDED` event to make others admins in the chat.
|
||||
Upon receiving this event,
|
||||
a client **MUST** validate the `chatId` provided with the updates,
|
||||
**MUST** ensure the author of the event is an admin of the chat,
|
||||
and **MUST** ensure all members are already members of the chat,
|
||||
otherwise the event **MUST** be ignored.
|
||||
If the event is valid,
|
||||
a client **MUST** update the list of admins of the chat,
|
||||
adding the members received.
|
||||
`members` is an array of hex-encoded public keys.
|
||||
|
||||
### MEMBER_REMOVED
|
||||
|
||||
Members and/or admins use a `MEMBER_REMOVED` event to leave or kick members
|
||||
from the chat.
|
||||
Upon receiving this event,
|
||||
a client **MUST** validate the `chatId` provided with the updates,
|
||||
and **MUST** ensure that:
|
||||
|
||||
- If the author of the event is an admin,
|
||||
the target can only be themselves or a non-admin member.
|
||||
- If the author of the event is not an admin,
|
||||
the target of the event can only be themselves.
|
||||
|
||||
If the event is valid,
|
||||
a client **MUST** remove the member from the list of members/admins of the chat,
|
||||
and no further message should be sent to them.
|
||||
|
||||
### ADMIN_REMOVED
|
||||
|
||||
Admins use an `ADMIN_REMOVED` event to drop admin privileges.
|
||||
Upon receiving this event,
|
||||
a client **MUST** validate the `chatId` provided with the updates,
|
||||
and **MUST** ensure that the author of the event is also the target of the event.
|
||||
If the event is valid,
|
||||
a client **MUST** remove the member from the list of admins of the chat.
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
||||
126
status/deprecated/keycard-usage-for-wallet-and-chat-keys.md
Normal file
126
status/deprecated/keycard-usage-for-wallet-and-chat-keys.md
Normal file
@@ -0,0 +1,126 @@
|
||||
---
|
||||
title: Keycard Usage for Wallet and Chat Keys
|
||||
name: Keycard Usage for Wallet and Chat Keys
|
||||
status: deprecated
|
||||
description: In this specification, we describe how Status communicates with Keycard to create, store and use multiaccount.
|
||||
editor: Filip Dimitrijevic <filip@status.im>
|
||||
contributors:
|
||||
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
This document specifies the integration of Keycard with Status
|
||||
for creating, storing, and managing multiaccounts.
|
||||
|
||||
## Definitions
|
||||
|
||||
- **Keycard Hardwallet**: Refer to [Keycard Documentation](https://keycard.tech/docs/).
|
||||
|
||||
---
|
||||
|
||||
## Multiaccount Creation/Restoring
|
||||
|
||||
### Creation and Restoring via Mnemonic
|
||||
|
||||
1. **Retrieve Application Info**
|
||||
|
||||
```clojure
|
||||
|
||||
status-im.hardwallet.card/get-application-info
|
||||
```
|
||||
|
||||
2. **Initialize Card**
|
||||
|
||||
```clojure
|
||||
|
||||
status-im.hardwallet.card/init-card
|
||||
```
|
||||
|
||||
3. **Pairing and Key Generation**
|
||||
|
||||
```clojure
|
||||
status-im.hard
|
||||
wallet.card/generate-and-load-keys
|
||||
```
|
||||
|
||||
### Restoring via Pairing
|
||||
|
||||
Used for pairing a card with an existing multiaccount:
|
||||
|
||||
1. **Retrieve Application Info**
|
||||
2. **Pair Card**
|
||||
3. **Generate and Load Keys**
|
||||
|
||||
---
|
||||
|
||||
## Multiaccount Unlocking
|
||||
|
||||
1. **Retrieve Application Info**
|
||||
2. **Get Keys with PIN**
|
||||
3. **Verify Pairing Status**
|
||||
|
||||
---
|
||||
|
||||
## Transaction Signing
|
||||
|
||||
1. **Retrieve Application Info**
|
||||
2. **Sign Transaction**
|
||||
|
||||
```clojure
|
||||
|
||||
status-im.hardwallet.card/sign
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Account Derivation
|
||||
|
||||
1. **Verify PIN**
|
||||
2. **Export Account Key**
|
||||
|
||||
```clojure
|
||||
|
||||
status-im.hardwallet.card/export-key
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PIN Management
|
||||
|
||||
### Reset PIN
|
||||
|
||||
- Change current PIN to new PIN.
|
||||
|
||||
### Unblock PIN
|
||||
|
||||
- If the PIN is entered incorrectly three times, use the PUK to reset.
|
||||
|
||||
---
|
||||
|
||||
## Status-Go Calls
|
||||
|
||||
### Required Status-Go API Calls
|
||||
|
||||
- **SaveAccountAndLoginWithKeycard**
|
||||
- **LoginWithKeycard**
|
||||
- **HashTransaction/HashMessage**
|
||||
- **SendTransactionWithSignature**
|
||||
|
||||
---
|
||||
|
||||
## Key Storage
|
||||
|
||||
### Keycard-Backed Account
|
||||
|
||||
All keys are securely stored on the Keycard, retrieved as needed.
|
||||
|
||||
### Database Encryption
|
||||
|
||||
A Keycard account’s database uses the `encryption-public-key` as a password.
|
||||
|
||||
---
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
||||
57
status/deprecated/notifications.md
Normal file
57
status/deprecated/notifications.md
Normal file
@@ -0,0 +1,57 @@
|
||||
---
|
||||
title: NOTIFICATIONS
|
||||
name: Notifications
|
||||
status: deprecated
|
||||
description: A client should implement local notifications to offer notifications for any event in the app without the privacy cost and dependency on third party services.
|
||||
editor: Filip Dimitrijevic <filip@status.im>
|
||||
contributors:
|
||||
- Eric Dvorsak <eric@status.im>
|
||||
---
|
||||
|
||||
## Local Notifications
|
||||
|
||||
A client should implement local notifications to offer notifications
|
||||
for any event in the app without the privacy cost and dependency on third-party services.
|
||||
This approach requires the client to run a background service to continuously
|
||||
or periodically check for updates.
|
||||
|
||||
### Android
|
||||
|
||||
Android allows running services on the device.
|
||||
When the user enables notifications, the client may start a `Foreground Service`
|
||||
and display a permanent notification indicating that the service is running,
|
||||
as required by Android guidelines.
|
||||
This service ensures that the app is not killed by the system
|
||||
when it runs in the background.
|
||||
The client can then run in the background
|
||||
and display local notifications on events,
|
||||
such as receiving a message in a one-to-one chat.
|
||||
|
||||
To facilitate implementing local notifications,
|
||||
a node implementation like `status-go` may provide a specific notification signal.
|
||||
|
||||
Notifications run as a separate process on Android,
|
||||
and interacting with a notification generates an Intent.
|
||||
The `NewMessageSignalHandler` may use a `BroadcastReceiver` to handle intents
|
||||
and update the state of local notifications
|
||||
when the user dismisses or taps a notification.
|
||||
If the user taps on a notification,
|
||||
the `BroadcastReceiver` generates a new intent to open the app,
|
||||
using universal links to navigate the user to the correct place.
|
||||
|
||||
### iOS
|
||||
|
||||
Local notifications cannot be offered on iOS,
|
||||
as there is no concept of persistent background services in iOS.
|
||||
It does support background updates, but these are not consistently triggered
|
||||
and cannot be relied upon. The system determines when background updates occur,
|
||||
based on unknown heuristics.
|
||||
|
||||
### Why Are There No Push Notifications?
|
||||
|
||||
Push Notifications, as provided by Apple and Google, present a privacy concern,
|
||||
as they require a centralized service that knows the recipient of each notification.
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
||||
354
status/deprecated/payloads.md
Normal file
354
status/deprecated/payloads.md
Normal file
@@ -0,0 +1,354 @@
|
||||
---
|
||||
title: PAYLOADS
|
||||
name: Payloads
|
||||
status: deprecated
|
||||
description: Payload of messages in Status, regarding chat and chat-related use cases.
|
||||
editor:
|
||||
contributors:
|
||||
- Adam Babik <adam@status.im>
|
||||
- Andrea Maria Piana <andreap@status.im>
|
||||
- Oskar Thorén <oskar@status.im>
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
This specification describes how the payload of each message in Status looks
|
||||
like. It is primarily centered around chat and chat-related use cases.
|
||||
|
||||
The payloads aim to be flexible enough to support messaging but also cases
|
||||
described in the Status Whitepaper as well as various clients created using
|
||||
different technologies.
|
||||
|
||||
## Introduction
|
||||
|
||||
This document describes the payload format and some special considerations.
|
||||
|
||||
## Payload Wrapper
|
||||
|
||||
The node wraps all payloads in a protobuf record:
|
||||
|
||||
```protobuf
|
||||
message ApplicationMetadataMessage {
|
||||
bytes signature = 1;
|
||||
bytes payload = 2;
|
||||
|
||||
Type type = 3;
|
||||
|
||||
enum Type {
|
||||
UNKNOWN = 0;
|
||||
CHAT_MESSAGE = 1;
|
||||
CONTACT_UPDATE = 2;
|
||||
MEMBERSHIP_UPDATE_MESSAGE = 3;
|
||||
PAIR_INSTALLATION = 4;
|
||||
SYNC_INSTALLATION = 5;
|
||||
REQUEST_ADDRESS_FOR_TRANSACTION = 6;
|
||||
ACCEPT_REQUEST_ADDRESS_FOR_TRANSACTION = 7;
|
||||
DECLINE_REQUEST_ADDRESS_FOR_TRANSACTION = 8;
|
||||
REQUEST_TRANSACTION = 9;
|
||||
SEND_TRANSACTION = 10;
|
||||
DECLINE_REQUEST_TRANSACTION = 11;
|
||||
SYNC_INSTALLATION_CONTACT = 12;
|
||||
SYNC_INSTALLATION_PUBLIC_CHAT = 14;
|
||||
CONTACT_CODE_ADVERTISEMENT = 15;
|
||||
PUSH_NOTIFICATION_REGISTRATION = 16;
|
||||
PUSH_NOTIFICATION_REGISTRATION_RESPONSE = 17;
|
||||
PUSH_NOTIFICATION_QUERY = 18;
|
||||
PUSH_NOTIFICATION_QUERY_RESPONSE = 19;
|
||||
PUSH_NOTIFICATION_REQUEST = 20;
|
||||
PUSH_NOTIFICATION_RESPONSE = 21;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`signature` is the bytes of the signed SHA3-256 of the payload,
|
||||
signed with the key of the author.
|
||||
The node uses the signature to validate authorship of the message
|
||||
so it can be relayed to third parties.
|
||||
Messages without signatures will not be relayed
|
||||
and are considered plausibly deniable.
|
||||
|
||||
`payload` is the protobuf-encoded content of the message,
|
||||
with the corresponding type set.
|
||||
|
||||
## Encoding
|
||||
|
||||
The node encodes the payload using Protobuf.
|
||||
|
||||
## Types of Messages
|
||||
|
||||
### Message
|
||||
|
||||
The type `ChatMessage` represents a chat message exchanged between clients.
|
||||
|
||||
### Payload
|
||||
|
||||
The protobuf description is:
|
||||
|
||||
```protobuf
|
||||
message ChatMessage {
|
||||
uint64 clock = 1; // Lamport timestamp of the chat message
|
||||
uint64 timestamp = 2; // Unix timestamps in milliseconds
|
||||
string text = 3; // Text of the message
|
||||
string response_to = 4; // Id of the message being replied to
|
||||
string ens_name = 5; // Ens name of the sender
|
||||
string chat_id = 6; // Chat id
|
||||
MessageType message_type = 7;
|
||||
ContentType content_type = 8;
|
||||
|
||||
oneof payload {
|
||||
StickerMessage sticker = 9;
|
||||
}
|
||||
|
||||
enum MessageType {
|
||||
UNKNOWN_MESSAGE_TYPE = 0;
|
||||
ONE_TO_ONE = 1;
|
||||
PUBLIC_GROUP = 2;
|
||||
PRIVATE_GROUP = 3;
|
||||
SYSTEM_MESSAGE_PRIVATE_GROUP = 4;
|
||||
}
|
||||
|
||||
enum ContentType {
|
||||
UNKNOWN_CONTENT_TYPE = 0;
|
||||
TEXT_PLAIN = 1;
|
||||
STICKER = 2;
|
||||
STATUS = 3;
|
||||
EMOJI = 4;
|
||||
TRANSACTION_COMMAND = 5;
|
||||
SYSTEM_MESSAGE_CONTENT_PRIVATE_GROUP = 6;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Payload Fields
|
||||
|
||||
| Field | Name | Type | Description |
|
||||
| ----------- | ----------- | ----------- | ------------------------------------------- |
|
||||
| 1 | clock | `uint64` | The clock of the chat |
|
||||
| 2 | timestamp | `uint64` | Sender timestamp at message creation |
|
||||
| 3 | text | `string` | The content of the message |
|
||||
| 4 | response_to | `string` | ID of the message replied to |
|
||||
| 5 | ens_name | `string` | ENS name of the user sending the message |
|
||||
| 6 | chat_id | `string` | Local ID of the chat |
|
||||
| 7 | message_type | `MessageType` | Type of message (one-to-one, public, group) |
|
||||
| 8 | content_type | `ContentType` | Type of message content |
|
||||
| 9 | payload | `Sticker\|nil` | Payload of the message |
|
||||
|
||||
## Content Types
|
||||
|
||||
Nodes require content types to interpret incoming messages. Not all messages
|
||||
are plain text; some carry additional information.
|
||||
|
||||
The following content types **MUST** be supported:
|
||||
|
||||
- `TEXT_PLAIN`: Identifies a message with plaintext content.
|
||||
|
||||
Other content types that **MAY** be implemented by clients include:
|
||||
|
||||
- `STICKER`
|
||||
- `STATUS`
|
||||
- `EMOJI`
|
||||
- `TRANSACTION_COMMAND`
|
||||
|
||||
## Mentions
|
||||
|
||||
A mention **MUST** be represented as a string in the `@0xpk` format,
|
||||
where `pk` is the public key of the user to be mentioned,
|
||||
within the text field of a message with `content_type: TEXT_PLAIN`.
|
||||
A message **MAY** contain more than one mention.
|
||||
|
||||
This specification **RECOMMENDS** that the application does not require the user
|
||||
to enter the entire public key. Instead, it should allow the user
|
||||
to create a mention by typing `@` followed by the ENS or 3-word pseudonym,
|
||||
with auto-completion functionality.
|
||||
|
||||
For better user experience, the client **SHOULD** display the ENS name
|
||||
or 3-word pseudonym corresponding to the key instead of the public key.
|
||||
|
||||
## Sticker Content Type
|
||||
|
||||
A `ChatMessage` with `STICKER` content type **MUST** specify the ID of the pack
|
||||
and the hash of the pack in the `Sticker` field:
|
||||
|
||||
```protobuf
|
||||
message StickerMessage {
|
||||
string hash = 1;
|
||||
int32 pack = 2;
|
||||
}
|
||||
```
|
||||
|
||||
## Message Types
|
||||
|
||||
A node requires message types to decide how to encrypt a message and what
|
||||
metadata to attach when passing it to the transport layer.
|
||||
|
||||
The following message types **MUST** be supported:
|
||||
|
||||
- `ONE_TO_ONE`: A one-to-one message.
|
||||
- `PUBLIC_GROUP`: A message to the public group.
|
||||
- `PRIVATE_GROUP`: A message to the private group.
|
||||
|
||||
## Clock vs Timestamp and Message Ordering
|
||||
|
||||
If a user sends a new message before receiving messages that were sent while
|
||||
they were offline, the new message should be displayed last in the chat.
|
||||
|
||||
The Status client speculates that its Lamport timestamp will beat the current
|
||||
chat timestamp, using the format: `clock = max({timestamp}, chat_clock + 1)`.
|
||||
|
||||
This satisfies the Lamport requirement: if `a -> b`, then `T(a) < T(b)`.
|
||||
|
||||
- `timestamp` **MUST** be Unix time in milliseconds when the node creates the
|
||||
message. This field **SHOULD** not be relied upon for message ordering.
|
||||
- `clock` **SHOULD** be calculated using Lamport timestamps, based on the last
|
||||
received message's clock value: `max(timeNowInMs, last-message-clock-value + 1)`.
|
||||
|
||||
Messages with a clock greater than 120 seconds over the Whisper/Waku timestamp
|
||||
**SHOULD** be discarded to prevent malicious clock increases. Messages with a
|
||||
clock less than 120 seconds under the Whisper/Waku timestamp may indicate
|
||||
attempted insertion into chat history.
|
||||
|
||||
The node uses the clock value for message ordering. The distributed nature of
|
||||
the system produces casual ordering, which may lead to counter-intuitive results
|
||||
in edge cases. For example, when a user joins a public chat and sends a message
|
||||
before receiving previous messages, their message clock might be lower, causing
|
||||
the message to appear in the past once historical messages are fetched.
|
||||
|
||||
## Chats
|
||||
|
||||
A chat is a structure used to organize messages, helping to display messages
|
||||
from a single recipient or group of recipients.
|
||||
|
||||
All incoming messages are matched against a chat. The table below shows how to
|
||||
calculate a chat ID for each message type:
|
||||
|
||||
| Message Type | Chat ID Calculation | Direction | Comment |
|
||||
| -------------- | ------------------------------------------- | -------------- | --------- |
|
||||
| PUBLIC_GROUP | Chat ID equals public channel name | Incoming/Outgoing | |
|
||||
| ONE_TO_ONE | Hex-encode the recipient's public key as chat ID | Outgoing | |
|
||||
| user-message | Hex-encode the message sender’s public key as chat ID | Incoming | If no match, node may discard or create a new chat |
|
||||
| PRIVATE_GROUP | Use chat ID from the message | Incoming/Outgoing | If no match, discard message |
|
||||
|
||||
## Contact Update
|
||||
|
||||
`ContactUpdate` notifies peers that the user has been added as a contact or
|
||||
that user information has changed.
|
||||
|
||||
```protobuf
|
||||
message ContactUpdate {
|
||||
uint64 clock = 1;
|
||||
string ens_name = 2;
|
||||
string profile_image = 3;
|
||||
}
|
||||
```
|
||||
|
||||
Payload Fields
|
||||
|
||||
| Field | Name | Type | Description |
|
||||
| ----------- | ------------- | ------- | ------------------------------------------------ |
|
||||
| 1 | clock | uint64 | Clock value of the chat with the user |
|
||||
| 2 | ens_name | string | ENS name if set |
|
||||
| 3 | profile_image | string | Base64-encoded profile picture of the user |
|
||||
|
||||
A client **SHOULD** send a `ContactUpdate` when:
|
||||
|
||||
- The `ens_name` has changed.
|
||||
- The profile image is edited.
|
||||
|
||||
Clients **SHOULD** also periodically send `ContactUpdate` messages to contacts.
|
||||
The Status official client sends these updates every 48 hours.
|
||||
|
||||
## SyncInstallationContact
|
||||
|
||||
The node uses `SyncInstallationContact` messages to synchronize contacts across
|
||||
devices in a best-effort manner.
|
||||
|
||||
```protobuf
|
||||
message SyncInstallationContact {
|
||||
uint64 clock = 1;
|
||||
string id = 2;
|
||||
string profile_image = 3;
|
||||
string ens_name = 4;
|
||||
uint64 last_updated = 5;
|
||||
repeated string system_tags = 6;
|
||||
}
|
||||
```
|
||||
|
||||
Payload Fields
|
||||
|
||||
| Field | Name | Type | Description |
|
||||
| -------------- | ------------- | ------------- | ----------------------------------------- |
|
||||
| 1 | clock | uint64 | Clock value of the chat |
|
||||
| 2 | id | string | ID of the contact synced |
|
||||
| 3 | profile_image | string | Base64-encoded profile picture of the user |
|
||||
| 4 | ens_name | string | ENS name of the contact |
|
||||
| 5 | system_tags | array[string] | System tags like ":contact/added" |
|
||||
|
||||
## SyncInstallationPublicChat
|
||||
|
||||
The node uses `SyncInstallationPublicChat` to synchronize public chats across
|
||||
devices.
|
||||
|
||||
```protobuf
|
||||
message SyncInstallationPublicChat {
|
||||
uint64 clock = 1;
|
||||
string id = 2;
|
||||
}
|
||||
```
|
||||
|
||||
Payload Fields
|
||||
|
||||
| Field | Name | Type | Description |
|
||||
| ----------- | ------ | ------ | --------------------- |
|
||||
| 1 | clock | uint64 | Clock value of the chat |
|
||||
| 2 | id | string | ID of the chat synced |
|
||||
|
||||
## PairInstallation
|
||||
|
||||
The node uses `PairInstallation` messages to propagate information about a
|
||||
device to its paired devices.
|
||||
|
||||
```protobuf
|
||||
message PairInstallation {
|
||||
uint64 clock = 1;
|
||||
string installation_id = 2;
|
||||
string device_type = 3;
|
||||
string name = 4;
|
||||
}
|
||||
```
|
||||
|
||||
Payload Fields
|
||||
|
||||
| Field | Name | Type | Description |
|
||||
| ----------------- | -------------- | ------ | ---------------------------------------------- |
|
||||
| 1 | clock | uint64 | Clock value of the chat |
|
||||
| 2 | installation_id | string | Randomly generated ID that identifies this device |
|
||||
| 3 | device_type | string | OS of the device (iOS, Android, or desktop) |
|
||||
| 4 | name | string | Self-assigned name of the device |
|
||||
|
||||
## MembershipUpdateMessage and MembershipUpdateEvent
|
||||
|
||||
`MembershipUpdateEvent` propagates information about group membership changes
|
||||
in a group chat. The details are covered in the [Group Chats specs](https://rfc.vac.dev/status/deprecated/group-chat.md).
|
||||
|
||||
## Upgradability
|
||||
|
||||
There are two ways to upgrade the protocol without breaking compatibility:
|
||||
|
||||
- A node always supports accretion.
|
||||
- A node does not support deletion of existing fields or messages,
|
||||
which might break compatibility.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
-
|
||||
|
||||
## Changelog
|
||||
|
||||
### Version 0.3
|
||||
|
||||
- **Released**: May 22, 2020
|
||||
- **Changes**: Added language to include Waku in all relevant places.
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
||||
172
status/deprecated/push-notification-server.md
Normal file
172
status/deprecated/push-notification-server.md
Normal file
@@ -0,0 +1,172 @@
|
||||
---
|
||||
title: PUSH-NOTIFICATION-SERVER
|
||||
name: Push notification server
|
||||
status: deprecated
|
||||
description: Status provides a set of Push notification services that can be used to achieve this functionality.
|
||||
editor: Filip Dimitrijevic <filip@status.im>
|
||||
contributors:
|
||||
- Andrea Maria Piana <andreap@status.im>
|
||||
---
|
||||
|
||||
## Reason
|
||||
|
||||
Push notifications for iOS and some Android devices rely on centralized services
|
||||
like APN for iOS or Firebase.
|
||||
Android devices lacking foreground service support
|
||||
or killing such services frequently benefit from these services.
|
||||
iOS only allows certain app types, like VoIP,
|
||||
to keep connections open in the background,
|
||||
which Status does not qualify for.
|
||||
Background execution on iOS is limited and unreliable for push notifications.
|
||||
|
||||
Since a privacy-preserving implementation is challenging,
|
||||
Status enables push notifications only as an opt-in feature, disabled by default.
|
||||
|
||||
## Requirements
|
||||
|
||||
The party releasing the app **must** possess an Apple Push Notification certificate
|
||||
and maintain a publicly accessible Gorush server for notifications.
|
||||
Status runs its own Gorush instance.
|
||||
|
||||
### Components
|
||||
|
||||
- **Gorush Instance**: Publicly available for push notifications only.
|
||||
- **Push Notification Server**: Handles client registration for push notifications.
|
||||
- **Registering Client**: A Status client that registers to receive notifications.
|
||||
- **Sending Client**: A Status client that initiates notifications.
|
||||
|
||||
## Registering with Push Notification Service
|
||||
|
||||
Clients **may** register with one or more push notification services.
|
||||
They must send a PNR (Push Notification Registration) message
|
||||
to a partitioned topic for their public key,
|
||||
encrypted with AES-GCM using a Diffie–Hellman key derived from client
|
||||
and server identities.
|
||||
The registration payload must follow this format:
|
||||
|
||||
```protobuf
|
||||
message PushNotificationRegistration {
|
||||
enum TokenType {
|
||||
UNKNOWN_TOKEN_TYPE = 0;
|
||||
APN_TOKEN = 1;
|
||||
FIREBASE_TOKEN = 2;
|
||||
}
|
||||
TokenType token_type = 1;
|
||||
string device_token = 2;
|
||||
string installation_id = 3;
|
||||
string access_token = 4;
|
||||
bool enabled = 5;
|
||||
uint64 version = 6;
|
||||
repeated bytes allowed_key_list = 7;
|
||||
repeated bytes blocked_chat_list = 8;
|
||||
bool unregister = 9;
|
||||
bytes grant = 10;
|
||||
bool allow_from_contacts_only = 11;
|
||||
string apn_topic = 12;
|
||||
bool block_mentions = 13;
|
||||
repeated bytes allowed_mentions_chat_list = 14;
|
||||
}
|
||||
```
|
||||
|
||||
### Server Requirements
|
||||
|
||||
A push notification server **must** validate the registration
|
||||
and respond with errors if the message is malformed,
|
||||
has unsupported tokens, or contains empty fields.
|
||||
Successful responses contain `success = true`.
|
||||
|
||||
## Query Topic
|
||||
|
||||
On successful registration, the server listens on a topic derived from:
|
||||
|
||||
0XHexEncode(Shake256(CompressedClientPublicKey))
|
||||
|
||||
## Server Grant
|
||||
|
||||
Push notification servers demonstrate authorization via a grant specific
|
||||
to the client-server pair:
|
||||
|
||||
```Signature(Keccak256(CompressedClientPublicKey . CompressedServerPublicKey .
|
||||
AccessToken), ClientPrivateKey)```
|
||||
|
||||
## Re-registering and Unregistering
|
||||
|
||||
Clients **should** re-register when tokens change, ensuring the latest
|
||||
PushNotificationRegistration is available and advertising changes.
|
||||
To unregister, clients set `unregister = true` in the request.
|
||||
|
||||
## Advertising Push Notification Servers
|
||||
|
||||
Clients **should** periodically advertise the push notification services
|
||||
they registered with for each device. This is done using `PushNotificationQueryInfo`
|
||||
messages wrapped in `ApplicationMetadataMessage`.
|
||||
|
||||
## Discovering Push Notification Servers
|
||||
|
||||
Clients discover push notification servers by listening to contact code topics
|
||||
or querying mail servers for the latest contact codes.
|
||||
|
||||
## Querying the Push Notification Server
|
||||
|
||||
If a token is absent in advertisements, clients **should** query the server directly:
|
||||
|
||||
```protobuf
|
||||
message PushNotificationQuery {
|
||||
repeated bytes public_keys = 1;
|
||||
}
|
||||
```
|
||||
|
||||
### Query Response
|
||||
|
||||
Servers respond with a `PushNotificationQueryResponse` message containing:
|
||||
|
||||
```protobuf
|
||||
message PushNotificationQueryInfo {
|
||||
string access_token = 1;
|
||||
string installation_id = 2;
|
||||
bytes public_key = 3;
|
||||
repeated bytes allowed_user_list = 4;
|
||||
bytes grant = 5;
|
||||
uint64 version = 6;
|
||||
bytes server_public_key = 7;
|
||||
}
|
||||
```
|
||||
|
||||
Clients verify grants to ensure authorized push notifications.
|
||||
|
||||
## Sending a Push Notification
|
||||
|
||||
Clients send a notification targeting specific installation IDs, using this format:
|
||||
|
||||
```protobuf
|
||||
message PushNotification {
|
||||
string access_token = 1;
|
||||
string chat_id = 2;
|
||||
bytes public_key = 3;
|
||||
string installation_id = 4;
|
||||
bytes message = 5;
|
||||
PushNotificationType type = 6;
|
||||
bytes author = 7;
|
||||
}
|
||||
```
|
||||
|
||||
Servers validate the `access_token` and, if valid, send the notification
|
||||
to Gorush, following Gorush’s data structure.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
For standard operations, registering with a push notification service discloses:
|
||||
|
||||
1. Chat key
|
||||
2. Devices receiving notifications
|
||||
3. Any filtered chat IDs
|
||||
|
||||
In anonymous mode, chat keys are not disclosed.
|
||||
|
||||
## Changelog
|
||||
|
||||
**Version 0.1**: Initial Release
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
||||
239
status/deprecated/secure-transport.md
Normal file
239
status/deprecated/secure-transport.md
Normal file
@@ -0,0 +1,239 @@
|
||||
---
|
||||
title: SECURE-TRANSPORT
|
||||
name: Secure Transport
|
||||
status: deprecated
|
||||
description: This document describes how Status provides a secure channel between two peers, providing confidentiality, integrity, authenticity, and forward secrecy.
|
||||
editor: Filip Dimitrijevic <filip@status.im>
|
||||
contributors:
|
||||
- Andrea Maria Piana <andreap@status.im>
|
||||
- Corey Petty <corey@status.im>
|
||||
- Dean Eigenmann <dean@status.im>
|
||||
- Oskar Thorén <oskar@status.im>
|
||||
- Pedro Pombeiro <pedro@status.im>
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
This document describes how Status provides a secure channel between two peers,
|
||||
providing confidentiality, integrity, authenticity, and forward secrecy.
|
||||
It is transport-agnostic and works over asynchronous networks.
|
||||
|
||||
It builds on the X3DH and Double Ratchet specifications,
|
||||
with adaptations to operate in a decentralized environment.
|
||||
|
||||
## Introduction
|
||||
|
||||
This document describes how nodes establish a secure channel
|
||||
and how various conversational security properties are achieved.
|
||||
|
||||
## Definitions
|
||||
|
||||
Perfect Forward Secrecy provides assurances that session keys remain secure
|
||||
even if private keys are later compromised.
|
||||
Secret channel describes a communication channel
|
||||
where the Double Ratchet algorithm is in use.
|
||||
|
||||
## Design Requirements
|
||||
|
||||
- **Confidentiality**: The adversary should not be able to learn what data
|
||||
is being exchanged between two Status clients.
|
||||
- **Authenticity**: The adversary should not cause either endpoint
|
||||
of a Status 1:1 chat to accept data from any third party
|
||||
as though it came from the other endpoint.
|
||||
- **Forward Secrecy**: The adversary should not learn what data was exchanged
|
||||
between two Status clients, even if later the adversary compromises
|
||||
one or both of the endpoint devices.
|
||||
- **Integrity**: The adversary should not cause either endpoint
|
||||
of a Status 1:1 chat to accept tampered data.
|
||||
|
||||
These properties are ensured by [Signal’s Double Ratchet](https://signal.org/docs/specifications/doubleratchet/).
|
||||
|
||||
## Conventions
|
||||
|
||||
Types used in this specification are defined using Protobuf.
|
||||
|
||||
## Transport Layer
|
||||
|
||||
Whisper and Waku serve as the transport layers for the Status chat protocol.
|
||||
|
||||
## User Flow for 1-to-1 Communications
|
||||
|
||||
### Account Generation
|
||||
|
||||
See [Account specification](https://rfc.vac.dev/status/deprecated/account.md).
|
||||
|
||||
### Account Recovery
|
||||
|
||||
If Alice recovers her account, Double Ratchet state information
|
||||
is unavailable, so she can no longer decrypt messages
|
||||
received from existing contacts.
|
||||
|
||||
If a Whisper/Waku topic message fails to decrypt,
|
||||
the node replies with the current bundle, notifying the other end of the device.
|
||||
Subsequent communications will use this new bundle.
|
||||
|
||||
### Messaging
|
||||
|
||||
All 1:1 and group chat messaging in Status uses end-to-end encryption
|
||||
for privacy and security. Public chat messages are publicly readable,
|
||||
as there’s no permission model for public chat participants.
|
||||
|
||||
This document covers only 1:1 and private group chat.
|
||||
Private group chat reduces to 1:1 chat,
|
||||
since each pair-wise participant has a secure channel.
|
||||
|
||||
### End-to-End Encryption
|
||||
|
||||
End-to-end encryption (E2EE) occurs between two clients.
|
||||
The main cryptographic protocol is a Status implementation
|
||||
of the Double Ratchet protocol, derived from Off-the-Record protocol.
|
||||
The transport protocol encrypts the message payload
|
||||
using Whisper/Waku (see Transport Layer),
|
||||
and symmetric key encryption.
|
||||
|
||||
Status uses prekeys (via X3DH) to operate in an asynchronous environment,
|
||||
so two parties need not be online simultaneously
|
||||
to initiate an encrypted conversation.
|
||||
|
||||
### Prekeys
|
||||
|
||||
Each client generates key material stored locally:
|
||||
|
||||
- **Identity keypair** based on secp256k1 - IK
|
||||
- **Signed prekey** based on secp256k1 - SPK
|
||||
- **Prekey signature** - Sig(IK, Encode(SPK))
|
||||
|
||||
More details are in the X3DH Prekey bundle creation section of ACCOUNT.
|
||||
|
||||
Prekey bundles can be extracted from any user’s messages
|
||||
or found by searching their topic, `{IK}-contact-code`.
|
||||
|
||||
### Bundle Retrieval
|
||||
|
||||
X3DH enables client apps to create and share a bundle of prekeys
|
||||
(X3DH bundle) requested by other interlocutors to start a conversation.
|
||||
Status chat clients must achieve this without a centralized server.
|
||||
|
||||
Considered approaches, from most to least convenient:
|
||||
|
||||
- **Contact codes**
|
||||
- **Public and one-to-one chats**
|
||||
- **QR codes**
|
||||
- **ENS record**
|
||||
- **Decentralized storage** (e.g., Swarm, IPFS)
|
||||
|
||||
Currently, only public and one-to-one messages and Whisper/Waku
|
||||
are used to exchange bundles.
|
||||
QR codes or ENS records do not update to delete used keys,
|
||||
so the bundle rotates every 24 hours, propagated by the app.
|
||||
|
||||
### 1:1 Chat Contact Request
|
||||
|
||||
The initial negotiation for a 1:1 chat involves two phases:
|
||||
|
||||
1. **Identity verification** (e.g., QR code, Identicon matching).
|
||||
A QR code serves both identity verification and bundle retrieval.
|
||||
2. **Asynchronous initial key exchange**, using X3DH.
|
||||
|
||||
See ACCOUNT for account generation and trust establishment.
|
||||
|
||||
### Initial Key Exchange Flow (X3DH)
|
||||
|
||||
Section 3 of X3DH protocol covers initial key exchange flow,
|
||||
with some additional context:
|
||||
|
||||
- Users’ identity keys IK_A and IK_B are their respective Status chat keys.
|
||||
- One-time prekey OPK_B is not used in a decentralized environment.
|
||||
- Nodes serve Bundles in a decentralized way, as described in bundle retrieval.
|
||||
|
||||
Alice retrieves Bob’s prekey bundle, which contains:
|
||||
|
||||
protobuf
|
||||
|
||||
```protobuf
|
||||
message Bundle {
|
||||
bytes identity = 1;
|
||||
map<string,SignedPreKey> signed_pre_keys = 2;
|
||||
bytes signature = 4;
|
||||
int64 timestamp = 5;
|
||||
}
|
||||
```
|
||||
|
||||
Fields:
|
||||
|
||||
- **identity**: Identity key IK_B
|
||||
- **signed_pre_keys**: Signed prekey SPK_B for each device, indexed by `installation-id`
|
||||
- **signature**: Prekey signature `Sig(IK_B, Encode(SPK_B))`
|
||||
- **timestamp**: When the bundle was created locally
|
||||
|
||||
## Double Ratchet
|
||||
|
||||
After establishing the initial shared secret SK through X3DH,
|
||||
it seeds a Double Ratchet exchange between Alice and Bob.
|
||||
Refer to the Double Ratchet spec for more details.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
These considerations apply as per section 4 of the X3DH spec
|
||||
and section 6 of the Double Ratchet spec, with some additions.
|
||||
|
||||
### Session Management
|
||||
|
||||
A node identifies a peer by:
|
||||
|
||||
1. An `installation-id` generated upon creating a new account in Status
|
||||
2. Their identity Whisper/Waku key
|
||||
|
||||
#### Initialization
|
||||
|
||||
A node initializes a session after a successful X3DH exchange.
|
||||
Subsequent messages use the established session until re-keying is needed.
|
||||
|
||||
#### Concurrent Sessions
|
||||
|
||||
If two concurrent sessions are created, the one with the symmetric key
|
||||
first in byte order **SHOULD** be used, marking the other expired.
|
||||
|
||||
#### Re-keying
|
||||
|
||||
On receiving a higher version bundle from a peer,
|
||||
the old bundle **SHOULD** be marked as expired,
|
||||
and a new session **SHOULD** be established on the next sent message.
|
||||
|
||||
### Multi-Device Support
|
||||
|
||||
Multi-device support is challenging without a central place for device info.
|
||||
Nodes propagate multi-device info using x3dh bundles,
|
||||
including information about paired devices and the sending device.
|
||||
|
||||
### Pairing
|
||||
|
||||
When adding a new account in Status, a new `installation-id` is generated.
|
||||
Devices should be paired as soon as possible.
|
||||
Once paired, contacts are notified of the new device,
|
||||
and it is included in further communications.
|
||||
|
||||
### Sending Messages to a Paired Group
|
||||
|
||||
When sending a message, the peer sends it to other `installation-id`s seen.
|
||||
Messages are sent using pairwise encryption, including the sender’s devices.
|
||||
|
||||
Account Recovery
|
||||
|
||||
Account recovery is similar to adding a new device and handled in the same way.
|
||||
|
||||
### Partitioned Devices
|
||||
|
||||
If a device receives a message not targeted to its `installation-id`,
|
||||
it sends an empty message with bundle information to include it in future communication.
|
||||
|
||||
## Changelog
|
||||
|
||||
### Version 0.3
|
||||
|
||||
- Released May 22, 2020
|
||||
- Added language to include Waku in all relevant places
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
||||
151
status/deprecated/waku-mailserver.md
Normal file
151
status/deprecated/waku-mailserver.md
Normal file
@@ -0,0 +1,151 @@
|
||||
---
|
||||
title: WAKU-MAILSERVER
|
||||
name: Waku Mailserver
|
||||
status: deprecated
|
||||
description: Waku Mailserver is a specification that allows messages to be stored permanently and to allow the stored messages to be delivered to requesting client nodes, regardless if the messages are not available in the network due to the message TTL expiring.
|
||||
editor: Filip Dimitrijevic <filip@status.im>
|
||||
contributors:
|
||||
- Adam Babik <adam@status.im>
|
||||
- Oskar Thorén <oskar@status.im>
|
||||
- Samuel Hawksby-Robinson <samuel@status.im>
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
Being mostly offline is an intrinsic property of mobile clients.
|
||||
They need to save network transfer and battery consumption to avoid high costs
|
||||
or constant charging.
|
||||
Waku protocol, however, is an online protocol.
|
||||
Messages are available in the Waku network only for a short period,
|
||||
calculated in seconds.
|
||||
|
||||
Waku Mailserver is a specification that allows messages to be stored permanently
|
||||
and to be delivered to requesting client nodes,
|
||||
even if the messages are no longer available in the network due to the TTL expiring.
|
||||
|
||||
## Mailserver
|
||||
|
||||
From a network perspective, a Mailserver is similar to any other Waku node.
|
||||
The only difference is that a Mailserver can archive messages
|
||||
and deliver them to its peers on-demand.
|
||||
|
||||
It’s important to note that a Mailserver only handles requests from its direct peers,
|
||||
and packets exchanged between a Mailserver and a peer are p2p messages.
|
||||
|
||||
### Archiving Messages
|
||||
|
||||
A node that wants to provide Mailserver functionality
|
||||
**MUST** store envelopes from incoming message packets (Waku packet-code 0x01).
|
||||
The envelopes can be stored in any format,
|
||||
but **MUST** be serialized and deserialized to the Waku envelope format.
|
||||
|
||||
A Mailserver **SHOULD** store envelopes for all topics to be useful for any peer;
|
||||
however, for specific cases, it **MAY** store envelopes for only a subset of topics.
|
||||
|
||||
### Requesting Messages
|
||||
|
||||
To request historic messages, a node **MUST** send a P2P Request packet (0x7e)
|
||||
to a peer with Mailserver functionality.
|
||||
This packet requires one argument, which **MUST** be a Waku envelope.
|
||||
|
||||
In the Waku envelope’s payload section,
|
||||
there **MUST** be RLP-encoded information about the request details:
|
||||
|
||||
```plaintext
|
||||
[ Lower, Upper, Bloom, Limit, Cursor ]
|
||||
```
|
||||
|
||||
- **Lower**: 4-byte unsigned integer (UNIX time in seconds;
|
||||
oldest requested envelope’s creation time).
|
||||
- **Upper**: 4-byte unsigned integer (UNIX time in seconds;
|
||||
newest requested envelope’s creation time).
|
||||
- **Bloom**: 64-byte array of Waku topics encoded in a bloom filter to filter envelopes.
|
||||
- **Limit**: 4-byte unsigned integer limiting the number of returned envelopes.
|
||||
- **Cursor**: array from the previous request (optional).
|
||||
|
||||
The **Cursor** field **SHOULD** be filled if the number of envelopes between **Lower**
|
||||
and **Upper** exceeds the **Limit**.
|
||||
The requester **SHOULD NOT** use a **Cursor** from one Mailserver
|
||||
in a request to another because the format or result **MAY** differ.
|
||||
|
||||
The envelope **MUST** be encrypted with a symmetric key agreed upon by the requester
|
||||
and the Mailserver.
|
||||
|
||||
### Receiving Historic Messages
|
||||
|
||||
Historic messages **MUST** be sent to a peer
|
||||
as a packet with a P2P Message code (0x7f), followed by an array of Waku envelopes.
|
||||
|
||||
To receive historic messages from a Mailserver,
|
||||
a node **MUST** trust the selected Mailserver,
|
||||
allowing it to send packets with the P2P Message code.
|
||||
By default, the node discards such packets.
|
||||
|
||||
Received envelopes **MUST** pass through the Waku envelope pipelines
|
||||
so that registered filters can pick them up and pass them to subscribers.
|
||||
|
||||
To confirm that all messages have been sent by a Mailserver,
|
||||
the requester **SHOULD** handle the P2P Request Complete code (0x7d),
|
||||
followed by the following parameters:
|
||||
|
||||
```plaintext
|
||||
[ RequestID, LastEnvelopeHash, Cursor ]
|
||||
```
|
||||
|
||||
- **RequestID**: 32-byte array with a Keccak-256 hash of the envelope
|
||||
containing the original request.
|
||||
- **LastEnvelopeHash**: 32-byte array with a Keccak-256 hash of the last sent envelope
|
||||
for the request.
|
||||
- **Cursor**: array from the previous request (optional).
|
||||
|
||||
If **Cursor** is not empty, it means not all messages were sent
|
||||
due to the **Limit** in the request.
|
||||
The requester **MAY** send more requests with the **Cursor** field
|
||||
to receive the rest.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Confidentiality
|
||||
|
||||
The node encrypts all Waku envelopes, so a Mailserver node cannot inspect their contents.
|
||||
|
||||
### Altruistic and Centralized Operator Risk
|
||||
|
||||
For usefulness, a Mailserver **SHOULD** be online most of the time.
|
||||
Users either need technical skills to run their own node,
|
||||
or rely on others to run it for them.
|
||||
|
||||
Currently, one of Status’s legal entities provides Mailservers altruistically,
|
||||
but this is suboptimal for decentralization, continuity, and risk.
|
||||
Research is ongoing to improve this system.
|
||||
|
||||
A Status client **SHOULD** allow customizable Mailserver selection.
|
||||
|
||||
### Privacy Concerns
|
||||
|
||||
To use a Mailserver, a node must connect to it directly, add it as a peer,
|
||||
and mark it as trusted.
|
||||
This allows the Mailserver to send direct p2p messages to the node
|
||||
instead of broadcasting them.
|
||||
The Mailserver can access the bloom filter of the topics the user is interested in,
|
||||
along with metadata like IP address and online status.
|
||||
|
||||
### Denial-of-Service
|
||||
|
||||
Since a Mailserver delivers expired envelopes and has a direct TCP connection
|
||||
with the recipient, the recipient is vulnerable to DoS attacks from a malicious
|
||||
Mailserver node.
|
||||
|
||||
## Changelog
|
||||
|
||||
### Version 0.1
|
||||
|
||||
- Released May 22, 2020
|
||||
- Created document
|
||||
- Forked from whisper-mailserver
|
||||
- Updated to keep Mailserver terminology consistent
|
||||
- Replaced Whisper references with Waku
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
||||
194
status/deprecated/waku-usage.md
Normal file
194
status/deprecated/waku-usage.md
Normal file
@@ -0,0 +1,194 @@
|
||||
---
|
||||
title: WAKU-USAGE
|
||||
name: Waku Usage
|
||||
status: deprecated
|
||||
description: Status uses Waku to provide privacy-preserving routing and messaging on top of devP2P.
|
||||
editor: Filip Dimitrijevic <filip@status.im>
|
||||
contributors:
|
||||
- Adam Babik <adam@status.im>
|
||||
- Corey Petty <corey@status.im>
|
||||
- Oskar Thorén <oskar@status.im>
|
||||
- Samuel Hawksby-Robinson <samuel@status.im>
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
Status uses Waku for privacy-preserving routing and messaging on top of devP2P.
|
||||
Waku uses topics to partition its messages,
|
||||
which are leveraged for all chat capabilities.
|
||||
In public chats, the channel name maps directly to its Waku topic,
|
||||
allowing anyone to listen on a single channel.
|
||||
|
||||
Since anyone can receive Waku envelopes,
|
||||
it relies on the ability to decrypt messages to identify the correct recipient.
|
||||
Status nodes do not rely on this property,
|
||||
and implement another secure transport layer on top of Whisper.
|
||||
|
||||
## Reason
|
||||
|
||||
To provide routing, metadata protection, topic-based multicasting,
|
||||
and basic encryption properties that support asynchronous chat.
|
||||
|
||||
## Terminology
|
||||
|
||||
- **Waku node**: an Ethereum node with Waku V1 enabled.
|
||||
- **Waku network**: a group of Waku nodes connected over the internet.
|
||||
- **Message**: a decrypted Waku message.
|
||||
- **Offline message**: an archived envelope.
|
||||
- **Envelope**: an encrypted message with metadata like topic and Time-To-Live.
|
||||
|
||||
## Waku Packets
|
||||
|
||||
| Packet Name | Code | References |
|
||||
|---------------------|------|---------------------------------|
|
||||
| Status | 0 | Status, WAKU-1 |
|
||||
| Messages | 1 | WAKU-1 |
|
||||
| Batch Ack | 11 | Undocumented. Marked for Deprecation |
|
||||
| Message Response | 12 | WAKU-1 |
|
||||
| Status Update | 22 | WAKU-1 |
|
||||
| P2P Request Complete| 125 | WAKU-MAILSERVER |
|
||||
| P2P Request | 126 | WAKU-MAILSERVER, WAKU-1 |
|
||||
| P2P Messages | 127 | WAKU-MAILSERVER, WAKU-1 |
|
||||
|
||||
## Waku Node Configuration
|
||||
|
||||
A Waku node must be properly configured to receive messages from Status clients.
|
||||
|
||||
Nodes use Waku’s Proof Of Work (PoW) algorithm to deter denial of service
|
||||
and spam/flood attacks.
|
||||
Since Status’ main client is mobile,
|
||||
this can lead to battery drain and poor app performance.
|
||||
All clients **MUST** use the following settings:
|
||||
|
||||
- Proof-of-work requirement not exceeding 0.002 for payloads under 50,000 bytes.
|
||||
- Proof-of-work requirement not exceeding 0.000002 for payloads of 50,000 bytes
|
||||
or more.
|
||||
- Time-to-live no lower than 10 seconds.
|
||||
|
||||
### Status Handshake
|
||||
|
||||
The handshake is an RLP-encoded packet sent to a newly connected peer.
|
||||
It **MUST** start with a Status Code (0x00), followed by items:
|
||||
|
||||
```plaintext
|
||||
[
|
||||
[ pow-requirement-key pow-requirement ]
|
||||
[ bloom-filter-key bloom-filter ]
|
||||
[ light-node-key light-node ]
|
||||
[ confirmations-enabled-key confirmations-enabled ]
|
||||
[ rate-limits-key rate-limits ]
|
||||
[ topic-interest-key topic-interest ]
|
||||
]
|
||||
```
|
||||
|
||||
| Option Name | Key | Type | Description | References |
|
||||
|-----------------------|-------|--------|-----------------------------------------------------|---------------------------------|
|
||||
| pow-requirement | 0x00 | uint64 | minimum PoW accepted by the peer | WAKU-1#pow-requirement |
|
||||
| bloom-filter | 0x01 | []byte | bloom filter of Waku topic accepted by the peer | WAKU-1#bloom-filter |
|
||||
| light-node | 0x02 | bool | when true, the peer won’t forward envelopes | WAKU-1#light-node |
|
||||
| confirmations-enabled | 0x03 | bool | when true, peer sends message confirmations | WAKU-1#confirmations-enabled |
|
||||
| rate-limits | 0x04 | | Rate limiting details | WAKU-1#rate-limits |
|
||||
| topic-interest | 0x05 | array | Specifies interest in envelopes with certain topics | WAKU-1#topic-interest |
|
||||
|
||||
## Rate Limiting
|
||||
|
||||
Each node **SHOULD** define its own rate limits as a basic DoS protection,
|
||||
applying these limits on IPs, peer IDs, and envelope topics.
|
||||
|
||||
Nodes **MAY** whitelist certain IPs or peer IDs,
|
||||
meaning they are not subject to rate limits.
|
||||
If a peer exceeds rate limits, the connection **MAY** be dropped.
|
||||
|
||||
Nodes **SHOULD** broadcast their rate limits to peers using packet code 0x00
|
||||
or 0x22. This information is RLP-encoded as:
|
||||
|
||||
```plaintext
|
||||
[ IP limits, PeerID limits, Topic limits ]
|
||||
```
|
||||
|
||||
## Keys Management
|
||||
|
||||
The protocol requires keys (symmetric or asymmetric) for:
|
||||
|
||||
- Signing & verifying messages (asymmetric key)
|
||||
- Encrypting & decrypting messages (symmetric or asymmetric key)
|
||||
|
||||
Keys are stored in memory and required at all times for message processing.
|
||||
PFS key management is described in SECURE-TRANSPORT.
|
||||
|
||||
## Contact Code Topic
|
||||
|
||||
Nodes use the contact code topic for discovering X3DH bundles
|
||||
so the first message can be PFS-encrypted.
|
||||
Each user periodically publishes to this topic.
|
||||
If user A wants to contact user B,
|
||||
they **SHOULD** search for their bundle on this contact code topic.
|
||||
|
||||
## Partitioned Topic
|
||||
|
||||
Waku is a broadcast-based protocol,
|
||||
where a unique topic per conversation would be inefficient and impact privacy.
|
||||
Instead, nodes use partitioned topics to balance efficiency and privacy.
|
||||
|
||||
Nodes use 5,000 partitioned topics, generated as follows:
|
||||
|
||||
```plaintext
|
||||
partitionTopic := "contact-discovery-" + strconv.FormatInt(partition.Int64(), 10)
|
||||
```
|
||||
|
||||
## Public Chats
|
||||
|
||||
Public chats **MUST** use a topic derived from a public chat name
|
||||
with the following algorithm:
|
||||
|
||||
```plaintext
|
||||
var hash []byte = keccak256(name)
|
||||
```
|
||||
|
||||
## Group Chat Topic
|
||||
|
||||
Group chats do not have a dedicated topic.
|
||||
Messages (including membership updates) are sent
|
||||
as one-to-one messages to multiple recipients.
|
||||
|
||||
## Negotiated Topic
|
||||
|
||||
For one-to-one messages, the client **MUST** listen to a negotiated topic,
|
||||
computed by generating a Diffie-Hellman key exchange
|
||||
and taking the first four bytes of the SHA3-256 key generated.
|
||||
|
||||
## Message Encryption
|
||||
|
||||
The Waku protocol requires message encryption,
|
||||
even though an encryption layer is specified above the transport layer.
|
||||
Public and group messages use symmetric encryption,
|
||||
creating the key from a channel name string.
|
||||
|
||||
## Message Confirmations
|
||||
|
||||
Messages may fail to be delivered for various reasons.
|
||||
Message confirmations notify the sender that the message
|
||||
has been received by direct peers.
|
||||
|
||||
The sender **MAY** send confirmations using Batch Acknowledge (0x0b)
|
||||
or Message Response (0x0c) packets.
|
||||
|
||||
## Waku V1 Extensions
|
||||
|
||||
### Request Historic Messages
|
||||
|
||||
To request historic messages, a node **MUST** send a P2P Request (0x7e)
|
||||
to a trusted Mailserver peer. The request does not await a response.
|
||||
|
||||
## Changelog
|
||||
|
||||
### Version 0.1
|
||||
|
||||
- Released May 22, 2020
|
||||
- Created document
|
||||
- Forked from whisper-usage
|
||||
- Updated terminology to keep Mailserver term consistent
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
||||
149
status/deprecated/whisper-mailserver.md
Normal file
149
status/deprecated/whisper-mailserver.md
Normal file
@@ -0,0 +1,149 @@
|
||||
---
|
||||
title: WHISPER-MAILSERVER
|
||||
name: Whisper mailserver
|
||||
status: deprecated
|
||||
description: Whisper Mailserver is a Whisper extension that allows to store messages permanently and deliver them to the clients even though they are already not available in the network and expired.
|
||||
editor: Filip Dimitrijevic <filip@status.im>
|
||||
contributors:
|
||||
- Adam Babik <adam@status.im>
|
||||
- Oskar Thorén <oskar@status.im>
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
Being mostly offline is an intrinsic property of mobile clients.
|
||||
They need to save network transfer and battery consumption
|
||||
to avoid spending too much money or constant charging.
|
||||
Whisper protocol, on the other hand, is an online protocol.
|
||||
Messages are available in the Whisper network only for a short period of time,
|
||||
calculated in seconds.
|
||||
|
||||
Whisper Mailserver is a Whisper extension
|
||||
that allows storing messages permanently
|
||||
and delivering them to clients
|
||||
even after they are no longer available in the network and have expired.
|
||||
|
||||
## Mailserver
|
||||
|
||||
From the network perspective, a Mailserver is just like any other Whisper node,
|
||||
with the difference being that it has the capability of archiving messages
|
||||
and delivering them to its peers on-demand.
|
||||
|
||||
It is important to note that a Mailserver only handles requests
|
||||
from its direct peers,
|
||||
and exchanged packets between Mailserver and a peer are p2p messages.
|
||||
|
||||
## Archiving Messages
|
||||
|
||||
A node providing Mailserver functionality **MUST** store envelopes
|
||||
from incoming message packets (Whisper packet-code 0x01).
|
||||
The envelopes can be stored in any format,
|
||||
but they **MUST** be serialized and deserialized to the Whisper envelope format.
|
||||
|
||||
A Mailserver **SHOULD** store envelopes for all topics to be useful for any peer,
|
||||
but for specific use cases, it **MAY** store envelopes for a subset of topics.
|
||||
|
||||
## Requesting Messages
|
||||
|
||||
To request historic messages, a node **MUST** send a packet P2P Request (0x7e)
|
||||
to a peer providing Mailserver functionality.
|
||||
This packet requires one argument, which **MUST** be a Whisper envelope.
|
||||
|
||||
In the Whisper envelope’s payload section,
|
||||
there **MUST** be RLP-encoded information about the request details:
|
||||
|
||||
- **Lower**: 4-byte unsigned integer (UNIX time in seconds;
|
||||
oldest requested envelope’s creation time)
|
||||
- **Upper**: 4-byte unsigned integer (UNIX time in seconds;
|
||||
newest requested envelope’s creation time)
|
||||
- **Bloom**: 64-byte array of Whisper topics encoded in a bloom filter
|
||||
to filter envelopes
|
||||
- **Limit**: 4-byte unsigned integer limiting the number of returned envelopes
|
||||
- **Cursor**: an array of a cursor returned from the previous request (optional)
|
||||
|
||||
The Cursor field **SHOULD** be filled
|
||||
if the number of envelopes between Lower and Upper exceeds Limit,
|
||||
so the requester can send another request with the obtained Cursor value.
|
||||
The content of the Cursor depends on the implementation.
|
||||
The requester **SHOULD NOT** use a Cursor from one Mailserver
|
||||
in a request to another, as the format or result **MAY** differ.
|
||||
|
||||
The envelope **MUST** be encrypted
|
||||
with a symmetric key agreed between the requester and Mailserver.
|
||||
|
||||
## Receiving Historic Messages
|
||||
|
||||
Historic messages **MUST** be sent to a peer as a packet with a P2P Message code
|
||||
(0x7f), followed by an array of Whisper envelopes.
|
||||
This is incompatible with the original Whisper spec (EIP-627),
|
||||
which allows only a single envelope,
|
||||
but an array of envelopes is much more performant.
|
||||
To stay compatible with EIP-627,
|
||||
a peer receiving historic messages **MUST** handle both cases.
|
||||
|
||||
To receive historic messages from a Mailserver,
|
||||
a node **MUST** trust the selected Mailserver,
|
||||
which is allowed to send packets with the P2P Message code.
|
||||
By default, the node discards such packets.
|
||||
|
||||
Received envelopes **MUST** pass through the Whisper envelope pipelines
|
||||
so that registered filters can pick them up and pass them to subscribers.
|
||||
|
||||
To know that all messages have been sent by the Mailserver,
|
||||
the requester **SHOULD** handle P2P Request Complete code (0x7d),
|
||||
followed by these parameters:
|
||||
|
||||
- **RequestID**: 32-byte array with a Keccak-256 hash of the envelope
|
||||
containing the original request
|
||||
- **LastEnvelopeHash**: 32-byte array with a Keccak-256 hash of the last sent
|
||||
envelope for the request
|
||||
- **Cursor**: an array of a cursor returned from the previous request (optional)
|
||||
|
||||
If Cursor is not empty, not all messages were sent due to the request’s Limit.
|
||||
One or more consecutive requests **MAY** be sent with the Cursor field filled
|
||||
to receive the remaining messages.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Confidentiality
|
||||
|
||||
The node encrypts all Whisper envelopes.
|
||||
A Mailserver node cannot inspect their contents.
|
||||
|
||||
### Altruistic and Centralized Operator Risk
|
||||
|
||||
To be useful, a Mailserver **SHOULD** be online most of the time,
|
||||
meaning users must be somewhat tech-savvy to run their own node
|
||||
or rely on someone else.
|
||||
|
||||
Currently, one of Status’s legal entities provides Mailservers altruistically,
|
||||
but this is suboptimal from a decentralization, continuance,
|
||||
and risk perspective.
|
||||
Developing a better system is ongoing research.
|
||||
|
||||
A Status client **SHOULD** allow the Mailserver selection to be customizable.
|
||||
|
||||
### Privacy Concerns
|
||||
|
||||
To use a Mailserver, a node connects directly to it, i.e.,
|
||||
adds the Mailserver as its peer and marks it as trusted.
|
||||
This gives the Mailserver access
|
||||
to the bloom filter of topics the user is interested in,
|
||||
as well as metadata like the user’s IP address when online.
|
||||
|
||||
### Denial-of-Service (DoS)
|
||||
|
||||
A Mailserver delivers expired envelopes
|
||||
and has a direct TCP connection with the recipient,
|
||||
leaving the recipient vulnerable to DoS attacks from a malicious Mailserver.
|
||||
|
||||
## Changelog
|
||||
|
||||
### Version 0.3
|
||||
|
||||
- Released May 22, 2020
|
||||
- Change to keep Mailserver term consistent
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
||||
196
status/deprecated/whisper-usage.md
Normal file
196
status/deprecated/whisper-usage.md
Normal file
@@ -0,0 +1,196 @@
|
||||
---
|
||||
title: WHISPER-USAGE
|
||||
name: Whisper Usage
|
||||
status: deprecated
|
||||
description: Status uses Whisper to provide privacy-preserving routing and messaging on top of devP2P.
|
||||
editor: Filip Dimitrijevic <filip@status.im>
|
||||
contributors:
|
||||
- Adam Babik <adam@status.im>
|
||||
- Andrea Piana <andreap@status.im>
|
||||
- Corey Petty <corey@status.im>
|
||||
- Oskar Thorén <oskar@status.im>
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
Status uses Whisper to provide privacy-preserving routing
|
||||
and messaging on top of devP2P.
|
||||
Whisper uses topics to partition its messages,
|
||||
which supports chat capabilities.
|
||||
For public chats, the channel name maps to its Whisper topic,
|
||||
allowing anyone to listen on a single channel.
|
||||
|
||||
Whisper relies on decryption to identify recipients,
|
||||
but Status nodes add another secure transport layer,
|
||||
and Whisper extensions allow for offline messaging.
|
||||
|
||||
## Reason
|
||||
|
||||
Provide routing, metadata protection, topic-based multicasting,
|
||||
and basic encryption for asynchronous chat.
|
||||
|
||||
## Terminology
|
||||
|
||||
- **Whisper node**: An Ethereum node with Whisper V6 enabled.
|
||||
- **Whisper network**: A group of Whisper nodes connected through the internet.
|
||||
- **Message**: A decrypted Whisper message.
|
||||
- **Offline message**: An archived envelope.
|
||||
- **Envelope**: An encrypted message with metadata like topic and TTL.
|
||||
|
||||
## Whisper Packets
|
||||
|
||||
| Packet Name | Code | EIP-627 | References |
|
||||
|---------------------|------|---------|--------------------|
|
||||
| Status | 0 | ✔ | Handshake |
|
||||
| Messages | 1 | ✔ | EIP-627 |
|
||||
| PoW Requirement | 2 | ✔ | EIP-627 |
|
||||
| Bloom Filter | 3 | ✔ | EIP-627 |
|
||||
| Batch Ack | 11 | 𝘅 | Undocumented |
|
||||
| Message Response | 12 | 𝘅 | Undocumented |
|
||||
| P2P Sync Request | 123 | 𝘅 | Undocumented |
|
||||
| P2P Sync Response | 124 | 𝘅 | Undocumented |
|
||||
| P2P Request | 126 | ✔ | WHISPER-MAILSERVER |
|
||||
| P2P Messages | 127 | ✔/𝘅 | WHISPER-MAILSERVER |
|
||||
|
||||
## Whisper Node Configuration
|
||||
|
||||
A Whisper node must be configured to receive messages from Status clients.
|
||||
Whisper’s PoW deters denial-of-service attacks,
|
||||
and all clients **MUST** use:
|
||||
|
||||
- PoW requirement ≤ 0.00001
|
||||
- TTL ≥ 10 seconds
|
||||
- Payloads < 50000 bytes must use PoW target ≥ 0.002 for backward compatibility
|
||||
|
||||
## Handshake
|
||||
|
||||
Handshake is an RLP-encoded packet sent to a newly connected peer.
|
||||
It **MUST** start with Status Code (0x00)
|
||||
and follow up with:
|
||||
|
||||
```plaintext
|
||||
[ protocolVersion, PoW, bloom, isLightNode, confirmationsEnabled, rateLimits ]
|
||||
```
|
||||
|
||||
Optional fields like `bloom`, `isLightNode`,
|
||||
and other fields **MUST** be sequential if included to avoid ambiguity.
|
||||
|
||||
## Rate Limiting
|
||||
|
||||
Nodes **SHOULD** define rate limits for IPs, peer IDs,
|
||||
and topics to prevent DoS attacks,
|
||||
and rate limits **MAY** be advertised with packet code (0x14).
|
||||
|
||||
```plaintext
|
||||
[ IP limits, PeerID limits, Topic limits ]
|
||||
```
|
||||
|
||||
Nodes **SHOULD** respect peer rate limits
|
||||
and throttle packets as needed.
|
||||
|
||||
## Keys Management
|
||||
|
||||
Keys are required for signing/verifying (asymmetric)
|
||||
and encrypting/decrypting (asymmetric or symmetric) messages.
|
||||
Keys for PFS are described in SECURE-TRANSPORT.
|
||||
|
||||
## Contact Code Topic
|
||||
|
||||
Nodes use the contact code topic for X3DH bundle discovery,
|
||||
and the topic is derived as follows:
|
||||
|
||||
```plaintext
|
||||
contactCode := "0x" + hexEncode(activePublicKey) + "-contact-code"
|
||||
```
|
||||
|
||||
## Partitioned Topic
|
||||
|
||||
Partitioned topics balance efficiency and privacy.
|
||||
Nodes use 5000 topics, generated as follows:
|
||||
|
||||
```plaintext
|
||||
partitionTopic := "contact-discovery-" + strconv.FormatInt(partition.Int64(), 10)
|
||||
```
|
||||
|
||||
## Public Chats
|
||||
|
||||
Public chat topics derive from the chat name as follows:
|
||||
|
||||
```plaintext
|
||||
var hash []byte = keccak256(name)
|
||||
```
|
||||
|
||||
## Group Chat Topic
|
||||
|
||||
Group chats do not use a dedicated topic;
|
||||
messages are sent one-to-one.
|
||||
|
||||
## Negotiated Topic
|
||||
|
||||
One-to-one messages use a negotiated topic based on a Diffie-Hellman key
|
||||
exchange,
|
||||
and the topic is derived as follows:
|
||||
|
||||
```go
|
||||
sharedKey, err := ecies.ImportECDSA(myPrivateKey).GenerateShared(
|
||||
ecies.ImportECDSAPublic(theirPublicKey),
|
||||
16,
|
||||
16,
|
||||
)
|
||||
```
|
||||
|
||||
## Flow
|
||||
|
||||
To message client B,
|
||||
client A **SHOULD**:
|
||||
|
||||
1. Listen to B’s Contact Code Topic for bundle info.
|
||||
2. Send a message on B’s partitioned topic.
|
||||
3. Listen to the Negotiated Topic between A & B.
|
||||
|
||||
## Message Encryption
|
||||
|
||||
Whisper requires encryption,
|
||||
and public/group messages use symmetric encryption
|
||||
with a channel-based key,
|
||||
while one-to-one messages use asymmetric encryption.
|
||||
|
||||
## Message Confirmations
|
||||
|
||||
Message confirmations inform a node that its message has been seen by peers,
|
||||
and confirmations **MAY** be sent using Batch Ack (0x0b)
|
||||
or Message Response (0x0c) packets.
|
||||
|
||||
## Whisper V6 Extensions
|
||||
|
||||
### Request Historic Messages
|
||||
|
||||
Requests historic messages from a Mailserver,
|
||||
and the Mailserver **MUST** be a direct, trusted peer.
|
||||
|
||||
### shhext_requestMessages
|
||||
|
||||
Parameters:
|
||||
|
||||
- **Object**: The message request object
|
||||
- **mailServerPeer**: Mailserver’s enode address.
|
||||
- **from**: Lower time bound (default 24 hours back).
|
||||
- **to**: Upper time bound (default now).
|
||||
- **limit**: Message limit (default no limit).
|
||||
- **cursor**: Used for pagination.
|
||||
- **topics**: Hex-encoded message topics.
|
||||
- **symKeyID**: Symmetric key ID for Mailserver authentication.
|
||||
|
||||
## Changelog
|
||||
|
||||
### 0.3
|
||||
|
||||
- Updated minimum PoW to 0.00001
|
||||
|
||||
### 0.2
|
||||
|
||||
- Document created
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
||||
Reference in New Issue
Block a user