Merge branch 'master' into master-android

This commit is contained in:
Evgeny Poberezkin
2025-12-22 22:20:36 +00:00
18 changed files with 528 additions and 139 deletions
+8 -1
View File
@@ -147,6 +147,12 @@ jobs:
with:
swap-size-gb: 30
- name: Get UID and GID
id: ids
run: |
echo "uid=$(id -u)" >> $GITHUB_OUTPUT
echo "gid=$(id -g)" >> $GITHUB_OUTPUT
# Otherwise we run out of disk space with Docker build
- name: Free disk space
if: matrix.should_run == true
@@ -177,6 +183,8 @@ jobs:
build-args: |
TAG=${{ matrix.os }}
GHC=${{ matrix.ghc }}
USER_UID=${{ steps.ids.outputs.uid }}
USER_GID=${{ steps.ids.outputs.gid }}
# Docker needs these flags for AppImage build:
# --device /dev/fuse
@@ -209,7 +217,6 @@ jobs:
if: matrix.should_run == true
shell: docker exec -t builder sh -eu {0}
run: |
chmod -R 777 dist-newstyle ~/.cabal && git config --global --add safe.directory '*'
cabal clean
cabal update
cabal build -j --enable-tests
+30 -7
View File
@@ -13,6 +13,10 @@ ARG JAVA_HASH_ARM64=2b460859b681757b33a7591b6238ecaf51569d05d2684984e5f0a89c6514
ENV TZ=Etc/UTC \
DEBIAN_FRONTEND=noninteractive
ARG USER_UID=1000
ARG USER_GID=1000
ARG USER_NAME=builder
# Install curl, git and and simplex-chat dependencies
RUN apt-get update && \
apt-get install -y curl \
@@ -38,6 +42,11 @@ RUN apt-get update && \
file \
appstream \
gpg \
zipalign \
apksigner \
python3 \
python3-venv \
xz-utils \
unzip &&\
ln -s /bin/fusermount /bin/fusermount3 || :
@@ -67,6 +76,12 @@ RUN export JAVA_FILENAME='java-corretto.deb' \
echo "Checksum mismatch" && exit 1; \
fi
RUN userdel -r ubuntu || :
RUN groupadd -g ${USER_GID} ${USER_NAME} || :; useradd -u ${USER_UID} -g ${USER_GID} --create-home --shell /bin/bash ${USER_NAME} || :
RUN mkdir /nix /out && chown ${USER_NAME}:${USER_NAME} /nix /out
USER ${USER_NAME}
WORKDIR /home/${USER_NAME}
# Specify bootstrap Haskell versions
ENV BOOTSTRAP_HASKELL_GHC_VERSION=${GHC}
ENV BOOTSTRAP_HASKELL_CABAL_VERSION=${CABAL}
@@ -78,8 +93,10 @@ ENV BOOTSTRAP_HASKELL_INSTALL_NO_STACK_HOOK=true
# Install ghcup
RUN curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_NONINTERACTIVE=1 sh
# Setup basic env variables (required)
ENV HOME="/home/${USER_NAME}" USER="${USER_NAME}"
# Adjust PATH
ENV PATH="/root/.cabal/bin:/root/.ghcup/bin:$PATH"
ENV PATH="$HOME/.cabal/bin:$HOME/.ghcup/bin:$PATH"
# Set both as default
RUN ghcup set ghc "${GHC}" && \
@@ -90,8 +107,8 @@ RUN ghcup set ghc "${GHC}" && \
#=====================
ARG SDK_VERSION=13114758
ENV SDK_VERSION=$SDK_VERSION \
ANDROID_HOME=/root
ENV SDK_VERSION="$SDK_VERSION" \
ANDROID_HOME="$HOME"
RUN curl -L -o tools.zip "https://dl.google.com/android/repository/commandlinetools-linux-${SDK_VERSION}_latest.zip" && \
unzip tools.zip && rm tools.zip && \
@@ -101,11 +118,17 @@ RUN curl -L -o tools.zip "https://dl.google.com/android/repository/commandlineto
ENV PATH="$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/cmdline-tools/tools/bin"
# https://askubuntu.com/questions/885658/android-sdk-repositories-cfg-could-not-be-loaded
RUN mkdir -p ~/.android ~/.gradle && \
touch ~/.android/repositories.cfg && \
echo 'org.gradle.console=plain' > ~/.gradle/gradle.properties &&\
RUN mkdir -p "$HOME/.android" "$HOME/.gradle" && \
touch "$HOME/.android/repositories.cfg" && \
echo 'org.gradle.console=plain' > "$HOME/.gradle/gradle.properties" &&\
yes | sdkmanager --licenses >/dev/null
ENV PATH=$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools
ENV PATH="$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools"
# Android reproducibility scripts
RUN python3 -m venv "$HOME/.venv"
RUN "$HOME/.venv/bin/pip" install apksigcopier repro-apk
ENV PATH="$HOME/.venv/bin:$PATH"
WORKDIR /project
@@ -10,6 +10,7 @@ import SwiftUI
struct ChatHelp: View {
@EnvironmentObject var chatModel: ChatModel
@State private var showNewChatSheet = false
let dismissSettingsSheet: DismissAction
var body: some View {
@@ -38,7 +39,7 @@ struct ChatHelp: View {
HStack(spacing: 8) {
Text("Tap button ")
NewChatMenuButton()
NewChatMenuButton(showNewChatSheet: $showNewChatSheet)
Text("above, then choose:")
}
@@ -140,6 +140,7 @@ struct ChatListView: View {
@StateObject private var connectProgressManager = ConnectProgressManager.shared
@EnvironmentObject var theme: AppTheme
@Binding var activeUserPickerSheet: UserPickerSheet?
@State private var showNewChatSheet = false
@State private var searchMode = false
@FocusState private var searchFocussed
@State private var searchText = ""
@@ -189,6 +190,10 @@ struct ChatListView: View {
onDismiss: { chatModel.laRequest = nil },
content: { UserPickerSheetView(sheet: $0) }
)
.appSheet(isPresented: $showNewChatSheet) {
NewChatSheet()
.environment(\EnvironmentValues.refresh as! WritableKeyPath<EnvironmentValues, RefreshAction?>, nil)
}
.onChange(of: activeUserPickerSheet) {
if $0 != nil {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
@@ -331,7 +336,7 @@ struct ChatListView: View {
@ViewBuilder var trailingToolbarItem: some View {
switch chatModel.chatRunning {
case .some(true): NewChatMenuButton()
case .some(true): NewChatMenuButton(showNewChatSheet: $showNewChatSheet)
case .some(false): chatStoppedIcon()
case .none: EmptyView()
}
@@ -12,7 +12,7 @@ import SimpleXChat
struct NewChatMenuButton: View {
// do not use chatModel here because it prevents showing AddGroupMembersView after group creation and QR code after link creation on iOS 16
// @EnvironmentObject var chatModel: ChatModel
@State private var showNewChatSheet = false
@Binding var showNewChatSheet: Bool
@State private var alert: SomeAlert? = nil
var body: some View {
@@ -25,10 +25,6 @@ struct NewChatMenuButton: View {
.scaledToFit()
.frame(width: 24, height: 24)
}
.appSheet(isPresented: $showNewChatSheet) {
NewChatSheet()
.environment(\EnvironmentValues.refresh as! WritableKeyPath<EnvironmentValues, RefreshAction?>, nil)
}
.alert(item: $alert) { a in
return a.alert
}
@@ -471,5 +467,5 @@ struct DeletedChats: View {
}
#Preview {
NewChatMenuButton()
NewChatMenuButton(showNewChatSheet: Binding.constant(false))
}
@@ -2616,7 +2616,7 @@ object ChatController {
if (chatModel.chatsContext.hasChat(rhId, r.chat_.id)) {
chatModel.chatsContext.updateChatInfo(rhId, r.chat_.chatInfo)
} else {
chatModel.chatsContext.addChat(r.chat_)
chatModel.chatsContext.addChat(r.chat_.copy(remoteHostId = rhId))
}
} else {
val cInfo = ChatInfo.ContactRequest(contactRequest)
+1 -1
View File
@@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd
source-repository-package
type: git
location: https://github.com/simplex-chat/simplexmq.git
tag: 2ca440dd2dfd494ff2bb40cc0409d08069d02e04
tag: 77ac4521908da6bddf0529e28de494d090cd1807
source-repository-package
type: git
@@ -0,0 +1,144 @@
# Community Vouchers FAQ
This is an unabridged version of FAQ previously published at https://simplex.chat/vouchers.
- [Why Community Vouchers?](#why-community-vouchers)
- [Free Tier?](#free-tier)
- [How Will Vouchers Work?](#how-will-vouchers-work)
- [Will self-hosted servers still be supported by SimpleX network?](#will-self-hosted-servers-still-be-supported-by-simplex-network)
- [What problems Community Vouchers solve that other payment methods can't?](#what-problems-community-vouchers-solve-that-other-payment-methods-cant)
- [How is it possible to provide privacy on public blockchain?](#how-is-it-possible-to-provide-privacy-on-public-blockchain)
- [Will Community Vouchers be pre-sold via private or public sale?](#will-community-vouchers-be-pre-sold-via-private-or-public-sale)
- [Who will sell vouchers?](#who-will-sell-vouchers)
- [How the server operator revenue share is determined?](#how-the-server-operator-revenue-share-is-determined)
- [Who will control and upgrade smart contracts?](#who-will-control-and-upgrade-smart-contracts)
- [Will I be able to sell or transfer Community Vouchers to other people?](#will-i-be-able-to-sell-or-transfer-community-vouchers-to-other-people)
- [Why Not Existing Crypto?](#why-not-existing-crypto)
- [Why build on Ethereum blockchain?](#why-build-on-ethereum-blockchain)
- [Have you considered other blockchains?](#have-you-considered-other-blockchains)
- [Which token specification do you plan to use?](#which-token-specification-do-you-plan-to-use)
- [If you build on another blockchain, how the NFT will be used to provide access?](#if-you-build-on-another-blockchain-how-the-nft-will-be-used-to-provide-access)
### Why Community Vouchers?
<img src="/img/design_3/community_vouchers_light.jpg" width="38%" class="float-to-right dark:hidden">
<img src="/img/design_3/community_vouchers_dark.jpg" width="38%" class="float-to-right hidden dark:block">
To cover server costs securely and privately.
With "free" centralized platforms:
- you lose security and privacy, because your data is used for advertising and sold.
- they de-platform inconvenient users, often based on frivolous complaints.
- you don't own all rights to your content.
Paying for server capacity may be cheaper than "free" platforms. Our estimates based on the current costs are $5-10/month for 5,000 active message receivers (could be up to 50,000 listed community members) with 5-10 GB of files/media archive. These estimates are preliminary and may change.
### Free Tier?
It will be determined after testing. Preliminarily, we expect up to 1,000 active message receivers (can be up to 10,000 listed members) and 500 MB storage to be available for free groups.
"Active message recipient" in this model is a group member who periodically connects to the network, and receives group messages. Members who are listed but don't open the group for some time, for example two weeks, will stop receiving all group messages even when they are connected to the network. This is an evolving design that will balance security for group members and owners, to avoid inflated expenses, and to present realistic membership statistics to the group owners and to prospective members.
Private messaging with contacts and in private groups within "fair use" limits that we apply today will remain free:
- there can be up to 128 undelivered messages per destination,
- the undelivered messages are stored up to 21 days,
- files up to 1 GB can be sent for free,
- files are available for download for up to 2 days.
Larger limits may be offered in paid tier, but it is not planned initially &mdash; the focus of Community Vouchers is to create a commercial model for communities.
### How Will Vouchers Work?
Buy via app (like phone top-ups), with unused capacity shown in the app. An important design goal is to make Community Vouchers available to people who don't use any cryptocurrencies.
Testnet is likely to use hashed IDs for privacy and on-chain payments, to validate the pricing and economic model. Zero-knowledge proofs and in-app payments will be added by the time production network is launched.
### Will self-hosted servers still be supported by SimpleX network?
Yes, absolutely. Not only will the apps continue to support self-hosted servers, but we will improve it. We see network decentralization and server portability as very important, and while we need to develop a robust commercial model for the servers, we still need community-hosted servers to function, with all people using a single network:
- users who use self-hosted servers will be able to join groups that use pre-configured servers or Community Vouchers.
- users who use pre-configured servers will be able to join groups that are run on free community-hosted servers, same as today.
- you will be able to create new server operators (collections of messaging and file servers operated by one entity), so that the features currently available only for preset servers will be available to all servers very soon, and all servers that you and your community members want to use can be added to the app by scanning a QR code.
### What problems Community Vouchers solve that other payment methods can't?
Community Vouchers implemented via smart contracts on blockchain solve these problems:
- unlinkability of the voucher purchase and usage - to confirm ownership smart contracts will use zero-knowledge proofs, rather than visible transfers between blockchain addresses. While any blockchain observers may see that a given address purchased a voucher, they will not see how vouchers are used.
- server operators cannot fail to provide infrastructure &mdash; the funds will be locked in a smart contract until it is provided.
- codify the agreement about how revenue is shared between server operator and the network, so that it depends not on trust, but on cryptography.
### How is it possible to provide privacy on public blockchain?
In the same way it is possible to provide private communications on the public Internet, as SimpleX network does.
Our commitment to users' privacy and security remains as strong as ever, and we plan to bring the practical expertise of building private communication protocols over the last 5 years to how we develop the technology for the blockchain.
While specific designs are in early stages, here are some of the principles that we will follow to ensure privacy:
- each voucher purchase will be associated with a new blockchain address. There will be no per-user addresses, as wallets use. So the cornerstone of SimpleX network design - no user profile IDs - will be followed for blockchain development as well.
- all operations on blockchain will be supported by network servers that will run full blockchain nodes. For important requests, such as name resolution, the clients will use 2 or 3 independent servers, to ensure protection from MITM attacks.
- blockchain operations will be proxied, in the same way as it happens with private message routing.
We will be publishing the whitepaper about this design. It will provide an unprecedented level of security and privacy for blockchain applications, irrespective of which chain we choose to use.
### Will Community Vouchers be pre-sold via private or public sale?
There will be no Community Vouchers pre-sold or in any other way made available to the team, or to investors or to the public.
Any blockchain token that is pre-sold to raise funds to develop technology is not a utility token, regardless of how it's named &mdash; it becomes an investment contract that passes [Howey test](https://www.investopedia.com/terms/h/howey-test.asp).
This is not what we are doing. Community Vouchers are restricted utility tokens, not an investment contract. They will be only issued on demand to people who want to pay for network servers, at a fixed price.
### Who will sell vouchers?
Initially, Community Vouchers will be sold via a smart contract in exchange for some other tradeable tokens, most likely stablecoins. We don't plan any token emission, or any public or private pre-sales. And we won't have access to the funds from voucher sales &mdash; they will be locked in a smart contract, and only released once servers have provided capacity to the users, with the funds shared between server operators and the SimpleX network, with operators receiving up to 60%, depending on trust evaluation. The SimpleX network funds will be managed by smart contracts, and will be used for governance and development as defined by the contracts. Their price will be fixed based on server costs, with the exact economic model developed during the testing phase.
### How the server operator revenue share is determined?
It will be based on the goal that servers must provide both reliability and security to the users. Security in any multi-node network depends on users' ability to choose independent servers that are provided by different entities, and the apps are already programmed not just to use different servers for the message delivery path, but to use servers of different operators. Even though currently there are only 2 preset operators &mdash; SimpleX Chat and Flux &mdash; and all servers added to the app by the user are considered a third operator, it substantially improves privacy and security.
In the future, the operators that confirmed their identity to the network will receive a much higher revenue share than anonymous ones. We believe that for users to be private and secure, operators must be known, and must accept legally binding terms of operation, same as preset operators do today.
The other two factors that will affect "trust evaluation" will be how long the operator was available on the network and servers' availability uptime. Similar to how we monitor the uptime of our servers, the network will monitor the uptime of all servers, and it will affect the revenue share.
We don't have an exact model for revenue sharing yet; it will be determined during testing and will evolve based on feedback from users and server operators.
### Who will control and upgrade smart contracts?
Community Vouchers will require several smart contracts for their functioning. During testing and development, SimpleX Chat will maintain and update all contracts. Once the network is ready for production, some critical contracts (e.g., those that control the funds) will be immutable, requiring a lot of testing and a security audit, and some less critical contracts will still be upgradeable based on a consensus model (e.g., multisig or voting).
It is always a journey from knowing that something is possible to knowing how exactly it will be done, and we are at the early stage of knowing it is possible. Specific designs would evolve, based on the input from legal and blockchain experts, and from the community &mdash; as everything else we develop for SimpleX network.
### Will I be able to sell or transfer Community Vouchers to other people?
Possibly, but with limits on the number of transactions and the time of holding.
Community Vouchers are designed with a single purpose &mdash; to facilitate payments for servers' capacity in a way that protects users' security. Smart contracts implementing them will restrict or completely prohibit trading. The specific parameters will be determined during design evolution and testing.
### Why Not Existing Crypto?
Existing cryptocurrencies do not allow the implementation of the required model for Community Vouchers. The price of cryptocurrencies is determined speculatively, and not based on costs. The fact that they can be freely traded and transferred exposes existing cryptocurrencies and tokens to financial regulations.
The existing cryptocurrencies such as XMR, BTC and some others will be accepted as payment for Community Vouchers, via bridges, but they cannot be used in the foundation of the system, because they are not as flexible as smart contracts, and cannot directly support the model we are developing.
### Why build on Ethereum blockchain?
Many people dislike Ethereum for its high energy usage and high transaction costs in the past. Also, blockchain transactions cannot provide privacy, can they? Why not use Monero (XMR) instead?
This was our assessment as well in the past. But the last three years changed it, addressing energy usage and transaction costs, and we've seen the growth of several L2 Ethereum blockchains. What made us decide that EVM-based blockchain is the best choice for the current stage is the planned rollout of zkEVM in 2025 with native support for zero-knowledge proofs.
[Our early ideas about Community Vouchers](https://github.com/simplex-chat/simplex-chat/blob/master/docs/rfcs/2024-04-26-commercial-model.md) and [the most recent design](https://github.com/simplex-chat/simplex-chat/blob/master/docs/rfcs/2025-10-23-vouchers.md) rely on zero-knowledge proofs, and as it will be natively supported, EVM blockchains provide a much better foundation to build Community Vouchers than building them from scratch &mdash; there is no need to re-invent solutions to problems that are already solved.
### Have you considered other blockchains?
We are actively considering which blockchain to build on. Ethereum ecosystem is the most widely adopted, and has very mature systems and tools, and it appears sufficient, but it has its downsides, as does everything. So we are not yet committed to Ethereum.
### Which token specification do you plan to use?
Even though these are not freely tradable tokens, we will likely make them compatible with [ERC20 token specification](https://eips.ethereum.org/EIPS/eip-20). It is very simple, one of the earliest, and the most adopted standard on EVM blockchain. It defines tokens, but they don't have to be freely tradeable &mdash; the specification allows any extensions and restrictions implemented on top of it.
Using this specification would make Community Vouchers partially compatible with wallets and chain explorers, making testing, development, and early adoption easier.
### If you build on another blockchain, how the NFT will be used to provide access?
We can take into account the list of addresses that hold NFTs and provide access to testnet on any blockchain via a cryptographic signature. That is the reason the NFT is deployed on Ethereum mainnet and not on some of L2 chains. We don't yet know at this stage which L2 testnet will be used.
+5 -2
View File
@@ -102,6 +102,7 @@ build() {
sed -i.bak 's/jniLibs.useLegacyPackaging =.*/jniLibs.useLegacyPackaging = true/' "$folder/apps/multiplatform/android/build.gradle.kts"
sed -i.bak '/android {/a lint {abortOnError = false}' "$folder/apps/multiplatform/android/build.gradle.kts"
sed -i.bak '/tasks/Q' "$folder/apps/multiplatform/android/build.gradle.kts"
sed -i.bak "s/android.version_code=.*/android.version_code=${vercode}/" "$folder/apps/multiplatform/gradle.properties"
for arch in $arches; do
if [ "$arch" = "armv7a" ]; then
@@ -169,8 +170,10 @@ pre() {
done
shift $(( $OPTIND - 1 ))
commit="${1:-HEAD}"
vercode="${1}"
commit="${2:-HEAD}"
}
main() {
+1 -1
View File
@@ -41,7 +41,7 @@ for ORIG_NAME in "${ORIG_NAMES[@]}"; do
if [ $case_insensitive -eq 1 ]; then
# For case-insensitive file systems
list_of_files=$(unzip -l "$ORIG_NAME_COPY" | grep res/ | sed -e "s|.*res/|res/|" | sort -z)
list_of_files=$(unzip -l "$ORIG_NAME_COPY" | grep res/ | sed -e "s|.*res/|res/|" | sort)
for file in $list_of_files; do
unzip -o -q -d apk "$ORIG_NAME_COPY" "$file"
(
+1 -1
View File
@@ -1,5 +1,5 @@
{
"https://github.com/simplex-chat/simplexmq.git"."2ca440dd2dfd494ff2bb40cc0409d08069d02e04" = "1jc1a9vh59l0l5hxlin1spv03afrgmmiml5xnakhbi4rk67n0wwr";
"https://github.com/simplex-chat/simplexmq.git"."77ac4521908da6bddf0529e28de494d090cd1807" = "1sbl5si9pns9zxn3fip43icfjh1kgv35axwwba2paaiigk669wyx";
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
"https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d";
"https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl";
+251
View File
@@ -0,0 +1,251 @@
#!/usr/bin/env sh
set -eu
SIMPLEX_KEY='3C:52:C4:FD:3C:AD:1C:07:C9:B0:0A:70:80:E3:58:FA:B9:FE:FC:B8:AF:5A:EC:14:77:65:F1:6D:0F:21:AD:85'
REPO_NAME="simplex-chat"
REPO="https://github.com/simplex-chat/${REPO_NAME}"
IMAGE_NAME='sx-local-android'
CONTAINER_NAME='sx-builder-android'
DOCKER_PATH_PROJECT='/project'
DOCKER_PATH_VERIFY='/verify'
export DOCKER_BUILDKIT=1
SIMPLEX_REPO='simplex-chat/simplex-chat'
CMDS="curl git docker"
INIT_DIR="$PWD"
TEMPDIR="$(mktemp -d)"
ARCHES="${ARCHES:-aarch64 armv7a}"
COLOR_CYAN="\033[36m"
COLOR_RESET="\033[0m"
SUFFIX_BUILT='built'
SUFFIX_DOWNLOADED='downloaded'
SUFFIX_BUILT_WITH_SIGNATURE='built-with-downloaded-signature'
cleanup() {
rm -rf -- "${TEMPDIR}"
docker rm --force "${CONTAINER_NAME}" 2>/dev/null || :
docker image rm "${IMAGE_NAME}" 2>/dev/null || :
}
trap 'cleanup' EXIT INT
check() {
commands="$1"
set +u
for i in $commands; do
if ! command -v "$i" > /dev/null 2>&1; then
commands_failed="$i $commands_failed"
fi
done
if [ -n "$commands_failed" ]; then
commands_failed=${commands_failed% *}
printf "%s is not found in your \$PATH. Please install them and re-run the script.\n" "$commands_failed"
exit 1
fi
set -u
}
download_apk() {
tag="$1"
filename="$2"
file_out="$3"
curl -L "${REPO}/releases/download/${tag}/${filename}" -o "$file_out"
}
setup_git() {
workdir="$1"
name="$2"
git -C "$workdir" clone "${REPO}.git" "$name"
}
checkout_git() {
git_dir="$1"
tag="$2"
git -C "$git_dir" reset --hard
git -C "$git_dir" clean -dfx
git -C "$git_dir" checkout "$tag"
}
check_apk() {
apk_name="$1"
expected="$2"
actual=$(docker exec "${CONTAINER_NAME}" apksigner verify --print-certs "${DOCKER_PATH_VERIFY}/${apk_name}" | grep 'SHA-256' | awk '{print $NF}' | fold -w2 | paste -sd: | tr '[:lower:]' '[:upper:]')
if [ "$expected" = "$actual" ]; then
return 0
else
return 1
fi
}
verify_apk() {
apk_name="$1"
# https://github.com/obfusk/apksigcopier?tab=readme-ov-file#what-about-signatures-made-by-apksigner-from-build-tools--3500-rc1
docker exec "${CONTAINER_NAME}" repro-apk zipalign --page-size 16 --pad-like-apksigner --replace "${DOCKER_PATH_VERIFY}/${apk_name}.${SUFFIX_BUILT}" \
"${DOCKER_PATH_VERIFY}/${apk_name}.aligned"
docker exec "${CONTAINER_NAME}" mv "${DOCKER_PATH_VERIFY}/${apk_name}.aligned" \
"${DOCKER_PATH_VERIFY}/${apk_name}.${SUFFIX_BUILT}"
docker exec "${CONTAINER_NAME}" apksigcopier copy "${DOCKER_PATH_VERIFY}/${apk_name}.${SUFFIX_DOWNLOADED}" \
"${DOCKER_PATH_VERIFY}/${apk_name}.${SUFFIX_BUILT}" \
"${DOCKER_PATH_VERIFY}/${apk_name}.${SUFFIX_BUILT_WITH_SIGNATURE}"
downloaded_apk_hash=$(docker exec "${CONTAINER_NAME}" sha256sum "${DOCKER_PATH_VERIFY}/${apk_name}.${SUFFIX_DOWNLOADED}" | awk '{print $1}')
built_apk_hash=$(docker exec "${CONTAINER_NAME}" sha256sum "${DOCKER_PATH_VERIFY}/${apk_name}.${SUFFIX_BUILT_WITH_SIGNATURE}" | awk '{print $1}')
if [ "$downloaded_apk_hash" = "$built_apk_hash" ]; then
return 0
else
return 1
fi
}
print_vercode() {
build_dir="$1"
awk -F'=' '/android.version_code=/ {print $2}' "${build_dir}/apps/multiplatform/gradle.properties"
}
setup_container() {
dir_git="$1"
dir_apk="$2"
docker build \
--no-cache \
-f "${dir_git}/Dockerfile.build" \
-t "${IMAGE_NAME}" \
--build-arg=USER_UID="$(id -u)" \
--build-arg=USER_GID="$(id -g)" \
.
# Run container in background
docker run -t -d \
--name "${CONTAINER_NAME}" \
--device /dev/fuse \
--cap-add SYS_ADMIN \
--security-opt apparmor:unconfined \
--security-opt seccomp:unconfined \
-v "${dir_git}:${DOCKER_PATH_PROJECT}" \
-v "${dir_apk}:${DOCKER_PATH_VERIFY}" \
"${IMAGE_NAME}"
}
build_apk() {
arch="$1"
vercode="$2"
apk_out="simplex-${arch}.apk.${SUFFIX_BUILT}"
# Gradle setup
docker exec -i "${CONTAINER_NAME}" sh << EOF
cd $DOCKER_PATH_PROJECT/apps/multiplatform
./gradlew
EOF
docker exec -i "${CONTAINER_NAME}" sh << EOF
GRADLE_BIN=\$(find \$HOME/.gradle/wrapper/dists -name "gradle" -type f -executable 2>/dev/null | head -1)
GRADLE_DIR=\$(dirname "\$GRADLE_BIN")
export PATH="\$GRADLE_DIR:\$PATH"
ARCHES="$arch" ./scripts/android/build-android.sh -gs "$vercode" || ARCHES="$arch" ./scripts/android/build-android.sh -gs "$vercode"
APK_FILE=\$(find . -maxdepth 1 -type f -name '*.apk')
mv "\$APK_FILE" $DOCKER_PATH_VERIFY/$apk_out
EOF
}
main() {
tag="$1"
build_directory="${TEMPDIR}/${REPO_NAME}"
final_directory="$INIT_DIR/${tag}-${REPO_NAME}"
apk_directory="${final_directory}/android"
printf 'This script will:
1) build docker container.
2) download APK from GitHub and validate signatures.
3) build core library with nix (12-24 hours).
4) build APK and compare with downloaded one
Continue?'
read _
check "$CMDS"
mkdir -p "${apk_directory}"
# Setup initial git for Dockerfile.build
setup_git "$TEMPDIR" "$REPO_NAME"
checkout_git "$build_directory" "$tag"
printf "${COLOR_CYAN}Building Docker container...${COLOR_RESET}\n"
setup_container "$build_directory" "$apk_directory"
# Check phase
for arch in $ARCHES; do
filename="simplex-${arch}.apk"
download_apk "$tag" "$filename" "${apk_directory}/${filename}.${SUFFIX_DOWNLOADED}"
if check_apk "${filename}.${SUFFIX_DOWNLOADED}" "$SIMPLEX_KEY"; then
printf "${COLOR_CYAN}APK for %s is signed by valid key.${COLOR_RESET}\n" "$arch"
else
printf "${COLOR_CYAN}Signature of APK for %s is invalid., aborting the script.${COLOR_RESET}\n" "$arch"
exit 1
fi
done
# Build phase
for arch in $ARCHES; do
case "$arch" in
armv7a)
build_tag="${tag}-armv7a"
;;
aarch64)
build_tag="${tag}"
;;
*)
printf "${COLOR_CYAN}Unknown architecture: %s! Skipping the build...${COLOR_RESET}\n" "$arch"
continue
esac
# Setup the code
checkout_git "$build_directory" "$build_tag"
vercode=$(print_vercode "$build_directory")
printf "${COLOR_CYAN}Building APK for for %s...${COLOR_RESET}\n" "$arch"
build_apk "$arch" "$vercode"
done
# Verification phase
for arch in $ARCHES; do
filename="simplex-${arch}.apk"
if ! verify_apk "$filename"; then
printf "${COLOR_CYAN}Failed to verify %s! Aborting.\n${COLOR_RESET}" "$filename"
exit 1
fi
done
printf "${COLOR_CYAN}%s is reproducible.${COLOR_RESET}\n" "$tag"
cleanup
}
main "$@"
+2
View File
@@ -50,6 +50,8 @@ for os in '22.04' '24.04'; do
--no-cache \
--build-arg TAG="${os}" \
--build-arg GHC="${ghc}" \
--build-arg=USER_UID="$(id -u)" \
--build-arg=USER_GID="$(id -g)" \
-f "${tempdir}/${repo_name}/Dockerfile.build" \
-t "${image_name}" \
.
+1 -1
View File
@@ -5,7 +5,7 @@ cabal-version: 1.12
-- see: https://github.com/sol/hpack
name: simplex-chat
version: 6.5.0.5
version: 6.5.0.6
category: Web, System, Services, Cryptography
homepage: https://github.com/simplex-chat/simplex-chat#readme
author: simplex.chat
+7 -3
View File
@@ -233,9 +233,13 @@ startRemoteHost rh_ rcAddrPrefs_ port_ = do
pollEvents :: RemoteHostId -> RemoteHostClient -> CM ()
pollEvents rhId rhClient = do
oq <- asks outputQ
forever $ do
r_ <- liftRH rhId $ remoteRecv rhClient 10000000
forM r_ $ \r -> atomically $ writeTBQueue oq (Just rhId, r)
forever $
handlePollError oq $ do
r_ <- liftRH rhId $ remoteRecv rhClient 10000000
forM_ r_ $ \r -> atomically $ writeTBQueue oq (Just rhId, r)
where
handlePollError oq a = a `catchAllErrors` \e ->
atomically $ writeTBQueue oq (Just rhId, Left e)
httpError :: RemoteHostId -> HTTP2ClientError -> ChatError
httpError rhId = ChatErrorRemoteHost (RHId rhId) . RHEProtocolError . RPEHTTP2 . tshow
+2 -1
View File
@@ -36,6 +36,7 @@ import qualified Data.Aeson.TH as JQ
import qualified Data.Attoparsec.ByteString.Char8 as A
import qualified Data.ByteString.Base64 as B64
import Data.ByteString.Char8 (ByteString, pack, unpack)
import qualified Data.ByteString.Char8 as B
import qualified Data.ByteString.Lazy as LB
import Data.Functor (($>))
import Data.Int (Int64)
@@ -1411,7 +1412,7 @@ instance ToField AgentConnId where toField (AgentConnId m) = toField $ Binary m
instance StrEncoding AgentConnId where
strEncode (AgentConnId connId) = strEncode connId
strDecode s = AgentConnId <$> strDecode s
strP = AgentConnId <$> strP
strP = AgentConnId <$> (strP <|> pure B.empty)
instance FromJSON AgentConnId where
parseJSON = strParseJSON "AgentConnId"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 101 KiB

+64 -112
View File
@@ -4,174 +4,126 @@ title: "SimpleX Community Vouchers"
permalink: "/vouchers/index.html"
---
# SimpleX Community Vouchers
Since we started developing the SimpleX network, the app has been downloaded over 1.5 million times.
We are not just building a messenger. Unlike today's web dominated by big tech platforms, SimpleX is a network where you fully control your online identity, contacts, groups, and content without ads tracking you or companies mining your data.
The SimpleX network is designed to be private, secure, decentralized (meaning no single company owns it), and truly owned by its users. That's why we develop it as fully open-source code (anyone can review it or build their own apps and servers).
To make this vision sustainable, we're introducing Community Vouchers in 2026. Think of them as simple prepaid cards for phone calls, but for funding the servers that power your channels and groups.
**How it will work in simple terms**:
- Community Vouchers can be purchased using the usual in-app payments (like via Apple or Google Play) or using cryptocurrency, such as Bitcoin or Monero.
- Community Vouchers are secure and private: their usage can't be linked to their purchase, however you paid for them, thanks to advanced cryptography (zero-knowledge proofs).
# SimpleX Community Vouchers: Strategy & Vision
<a href="javascript:void(0);" data-show-overlay="mint-simplex-nft" class="open-overlay-btn"><img src="/img/design_3/simplex_nft_smpx.jpg" width="200" class="float-to-right" style="border-radius: 10px;"></a>
Under the hood, Community Vouchers are utility tokens on a blockchain (a secure, shared ledger that no single company controls). But you won't have to use blockchain if you don't want to: we are making vouchers as easy to use as gift cards.
SimpleX is a private and secure messaging network where you own your identity, contacts, groups, and content — there are no ads, no tracking, and no central authority. It relies on open protocols and open-source code, enabling anyone to audit the code and to create alternative apps and servers.
Community Vouchers are not tradable, and there will be no "pre-mine" or public sale.
To scale for large groups and channels, without relying on any single entity, SimpleX network needs a sustainable way to fund servers.
If you have a cryptowallet, and want to test Community Vouchers early, before full release, you can <a href="javascript:void(0);" data-show-overlay="mint-simplex-nft" class="open-overlay-btn">get a free access pass</a> to the test version &mdash; a free non-transferrable NFT on Ethereum mainnet, you only need to pay for gas.
Community Vouchers offer the solution - they are prepaid infrastructure credits for servers used by groups and channels.
To receive updates, connect to us [via SimpleX Chat](https://smp6.simplex.im/a#lrdvu2d8A1GumSmoKb2krQmtKhWXq-tyGpHuM7aMwsw).
These vouchers are not tradable tokens or speculative assets — there will be no pre-sale or emission. It's a method to pay directly for the network infrastructure while maintaining privacy.
## Community Vouchers FAQ &mdash; send your feedback
For early access to test vouchers, if you're familiar with cryptocurrencies, <a href="javascript:void(0);" data-show-overlay="mint-simplex-nft" class="open-overlay-btn">get a free access pass</a> to the test version &mdash; a free non-transferrable NFT on Ethereum mainnet, you only need to pay for gas.
These are early insights into how Community Vouchers can work &mdash; some of these ideas are still vague; they will evolve based on your feedback and testing.
## Why Community Vouchers?
- [Why Community Vouchers?](#why-community-vouchers)
- [Free Tier?](#free-tier)
- [How Will Vouchers Work?](#how-will-vouchers-work)
- [Will self-hosted servers still be supported by SimpleX network?](#will-self-hosted-servers-still-be-supported-by-simplex-network)
- [What problems Community Vouchers solve that other payment methods can't?](#what-problems-community-vouchers-solve-that-other-payment-methods-cant)
- [How is it possible to provide privacy on public blockchain?](#how-is-it-possible-to-provide-privacy-on-public-blockchain)
- [Will Community Vouchers be pre-sold via private or public sale?](#will-community-vouchers-be-pre-sold-via-private-or-public-sale)
- [Who will sell vouchers?](#who-will-sell-vouchers)
- [How the server operator revenue share is determined?](#how-the-server-operator-revenue-share-is-determined)
- [Who will control and upgrade smart contracts?](#who-will-control-and-upgrade-smart-contracts)
- [Will I be able to sell or transfer Community Vouchers to other people?](#will-i-be-able-to-sell-or-transfer-community-vouchers-to-other-people)
- [Why Not Existing Crypto?](#why-not-existing-crypto)
- [Why build on Ethereum blockchain?](#why-build-on-ethereum-blockchain)
- [Have you considered other blockchains?](#have-you-considered-other-blockchains)
- [Which token specification do you plan to use?](#which-token-specification-do-you-plan-to-use)
- [If you build on another blockchain, how the NFT will be used to provide access?](#if-you-build-on-another-blockchain-how-the-nft-will-be-used-to-provide-access)
### Why Community Vouchers?
<img src="/img/design_3/community_vouchers_light.jpg" width="38%" class="float-to-right dark:hidden">
<img src="/img/design_3/community_vouchers_dark.jpg" width="38%" class="float-to-right hidden dark:block">
To cover server costs securely and privately.
To pay for network infrastructure securely and privately.
With "free" centralized platforms:
- you lose security and privacy, because your data is used for advertising and sold.
- they de-platform inconvenient users, often based on frivolous complaints.
- you don't own all rights to your content.
Paying for server capacity may be cheaper than "free" platforms. Our estimates based on the current costs are $5-10/month for 5,000 active message receivers (could be up to 50,000 listed community members) with 5-10 GB of files/media archive. These estimates are preliminary and may change.
Paying for server capacity may be cheaper than "free" platforms.
### Free Tier?
## How Will It Work?
It will be determined after testing. Preliminarily, we expect up to 1,000 active message receivers (can be up to 10,000 listed members) and 500 MB storage to be available for free groups.
In short:
"Active message recipient" in this model is a group member who periodically connects to the network, and receives group messages. Members who are listed but don't open the group for some time, for example two weeks, will stop receiving all group messages even when they are connected to the network. This is an evolving design that will balance security for group members and owners, to avoid inflated expenses, and to present realistic membership statistics to the group owners and to prospective members.
<img src="/img/design_3/community_vouchers_light.jpg" width="38%" class="float-to-right dark:hidden">
Private messaging with contacts and in private groups within "fair use" limits that we apply today will remain free:
- there can be up to 128 undelivered messages per destination,
- the undelivered messages are stored up to 21 days,
- files up to 1 GB can be sent for free,
- files are available for download for up to 2 days.
<img src="/img/design_3/community_vouchers_dark.jpg" width="38%" class="float-to-right hidden dark:block">
Larger limits may be offered in paid tier, but it is not planned initially &mdash; the focus of Community Vouchers is to create a commercial model for communities.
- Buy Community Vouchers. Initially you would pay with a stablecoin (USDT/USDC). The goal to allow using other popular cryptocurrencies (BTC/ETH/XMR) and also in-app payments - to make direct usage of blockchain optional for the end users.
### How Will Vouchers Work?
- Funds are locked in an autonomous smart contract not controlled by SimpleX Chat company or by anybody else.
Buy via app (like phone top-ups), with unused capacity shown in the app. An important design goal is to make Community Vouchers available to people who don't use any cryptocurrencies.
- Assign the Community Voucher to a group or channel you want, using it's public address. This assignment is private, and group owners or server operators won't be able to link it to the purchase, thanks to zero-knowledge proofs.
Testnet is likely to use hashed IDs for privacy and on-chain payments, to validate the pricing and economic model. Zero-knowledge proofs and in-app payments will be added by the time production network is launched.
- Group or channel owners redeem the Vouchers to the server operators they use. The redemption is also private, and not linkable to the assignment or purchase.
### Will self-hosted servers still be supported by SimpleX network?
- Server operators receive up to 70% of the unlocked funds, with the rest being allocated to network development and governance.
Yes, absolutely. Not only will the apps continue to support self-hosted servers, but we will improve it. We see network decentralization and server portability as very important, and while we need to develop a robust commercial model for the servers, we still need community-hosted servers to function, with all people using a single network:
- users who use self-hosted servers will be able to join groups that use pre-configured servers or Community Vouchers.
- users who use pre-configured servers will be able to join groups that are run on free community-hosted servers, same as today.
- you will be able to create new server operators (collections of messaging and file servers operated by one entity), so that the features currently available only for preset servers will be available to all servers very soon, and all servers that you and your community members want to use can be added to the app by scanning a QR code.
## Why Blockchain?
### What problems Community Vouchers solve that other payment methods can't?
It's the only way to make SimpleX network truly decentralized and secure:
Community Vouchers implemented via smart contracts on blockchain solve these problems:
- unlinkability of the voucher purchase and usage - to confirm ownership smart contracts will use zero-knowledge proofs, rather than visible transfers between blockchain addresses. While any blockchain observers may see that a given address purchased a voucher, they will not see how vouchers are used.
- server operators cannot fail to provide infrastructure &mdash; the funds will be locked in a smart contract until it is provided.
- codify the agreement about how revenue is shared between server operator and the network, so that it depends not on trust, but on cryptography.
- Group and user names resistant to man-in-the-middle attacks.
### How is it possible to provide privacy on public blockchain?
- Public registry of network operators, with their trust scores.
In the same way it is possible to provide private communications on the public Internet, as SimpleX network does.
- Private and secure payments based on zero-knowledge proofs in smart-contracts.
Our commitment to users' privacy and security remains as strong as ever, and we plan to bring the practical expertise of building private communication protocols over the last 5 years to how we develop the technology for the blockchain.
We are currently evaluating several popular blockchains that have strong support for zero-knowledge proofs - technology that support private operations on public blockchains.
While specific designs are in early stages, here are some of the principles that we will follow to ensure privacy:
- each voucher purchase will be associated with a new blockchain address. There will be no per-user addresses, as wallets use. So the cornerstone of SimpleX network design - no user profile IDs - will be followed for blockchain development as well.
- all operations on blockchain will be supported by network servers that will run full blockchain nodes. For important requests, such as name resolution, the clients will use 2 or 3 independent servers, to ensure protection from MITM attacks.
- blockchain operations will be proxied, in the same way as it happens with private message routing.
## Timeline & How to Get Involved
We will be publishing the whitepaper about this design. It will provide an unprecedented level of security and privacy for blockchain applications, irrespective of which chain we choose to use.
**2025**:
- evaluating blockchains,
- drafting Community Vouchers whitepaper about system and cryptography design for Community Vouchers.
- development of large group and communities.
### Will Community Vouchers be pre-sold via private or public sale?
We welcome your feedback on this proposal and any in-progress design documents.
There will be no Community Vouchers pre-sold or in any other way made available to the team, or to investors or to the public.
**2026**:
- launch support for large groups and channels.
- test version of Community Vouchers.
- SimpleX network namespace v1.
Any blockchain token that is pre-sold to raise funds to develop technology is not a utility token, regardless of how it's named &mdash; it becomes an investment contract that passes [Howey test](https://www.investopedia.com/terms/h/howey-test.asp).
**Join in**:
- <a href="javascript:void(0);" data-show-overlay="mint-simplex-nft" class="open-overlay-btn">Get a free NFT</a> for early testing.
- Create a small group or channel using today's tech, and get it added to our experimental directory of groups.
- Talk to us if you want to be a server operator to earn revenue and about any partnerships.
This is not what we are doing. Community Vouchers are restricted utility tokens, not an investment contract. They will be only issued on demand to people who want to pay for network servers, at a fixed price.
## Community Vouchers FAQ
### Who will sell vouchers?
**Will self-hosted servers still work?**
Initially, Community Vouchers will be sold via a smart contract in exchange for some other tradeable tokens, most likely stablecoins. We don't plan any token emission, or any public or private pre-sales. And we won't have access to the funds from voucher sales &mdash; they will be locked in a smart contract, and only released once servers have provided capacity to the users, with the funds shared between server operators and the SimpleX network, with operators receiving up to 60%, depending on trust evaluation. The SimpleX network funds will be managed by smart contracts, and will be used for governance and development as defined by the contracts. Their price will be fixed based on server costs, with the exact economic model developed during the testing phase.
Yes! Support for self-hosted servers will be improved, and they can be used together with paid servers, for better reliability and censorship-resistance.
### How the server operator revenue share is determined?
**Why not just use existing cryptocurrency?**
It will be based on the goal that servers must provide both reliability and security to the users. Security in any multi-node network depends on users' ability to choose independent servers that are provided by different entities, and the apps are already programmed not just to use different servers for the message delivery path, but to use servers of different operators. Even though currently there are only 2 preset operators &mdash; SimpleX Chat and Flux &mdash; and all servers added to the app by the user are considered a third operator, it substantially improves privacy and security.
Cryptocurrencies are:
- Speculative and volatile.
- Regulated as financial transactions.
- BTC and XMR blockchains do not support smart contract logic, e.g. for locked funds.
In the future, the operators that confirmed their identity to the network will receive a much higher revenue share than anonymous ones. We believe that for users to be private and secure, operators must be known, and must accept legally binding terms of operation, same as preset operators do today.
**How can it be private on a public blockchain?**
The other two factors that will affect "trust evaluation" will be how long the operator was available on the network and servers' availability uptime. Similar to how we monitor the uptime of our servers, the network will monitor the uptime of all servers, and it will affect the revenue share.
High level of privacy is achieved by new address per purchase, proxied access to blockchain, and zero-knowledge proofs that make payment and usage unlinkable.
We don't have an exact model for revenue sharing yet; it will be determined during testing and will evolve based on feedback from users and server operators.
**Can I sell or transfer vouchers?**
### Who will control and upgrade smart contracts?
No, Community Vouchers cannot be sold or transferred. Once purchased and assigned to a group or channel, they can only be redeemed to server operators. They will expire in 12 months if not redeemed, with the funds released to network development and governance.
Community Vouchers will require several smart contracts for their functioning. During testing and development, SimpleX Chat will maintain and update all contracts. Once the network is ready for production, some critical contracts (e.g., those that control the funds) will be immutable, requiring a lot of testing and a security audit, and some less critical contracts will still be upgradeable based on a consensus model (e.g., multisig or voting).
**Free messaging limits?**
It is always a journey from knowing that something is possible to knowing how exactly it will be done, and we are at the early stage of knowing it is possible. Specific designs would evolve, based on the input from legal and blockchain experts, and from the community &mdash; as everything else we develop for SimpleX network.
Private chats and small groups remain free within fair use (up to 128 undelivered messages per contact, with up to 21 days storage, up to 1GB files stored for 2 days). Community Vouchers will be used to pay for large groups infrastructure and for memorable public names.
### Will I be able to sell or transfer Community Vouchers to other people?
**Who controls the smart contracts?**
Possibly, but with limits on the number of transactions and the time of holding.
We will control them during testing. Once released for general access, the contracts that accept and hold funds will be autonomous and immutable.
Community Vouchers are designed with a single purpose &mdash; to facilitate payments for servers' capacity in a way that protects users' security. Smart contracts implementing them will restrict or completely prohibit trading. The specific parameters will be determined during design evolution and testing.
**How is revenue share of server operators determined?**
### Why Not Existing Crypto?
Server operators will receive up to 70% of the infrastructure payments. A higher share will be allocated for:
- identified operators, because knowing who runs the servers achieves better user privacy and security,
- more reliable servers,
- servers that operated for a longer time.
Existing cryptocurrencies do not allow the implementation of the required model for Community Vouchers. The price of cryptocurrencies is determined speculatively, and not based on costs. The fact that they can be freely traded and transferred exposes existing cryptocurrencies and tokens to financial regulations.
**What is technology design?**
The existing cryptocurrencies such as XMR, BTC and some others will be accepted as payment for Community Vouchers, via bridges, but they cannot be used in the foundation of the system, because they are not as flexible as smart contracts, and cannot directly support the model we are developing.
[Early ideas about Community Vouchers](https://github.com/simplex-chat/simplex-chat/blob/master/docs/rfcs/2024-04-26-commercial-model.md).
### Why build on Ethereum blockchain?
[The most recent design](https://github.com/simplex-chat/simplex-chat/blob/master/docs/rfcs/2025-10-23-vouchers.md) based on zero-knowledge proofs.
Many people dislike Ethereum for its high energy usage and high transaction costs in the past. Also, blockchain transactions cannot provide privacy, can they? Why not use Monero (XMR) instead?
[Previosly shared FAQ](https://github.com/simplex-chat/simplex-chat/blob/master/docs/rfcs/2025-12-17-community-vouchers-faq.md).
This was our assessment as well in the past. But the last three years changed it, addressing energy usage and transaction costs, and we've seen the growth of several L2 Ethereum blockchains. What made us decide that EVM-based blockchain is the best choice for the current stage is the planned rollout of zkEVM in 2025 with native support for zero-knowledge proofs.
A whitepaper will be published in February 2026.
[Our early ideas about Community Vouchers](https://github.com/simplex-chat/simplex-chat/blob/master/docs/rfcs/2024-04-26-commercial-model.md) and [the most recent design](https://github.com/simplex-chat/simplex-chat/blob/master/docs/rfcs/2025-10-23-vouchers.md) rely on zero-knowledge proofs, and as it will be natively supported, EVM blockchains provide a much better foundation to build Community Vouchers than building them from scratch &mdash; there is no need to re-invent solutions to problems that are already solved.
### Have you considered other blockchains?
We are actively considering which blockchain to build on. Ethereum ecosystem is the most widely adopted, and has very mature systems and tools, and it appears sufficient, but it has its downsides, as does everything. So we are not yet committed to Ethereum.
### Which token specification do you plan to use?
Even though these are not freely tradable tokens, we will likely make them compatible with [ERC20 token specification](https://eips.ethereum.org/EIPS/eip-20). It is very simple, one of the earliest, and the most adopted standard on EVM blockchain. It defines tokens, but they don't have to be freely tradeable &mdash; the specification allows any extensions and restrictions implemented on top of it.
Using this specification would make Community Vouchers partially compatible with wallets and chain explorers, making testing, development, and early adoption easier.
### If you build on another blockchain, how the NFT will be used to provide access?
We can take into account the list of addresses that hold NFTs and provide access to testnet on any blockchain via a cryptographic signature. That is the reason the NFT is deployed on Ethereum mainnet and not on some of L2 chains. We don't yet know at this stage which L2 testnet will be used.
## Disclaimer