Commit Graph
338 Commits
Author SHA1 Message Date
spacedandy-agents-simplex e116987e5b badge-service: let a dev deployment ask its mock store while coverage runs
[dev] check_store_during_coverage = on makes every issueBadge for a
subscription ask the dev mock, during paid coverage too, and bank the
month of a charge it can grant, issued once coverage reaches it. So a
renewal can be watched by hand without waiting a month, and a mock that
forgot the plan after a restart answers ended at once.

Off by default, and refused unless accept_unverified_store_receipts is
on, which is itself refused beside a real store: a real store has not
started its next charge while coverage runs, and asking spends the
quota every subscriber shares.

Run: 011-subscription-tools, slice S3a
2026-10-20 15:37:53 +04:00
spacedandy-agents-simplex d50488460d Merge branch 'master' into f/badge-subscriptions
# Conflicts:
#	src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt
2026-10-19 09:49:17 +00:00
sh bdc4edc524 nix: build armv7a from master with ghc 8.10.7 (#7763) 2026-10-19 09:07:52 +01:00
EvgenyandEvgeny @ SimpleX Chat a766d0af0f ci: package releases with drafts in simplex-chat-libs (#7754)
* ci: package releases with drafts in simplex-chat-libs

* test release

* core: 7.1.0.12

* packages: release nodejs and python libraries

* fixes

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-10-19 07:50:09 +01:00
EvgenyandEvgeny @ SimpleX Chat 77f9f4a464 core: add peer type "agent" (#7738)
* add agent peer type

* bot types

* agent app icons

* refactor

* smaller image

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-10-17 19:23:53 +01:00
spacedandy-agents-simplex 613ce364f4 review: round 1 fixes
R1-A1: the docs and the PlayReads comment said the purchase path reads Play's subscriptions at most 300 times a minute; it asks about at most 300 subscriptions, and a credited one is read once more to acknowledge it, so made-up tokens can spend at most a tenth of the quota renewal checks share.
R1-A2: a comment on RequestLane repeated the one above the queues.
R1-B1: a test that a held pass, which sends no request, leaves the unrenewed run unchanged.
R1-B2: the outage test's last wait for the run is 30 s instead of 5 s.

Run: 007-subscriptions-retirement-lane, review round 1
2026-10-16 12:58:51 +00:00
spacedandy-agents-simplex bc79a360ce badge-service: read Play's subscriptions at most 300 times a minute for purchases
A Play subscription purchase is asked about without any offline check, so any token in the accepted grammar spends a read from the Subscriptions quota renewal checks share. The purchase path now takes one of a minute's 300 reads for each Play subscription it asks about, a tenth of Play's default quota; with none left, the claim is answered rate_limited with the seconds left in the minute and is not held, as Play was not asked. A claim already held takes no read, and App Store claims, verified offline first, take none.

Run: 007-subscriptions-retirement-lane, slice 3
2026-10-16 11:46:45 +00:00
spacedandy-agents-simplex ce7fed16b0 Merge branch 'badge-in-app-checkout' into f/badge-subscriptions
# Conflicts:
#	src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt
2026-10-16 10:19:54 +00:00
spacedandy-agents-simplex e3324c6828 Merge branch 'master' into badge-in-app-checkout
# Conflicts:
#	simplex-chat.cabal
#	src/Simplex/Chat/Store/Postgres/Migrations.hs
#	src/Simplex/Chat/Store/SQLite/Migrations.hs
#	src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt
#	src/Simplex/Chat/Store/SQLite/Migrations/chat_schema.sql
2026-10-16 09:40:53 +00:00
EvgenyandEvgeny @ SimpleX Chat 5dfe7c1f0e website: downloads page (#7728)
* website: downloads page

* bigger headings

* translations

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-10-15 22:10:59 +01:00
spacedandy-agents-simplex 23b4e07d21 badge-service: ask Play about a subscription purchase at most once an hour per token
The purchase path's hourly bound covered only App Store claims, so a re-presented Play subscription token, uncredited or credited to another key, spent a subscriptionsv2.get call each time, from the quota bucket Play renewal checks use. The bound now lives in purchaseSubscription, which both stores' purchase paths call, with one map per store: Play's keyed by the token's hash, so made-up Play tokens cannot fill the App Store's. Distinct made-up tokens are still one call each.

Run: 005-subscriptions-load-timing, slice 6
2026-10-15 17:29:40 +00:00
spacedandy-agents-simplex bceaf06a4b fixup! review: round 1 fixes 2026-10-15 16:49:43 +00:00
spacedandy-agents-simplex 908922060e fixup! review: round 1 fixes 2026-10-15 16:31:33 +00:00
spacedandy-agents-simplex 06c816de10 review: round 1 fixes
badge-service: a Play charge whose clipped period start leaves its month
already spent is answered as period over, not internal (R1-A1).
docs: the per-store answer classes list Play's 410 and the App Store
subscription check (R1-A2).
tests: a held receipt with no attempt yet blocks an invoice (R1-B2); a
renewing report keeps an ended status (R1-B3); a test comment names
[google] (run 005 C2-R2-1).
ios: a subscription refused because this Apple ID subscribed before
shows its sentence, not the error's name (R1-C2); ios, android, desktop:
the Check your order footnotes share one helper (R1-C3).

Run: 006-subscriptions-branch-review, review round 1
2026-10-15 15:50:21 +00:00
spacedandy-agents-simplex 5815c0150d badge-service: ask the App Store about a subscription purchase at most once an hour per claim
Anyone holding a real but uncreditable App Store subscription JWS, such as
their own lapsed subscription, could present it again and again, each time
spending an App Store Server API call from the quota every subscriber's
renewal check needs. The purchase path now remembers, in memory, which
subscription claims it asked about within the hour and answers a repeat
payment_pending with the time left. Keys are original transaction ids from
JWS that verified offline, entries expire after the hour, and a full table
asks rather than refuses, so memory stays bounded and no buyer waits on
another's claim.

Run: 005-subscriptions-load-timing, slice 4
2026-10-15 14:23:16 +00:00
spacedandy-agents-simplex 141ac06d47 Merge branch 'badge-in-app-checkout' into f/badge-subscriptions
# Conflicts:
#	apps/simplex-badge-service/README.md
#	apps/simplex-badge-service/badge_service.ini.example
#	apps/simplex-badge-service/src/BadgeService/Config.hs
#	apps/simplex-badge-service/src/BadgeService/Service.hs
#	apps/simplex-badge-service/src/BadgeService/StoreReceipts.hs
#	apps/simplex-badge-service/src/BadgeService/StoreReceipts/Apple.hs
#	apps/simplex-badge-service/src/BadgeService/StoreReceipts/Google.hs
#	scripts/badge-service/badge_service.ini.example
#	tests/Bots/BadgeService/BotTests.hs
#	tests/Bots/BadgeService/ConfigTests.hs
#	tests/Bots/BadgeService/FakePlay.hs
#	tests/Bots/BadgeService/FakeStore.hs
#	tests/Bots/BadgeService/StoreVerifierTests.hs
2026-10-14 11:44:31 +00:00
shandspaced4ndy daa7c4f3d8 badge-service: accept a list of Apple roots (#7707)
* badge-service: accept a list of Apple roots

* badge-service: document root_certificates

---------

Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>
2026-10-14 10:43:53 +00:00
spacedandy-agents-simplex 7c05719796 badge-service: check and acknowledge Google Play subscriptions
The Play subscription check reads purchases.subscriptionsv2 by token
through the existing service-account client, with the same HTTP classes as
product reads, and maps Play's state, base plan, period, order id and
offer phase; the period start is its end minus the plan's length, and a
pending subscription stays pending. A subscription is acknowledged with
purchases.subscriptions.acknowledge before it is credited, skipped when
Play reports it acknowledged, so it never reaches the one-time endpoint.
Each store's subscriptions answer provider_not_configured when that store
is not configured. A charge on a plan the catalog does not sell is pending
rather than a malformed period.

Run: 001-badge-subscriptions, slice 7
2026-10-14 08:47:30 +00:00
spacedandy-agents-simplex 732db2dfb0 badge-service: renew a subscription once its paid coverage ends
While a subscription purchase's coverage runs, issueBadge is unchanged
and makes no store call. Once it has ended, the service asks the store at
most once an hour per subscription, stamping every attempt, and answers
from the stored state in between; a failed check is retried after the
whole interval. A grantable charge is planned from the tip at the store's
period start, signed, and written with its issuance and state in one
transaction that re-reads the tip, answering internal if it moved. Any
other charge and the state are recorded without a ledger row. Every answer
for a subscription purchase carries its state.

Run: 001-badge-subscriptions, slice 4
2026-10-14 05:20:00 +00:00
spacedandy-agents-simplex c8b8ba4d4f badge-service: credit a store subscription purchase
The catalog now tells subscription products from one-time ones and maps a
store plan to its tier and months. A subscription receipt is checked with
the store once: with a grantable charge, the service plans the charge's
rows from the store's period start, signs the first month, and writes the
payment, purchase, charge, ledger rows, issuance, state and Play token in
one transaction, answering with the subscription state. Without one, it
answers payment_pending (300 s while the period has not started or the
store is pending, a day otherwise), receipt_invalid for an ended Play
subscription, or test_purchase, and writes nothing. Replays carry the
state. The store verifier interface gains the subscription check, which no
real store implements yet; the fake store does.

Run: 001-badge-subscriptions, slice 3b
2026-10-14 04:36:13 +00:00
spaced4ndy 59c588932e badge-service: verify App Store and Google Play purchases (#7654) 2026-10-13 15:24:07 +00:00
EvgenyandEvgeny @ SimpleX Chat 07c363849b core, ui: invite member of one group to another group (#7682)
* rfc: invite member of one group to another group

* update

* update

* implement

* version

* update

* do not show error if contact was removed when joining group

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-10-11 09:50:42 +01:00
EvgenyandEvgeny @ SimpleX Chat 2e56d32b52 core: badge presentations in profiles (#7573)
* badge presentation in groups

* fix tests

* badge presentations in profiles

* update simplexmq

* change types

* badge profile presentations

* improvements

* remove proof from cards, send owner public key for channel to relay

* add test

* merge migrations

* update

* prevent fallback to PHTest

* fixes

* many fixes

* fixes

* fixes

* cleanup

* improve

* query plans

* fix test

* diff

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-10-10 17:48:45 +01:00
spaced4ndy 57ab333a2b Merge branch 'master' into badge-in-app-checkout 2026-10-09 15:00:36 +04:00
EvgenyandEvgeny @ SimpleX Chat 10166454fd website: add sitemap, robots, llms.txt and markdown pages (#7670)
* website: markdown pages for llms

* website: add sitemap, robots, llms.txt and markdown pages

* faster site generation

* more faster

* faster

* update

* optimize build

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-10-09 07:53:40 +01:00
EvgenyandEvgeny @ SimpleX Chat f2b3fe385c core: remove legacy field to support contact connections in groups (#7671)
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-10-09 07:00:27 +01:00
spaced4ndy 80b7f96a96 merge master into badge-in-app-checkout 2026-10-08 14:31:30 +04:00
spaced4ndy 27d12f230d core, ui: buy a badge with an App Store or Google Play purchase (#7590) 2026-10-07 14:32:48 +00:00
Evgenyandshum b79223fe5c core: call media key HKDF, expire stale calls (#7642)
* core: call media key HKDF, expire stale calls

* core: expire stale calls in bulk SQL

* core: reduce call tests

* core: remove periodic call cleanup

* core: expire calls with DELETE RETURNING

* core: skip call item update when none expired

---------

Co-authored-by: shum <github.shum@liber.li>
2026-10-04 18:44:52 +01:00
EvgenyandEvgeny @ SimpleX Chat 851ff062da core: compress messages if needed to fit envelope, even if there is no PQ e2ee in connection (#7630)
* core: compress messages if needed to fit envelope, even if there is no PQ e2ee in connection

* simplify

* remove noise

* compress messages without PQ too

* case

* update query plans

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-09-30 14:07:00 +01:00
sh b1dc25dc3e badges: service group with multi-use codes (#7578)
* core: cancel the chat callback on interrupt

* badges: add multi-use codes

* badges: add the managed group

* badges: document multi-use codes and the group

* core: sign test badges with whole-second expiry

* badges: rework tracker and reply texts
2026-09-30 08:48:57 +01:00
EvgenyandEvgeny @ SimpleX Chat e863ee4c27 core: limit depth of forwarded messages (#7614)
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-09-29 21:56:03 +01:00
EvgenyandEvgeny @ SimpleX Chat 176e55895a blog: supporter badges (#7538)
* blog: supporter badges

* update post

* update date, add video image

* add image

* update

* update

* update post, add to lists

* update video

* add preview

* images

* update post and overview

* update

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-09-19 10:10:10 +01:00
EvgenyandEvgeny @ SimpleX Chat 000244f9a6 docs: supporter badges technical overview (#7535)
* docs: supporter badges

* improve

* update

* update

* improve

* update

* correction

* update

* simplify

* revise

* corrections

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-09-19 09:26:01 +01:00
spaced4ndy f9bab17643 core: renew badges monthly and alert when support ends (#7448) 2026-09-09 14:31:05 +00:00
spaced4ndy c623f4284c Merge branch 'master' into badges 2026-09-02 13:53:35 +04:00
EvgenyandEvgeny @ SimpleX Chat 90340b116d website: update livestream page (#7439)
* website: update livestream page

* update

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-08-31 23:41:54 +01:00
Evgeny Poberezkin ed2cf1d98f Merge branch 'master' into badges 2026-08-29 19:14:04 +01:00
Evgeny Poberezkin 498d7da837 Merge branch 'stable' 2026-08-29 18:59:49 +01:00
spaced4ndy e80a174f13 core: badge codes schema, plan (#7427) 2026-08-28 09:31:24 +00:00
Evgeny Poberezkin 78332d0c73 Merge branch 'master' into badges 2026-08-27 07:59:57 +01:00
sh a99541d0fe scripts: add chat relay docker setup (#7406)
* scripts: add chat relay docker setup

* docs: add docker setup to chat relay guide

* scripts: bump relay ref and add RTS options

* scripts: reduce comments in relay setup

* scripts: increase relay pool and queue size

* scripts: add relay metrics exporter

* docs: trim docker section in chat relay guide

* scripts: bump cabal for hackage key rotation

* scripts: retry cabal update on mirror failure

* scripts: split cabal update into its own layer

* scripts: allow setting relay address server

* docs: adjust systemd service limits

* docs: mention docker volume full path
2026-08-26 09:10:41 +01:00
Evgeny Poberezkin 1160215570 Merge stable 2026-08-18 17:16:21 +01:00
EvgenyandEvgeny @ SimpleX Chat 5e45fe1f0e directory: only create group links after approval (#7356)
* directory: only create group links after approval

* update test

* update messages

* diff

* get group and link in one query

* reduce database reads

* better errors

* typos

* query plans

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-08-18 16:35:37 +01:00
EvgenyandEvgeny @ SimpleX Chat 352550089f core: client and service schema for badge purchases (#7358)
* core: client and service schema for badge purchases

* simplify api, receipt is payment type

* split invoice

* update

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-08-17 19:25:18 +01:00
Evgeny Poberezkin e2a3f6317a website: add links 2026-08-16 13:14:07 +01:00
spaced4ndy 4217c9ee84 Merge branch 'master' into badges 2026-08-14 11:31:01 +04:00
Evgeny Poberezkin 0f45645afe Merge branch 'stable' 2026-08-12 15:30:16 +01:00
sh 0a61b0ddea android: add google and foss build flavors (#7328)
* android: add google and foss build flavors

* android: get the Google Play account country in the google flavor

* android, desktop: update whats new

* temp: comment out wefunder link
2026-08-12 15:28:59 +01:00
Narasimha-scandEvgeny 486c2abf26 ui: connect when a SimpleX link is pasted as a markdown hyperlink (#7348)
* ui: connect when a SimpleX link is pasted as a markdown hyperlink

* remove comments

Co-authored-by: Evgeny <evgeny@poberezkin.com>

---------

Co-authored-by: Evgeny <evgeny@poberezkin.com>
2026-08-12 14:54:45 +01:00