Pro backend 0.2 + libsession 1.7 compatibility updates - #63
Merged
jagerman merged 19 commits intoJul 28, 2026
Conversation
Bump the libsession-util submodule from 99f1b52 (v1.6.0-10) to 73e4d1e6
(v1.6.3-24, jagerman/libsession-util `pro-backend-updates-final`) — the FINAL
PIN for the Session Pro wire-format redesign. This brings the redesigned
session::pro_backend free-function API (request builders returning
{endpoint, body}, paired response parsers, provider_urls, opaque payment_id,
ms->seconds, revocation_tag) plus the renamed protobuf/config fields.
The N-API glue (src/pro/*, src/constants.cpp, types/pro/pro.d.ts) still
targets the OLD API and will NOT build until reworked to match — done in
follow-up commits.
Needs `git submodule update --init --recursive` inside libsession-util before
building.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
libsession stopped shipping provider display metadata (store/platform/account NAMES are translation data owned by each client; the per-provider URLs move to an on-demand ProWrapper.providerUrls(code) lookup). Remove the make_provider block + LIBSESSION_PRO_PROVIDERS constant; keep the general LIBSESSION_PRO_URLS. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rebind the ProWrapper N-API surface to session::pro_backend's redesigned
free-function API (libsession is now the single source of truth for both
request bodies and response parsing).
Requests (include/pro/pro.hpp): proProofRequest / proRevocationsRequest /
proStatusRequest now drop the wire `version`, take whole-second timestamps
(ms->seconds at the boundary), widen ticket to 64-bit, and return
{endpoint, body} (ProRequest) instead of a bare body string.
Responses (NEW): parseProProofResponse / parseRevocationsResponse /
parsePaymentDetailsResponse marshal the parsed C++ structs to JS — so desktop
deletes its zod wire schemas and consumes these instead. status/user-status
enums are surfaced as their raw ints (they line up 1:1 with the desktop
numeric enums); provider/plan are opaque wire slugs; payment collapses to one
opaque payment_id; timestamps emit ms (JS domain).
Provider URLs: NEW providerUrls(code) -> the 5 support/management URLs or null.
Display NAMES are gone from libsession (client i18n owns them).
pro.cpp: drop the now-dead provider/plan/status enum->string helpers (only the
pro-features status helper remains).
Config glue caught by the same re-pin (proof/convo/user-profile fields):
- pro/types.hpp ProProof: gen_index_hash->revocation_tag, expiry ms->seconds
at the C++ boundary (JS keeps genIndexHashB64/expiryMs).
- convo_info_volatile_config: pro_gen_index_hash->pro_revocation_tag,
pro_expiry_unix_ts now whole seconds.
- user_config: proof.revocation_tag, proof.expiry_unix_ts seconds, and
get/set_pro_access_expiry now whole seconds (ms<->seconds at the boundary).
types/pro/pro.d.ts + shared.d.ts: drop ProOriginatingPlatform /
ProBackendProviderConstant* / LIBSESSION_PRO_PROVIDERS; add ProRequest, the
response-parser return types, ProviderUrls, and the new method signatures.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…/PUBKEY) Bump the vendored libsession submodule 73e4d1e6 -> 857783e6 (the FINAL PIN) and adapt to the two changes since 73e4d1e6: - get-details `status` / `user_status` are now opaque string codes (the SESSION_PRO_BACKEND_PAYMENT_STATUS / _USER_PRO_STATUS enums were deleted): parsePaymentDetailsResponse now emits them as pass-through strings (item status: unredeemed/redeemed/expired/revoked; userStatus: never/active/expired). error_report stays a numeric enum. pro.d.ts retyped. - Expose the new libsession-owned backend identity so desktop stops hand-carrying its own: LIBSESSION_PRO_BACKEND_URL (session::pro_backend::URL, the overridable prod default) + LIBSESSION_PRO_BACKEND_PUBKEY_HEX (hex of session::pro_backend::PUBKEY) on the CONSTANTS wrapper; declared in shared.d.ts. Desktop will read these and derive X25519 on the fly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ring
The response wire format is a contract between libsession and the backend only;
the client must not parse or even assume it's JSON. So parseProProofResponse /
parseRevocationsResponse / parsePaymentDetailsResponse now take { body: Uint8Array }
(the raw response bytes relayed from the network) instead of { json: string }, and
hand the bytes straight to libsession's parser as a string_view over the buffer.
Desktop can relay its onion bodyBinary through with zero decoding — a future
wire-format change (e.g. bt-encoding) touches backend + libsession + this glue only.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…, not seconds libsession-util-nodejs should hand nodejs values in nodejs's units (milliseconds), converting from C++'s natural seconds — not push C++ units onto the JS side. parseRevocationsResponse: - retryInS (seconds duration) -> retryAtMs: the absolute retry-at instant in ms (`system_clock::now() + max(retry_in, 0)`, same wall clock as JS Date.now() since same process). Subsumes desktop's `Math.max` + `Date.now() + retry_in*1000` — the caller now feeds retryAtMs straight to updateNextRunAtMs. - retainForS (seconds) -> retainForMs (ms). Stays a duration (applied per item as seenAt + retainForMs), just in ms. pro.d.ts GetProRevocationsResponse updated to retryAtMs/retainForMs. (All other pro glue timestamps/durations already emit ms; these two were the stragglers.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e, PUBKEY_X25519)
Bump vendored libsession 857783e6 -> 418cdaba and adapt to that pin:
- C++ response/proof/config members renamed `*_unix_ts` -> `*_at` (no wire change):
update every read — GetProDetailsResponse.expiry_at/refund_requested_at,
ProPaymentItem.{purchased,redeemed,expiry,platform_refund_expiry,revoked,
refund_requested}_at, ProRevocationItem.effective_at, ProProof.expiry_at,
convo pro_expiry_at, ProConfig proof.expiry_at. JS field names/units unchanged
(still ms). (get/set_pro_access_expiry were not renamed.)
- ProRequest now carries content_type: expose it as `contentType` on the request
builders' output so clients set Content-Type from libsession, not a hardcoded
format. (C++ payload member is `data`; still surfaced under the JS key `body`.)
- Add LIBSESSION_PRO_BACKEND_PUBKEY_X25519_HEX (to_hex(pro_backend::PUBKEY_X25519))
so desktop reads the X25519 pubkey from libsession instead of deriving it.
- .d.ts updated: ProRequest.contentType, ConstantsType.LIBSESSION_PRO_BACKEND_PUBKEY_X25519_HEX.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…lope Re-pin libsession submodule 418cdaba -> a9e790a8 (Delta session-foundation#12). Response envelope is now a closed status enum + optional error_code slug + optional single diagnostic error, replacing the numeric status + errors[]: - emitResponseHeader() renders the C++ ResponseBase: status as its wire string ("ok"/"fail"/"error"), error_code/error (std::optional<string> -> string|null); drops errorsToJs. - pro.d.ts WithProResponseHeader: { status: 'ok'|'fail'|'error'; errorCode: string|null; error: string|null }. Desktop consumers re-key success to status === 'ok' (app repo). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…fix decode_for_community ms->s Add ProWrapper.visiblePlatforms() returning the purchasable provider slugs. Bump the libsession-util submodule a9e790a8 -> c6e5a210. Delta session-foundation#13 changed session::decode_for_community's timestamp param to sys_seconds, so convert nowMs accordingly in encrypt_decrypt. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…bsession revocation_tag) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The glue converted every libsession Pro timestamp to the JS millisecond domain by hand-writing `.time_since_epoch().count() * 1000` (for the sys_seconds fields) while deliberately omitting the *1000 for the two sys_ms fields (purchased_at/revoked_at). That left correctness resting on the author remembering each field's C++ resolution — a *1000 accidentally applied to a sys_ms field is an instant 1000x bug, and passing a sys_seconds straight to toJs() silently emits seconds into a `...Ms` key. Add toJsMs() overloads (a sys_ms time_point and a milliseconds duration) that rely on chrono's implicit, lossless widening: sys_seconds -> sys_ms and std::chrono::seconds -> milliseconds both convert at the call site, so every field routes through one helper with no hand-multiplication. purchased_at/ revoked_at stop being special cases. A finer-than-ms source (e.g. sys_time<microseconds>) fails to compile rather than silently truncating. No behavioural change: every emitted value is the same millisecond quantity as before. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bilb
reviewed
Jul 22, 2026
… caveat) session-desktop persists this shape to local storage and reads it back cast to this type. Adding an OPTIONAL field is always safe; adding a REQUIRED field needs a transition on the desktop read side (stale caches from older builds). Comment only; points at the reminder in session-desktop's getProDetailsFromStorage. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…n {count,unit}
Re-pin the libsession submodule to 3f8aace0 (stable) and absorb its changes:
- get_pro_details split (Delta session-foundation#15): proStatusRequest now builds pro_status_request
(no count); parsePaymentDetailsResponse -> parseProStatusResponse (parse_pro_status),
emitting userStatus/expiry/grace/refund + a single optional latestPayment (was an
items[] array + paymentsTotal). get_payment_details (history) is not wired.
- plan is now parsed: emit planCount + planUnit ("second".."lifetime") instead of the
raw "1m"/"1y" slug.
- string8 removed from libsession: drop the toJs_impl<string8> specialisation (the URL
bundle fields are now const char*, handled by the string_view overload).
- .d.ts: GetProDetailsResponse -> GetProStatusResponse (latestPayment, no items/total),
ProPaymentItem plan -> planCount/planUnit, parse rename.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The wire spec (docs/pro-wire-protocol.md) dropped its Delta-N change-history annotations, so every 'Delta #N' citation was a dangling reference. Reworded each to the current section (envelope -> §5/§5.1/§5.2, plan grammar -> §1, get_pro_status -> §3.4) or dropped the parenthetical where there is no section. Verified all remaining pro-wire-protocol § references resolve. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The refactor merged upstream (session-foundation/libsession-util dev, to become v1.7.0). Move the submodule off the now-orphaned WIP commit 3f8aace0 (rebased away before merge) to the current dev tip d63deea5, which includes the refactor plus the Pro backend integration tests + CI. The pro API is identical to 3f8aace0 (only Delta-citation comments differ), so no glue code changes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bilb
approved these changes
Jul 27, 2026
…n clamp) Pulls in the revocation-list retry_in/retain_for clamp (7d422cfd) now done in libsession's parse_revocations, plus its merge (#102) and the seed_payment obfuscated-account-id test fix. Lets clients drop their own client-side clamps. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Node/N-API counterpart of the Pro glue changes: same wire contract, converting to JS-idiomatic types (ms numbers). Re-pins
libsession-utiltoc6e5a210.This is required for Session Desktop compatibility with session-foundation/session-pro-backend#2 and session-foundation/libsession-util#95.
Changes
status('ok'|'fail'|'error'),errorCode(string|null), anderror(string|null); drops theerrors[]array.visible_platforms(): newProWrapper.visiblePlatforms(): string[](N-API +.d.ts) returning the purchasable provider slugs.session::decode_for_communitynow takessys_seconds, so convertnowMs → secondsinencrypt_decrypt(glue build fix; no behavior change).