Compare commits

...

15 Commits

Author SHA1 Message Date
Cofson
6108ca6f4b fixes according to review 2025-02-19 16:05:18 +01:00
Cofson
20a9d653c7 change of status 2025-02-15 03:29:07 +01:00
Cofson
58e0b67013 changes according to comments from Jimmy 2025-02-15 03:20:42 +01:00
Cofson
87568c6107 Update status/deprecated/5/secure-transport.md
Co-authored-by: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
2025-02-14 20:28:26 +01:00
Cofson
d5b99bce11 Update status/deprecated/5/secure-transport.md
Co-authored-by: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
2025-02-14 20:28:19 +01:00
Cofson
371fb4fb0e Update status/deprecated/11/waku-mailserver.md
Co-authored-by: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
2025-02-14 20:27:55 +01:00
Cofson
d469d90702 Update status/deprecated/10/waku-usage.md
Co-authored-by: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
2025-02-14 20:27:47 +01:00
Cofson
a2ec64c91d Fixes according to review 2024-11-25 04:21:37 +01:00
Cofson
e5590e56c2 all changes 2024-11-04 07:28:52 +01:00
Cofson
45a35c3a02 Rest of the RFCs from the specs.status.im page 2024-11-04 07:21:59 +01:00
Cofson
814a40d72a payloads 2024-10-01 15:08:00 +02:00
Cofson
cf00dffc8f Update payloads.md 2024-09-27 05:22:49 +02:00
Cofson
41fb2db7ca fixes and changes to the status specs
fixes and changes
2024-09-27 04:39:32 +02:00
Cofson
a4c23879d2 Update account-address.md 2024-09-27 03:44:39 +02:00
Cofson
8cfb5e5b19 Create account-address.md 2024-09-27 03:42:24 +02:00
17 changed files with 3132 additions and 0 deletions

View 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 Statuss 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 wont 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 wont 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**
Statuss 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
View 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 doesnt 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 whats 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 (dont 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.

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

View 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 channels 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 messages 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 messages sender derives from the messages 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
View 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.

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

View 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.
Theres 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.

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

View 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 accounts database uses the `encryption-public-key` as a password.
---
## Copyright
Copyright and related rights waived via CC0.

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

View 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 senders 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.

View 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 DiffieHellman 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 Gorushs 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.

View 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 [Signals 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 theres 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 users 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 Bobs 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 senders 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.

View 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.
Its 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 envelopes 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 envelopes creation time).
- **Upper**: 4-byte unsigned integer (UNIX time in seconds;
newest requested envelopes 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 Statuss 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.

View 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 Wakus 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 wont 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.

View 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 envelopes payload section,
there **MUST** be RLP-encoded information about the request details:
- **Lower**: 4-byte unsigned integer (UNIX time in seconds;
oldest requested envelopes creation time)
- **Upper**: 4-byte unsigned integer (UNIX time in seconds;
newest requested envelopes 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 requests 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 Statuss 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 users 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.

View 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.
Whispers 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 Bs Contact Code Topic for bundle info.
2. Send a message on Bs 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**: Mailservers 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.