Skip to content

feat: adopt MoonProto 11d170a1 — core Telegram reader, ms report timestamps, BUY refresh - #545

Merged
kirillDevPro merged 9 commits into
mainfrom
feat/moonproto-telegram-ms-buy-refresh
Sep 13, 2026
Merged

feat: adopt MoonProto 11d170a1 — core Telegram reader, ms report timestamps, BUY refresh#545
kirillDevPro merged 9 commits into
mainfrom
feat/moonproto-telegram-ms-buy-refresh

Conversation

@kirillDevPro

Copy link
Copy Markdown
Collaborator

What & why

MoonProto 11d170a1 added three things the terminal had no surface for. This PR adopts all three and cleans up what they made redundant:

  • Core Telegram reader from Settings. The core's built-in Telegram reader (enable/disable, phone or QR login, codes, 2FA, e-mail and registration steps, SOCKS5/MTProto proxy, resend with countdown, logout) used to need a remote desktop session to the core's machine. Settings → Telegram now has two sub-tabs: Terminal bot (the existing bot/access/chats/Mini App boxes, unchanged) and Telegram on core (a core picker plus the whole flow driven by the core's own full-state snapshots). Auth controls render only while the core connection is live AND its Telegram snapshot is fresh (ConnStatus::Ready alone never implies a current snapshot). No secret is stored or logged; a static contract keeps qr_link/password/secret out of every log call. Logout is the one confirmed action (it resets the shared account for every MoonBot process on that machine). QR is encoded locally with the qrcode crate — the only Cargo.lock addition besides the moonproto pin.
  • Millisecond report timestamps. BuyDateMs / SellSetDateMs / CloseDateMs are kept in the replica as nullable integers (NULL stays NULL, CloseDateMs = 0 is the "still open" sentinel, never a date). ReportStamp::resolve is the one home of the per-column preference rule; ReportAxis::to_utc_ms applies the core-timezone correction to the seconds part exactly once. Chart trade marks, the trade-replay window, the chart tooltip and the trade window's figures rail use the ms value when present and print .mmm; older cores and rows behave as before. The three columns join display_columns' SERVICE list so they never surface in the Report grid or CSV. With real ms times available, the PR fix(trade-window): keep the closed trade on the tape #457 tape-snapping workaround (snap_mark_to_tape, LiveTradeSnap, TapePrint, the tick cursor) is removed entirely — marks sit at the report's own time, the tape is still drawn.
  • "Save and refresh BUYs" in Strategies. A second action beside Apply routes a MoonShot field edit through sync_local_strategies_and_apply_to_orders for that one submission, so the core re-places standing BUYs after an OrderSize / Short / EmulatorMode / AutoCancelBuy change. Enabled only for MoonShot-kind strategies with such a draft; every other sync path stays unflagged; EditConfirmed still confirms settings only.

Also: the core picker menu is sized to the core names, the "Core parameters" disclosure is one full button, and the Settings tab body measures expanded content at intrinsic height so a long section is never clipped above the footer.

Not in this PR: MoonProto c6f9006 (per-order stops) — it needs a core that is not released yet.

How to verify

  • cargo test --workspace (moon-core 1955, moonterminal 1804, theme_contract 333, moon-chart 122), cargo fmt --all -- --check, cargo clippy — all green on the branch head.
  • Live on core 7.67.0.12: Settings → Telegram → Telegram on core → pick a core → Core parameters: "Service online", state wait_phone, phone/QR step rendered. (Logging in acts on the real account — not exercised here.)
  • Report → double-click a closed trade: the trade window's Opened/Closed show .mmm, marks sit on those times with no tape snapping.
  • Strategies → a MoonShot strategy → change EmulatorMode → the Save and refresh BUYs button enables; on an EMA strategy it stays disabled.

Brings the core Telegram reader controls, the millisecond report
timestamp columns and the apply-to-standing-orders strategy sync.
Only the moonproto stanza moves; every transitive edge stays where the
committed lock had it, proven by cargo fetch --locked.
A MoonShot user who changes OrderSize, Short, EmulatorMode or
AutoCancelBuy today keeps the old standing BUYs until they cancel on
their own. MoonProto 11d170a1 lets the same strategy snapshot carry a
one-shot refresh flag, so the Strategies window gains a second action,
"Save and refresh BUYs", enabled only when the pending edits touch one of
those four fields on a MoonShot strategy. The flag travels with that one
submission through CoreCmd::EditStrategyFields to
sync_local_strategies_and_apply_to_orders; every other sync path stays
unflagged, and EditConfirmed still confirms settings only.
…crutch

Cores can now send the optional integer report columns BuyDateMs, SellSetDateMs
and CloseDateMs beside the existing whole-second ones. The replica keeps them
faithfully: the append-only schema path adds them as nullable integers, and a
row whose upsert omits a column leaves it NULL rather than inventing a value.
Nothing is backfilled and milliseconds are never derived from seconds.

Where a second-aligned time used to be the best available, the millisecond one
is used instead: the chart's closed-trade marks, the trade-replay window, the
chart's trade tooltip and the trade window's figures rail, which now print .mmm
when the core supplied it and nothing extra otherwise. Older cores and rows
already stored behave exactly as before, through the seconds columns.

The rules that make that safe live in one place each. ReportStamp::resolve is
the only home of the per-column preference rule, so CloseDateMs = 0 -- the
wire's "still open" sentinel -- can never be read as a 1970 date.
ReportAxis::to_utc_ms applies the core-timezone correction to the seconds part
exactly once and re-attaches the sub-second remainder, because to_utc corrects
seconds and feeding it milliseconds is wrong by a factor of a thousand.
stamp_pair_to_utc_ms reconciles a trade whose two columns resolve independently
into one second -- an exact entry with a seconds-only exit would otherwise read
as a trade that closed before it opened, and go unreplayable.

The three new columns are replication detail, not facts of their own, so they
join the service list that keeps them out of the Report grid's column menu and
its CSV export. No query plan, ORDER BY or LIMIT changed; the open/closed
partition and every sort still read the seconds columns.

With real millisecond times available, the workaround that nudged entry and
exit arrows onto nearby public trade prints is no longer needed and is removed
in full, on the chart and in the Report's trade window alike. Marks sit at the
time the report gives. The tape is still drawn; it simply no longer moves
anything. The replay window's seconds entry point goes the same way, its only
caller having moved to milliseconds, and the moon-core tick cursor that existed
solely to feed the snap goes with it.
MoonProto 11d170a1 exposes the core's built-in Telegram reader: enable
and disable, phone or QR login, verification codes, the two-factor
password, the email and registration steps, a SOCKS5 or MTProto proxy,
code resend and logout. Until now every one of those needed a remote
desktop session to the core's machine.

Settings -> Telegram gains a second section for a picked core that
drives the whole flow from the core's own full-state snapshots: each
snapshot replaces the shown state, an unknown auth step renders as
unsupported with a refresh instead of guessing an input, and the
authentication controls appear only while the core connection is live
AND its Telegram snapshot is fresh, so a pre-outage QR or code step can
never become actionable off a stale snapshot. The QR is encoded here
from the tg://login link with the qrcode crate and drawn as a module
grid; it disappears the moment the step changes or the core drops.

No secret is ever stored or logged: phone, code, password, email and the
proxy password or MTProto secret are typed, sent and cleared from their
inputs, and a static contract keeps qr_link, password and secret out of
every log call in the new files. Logout is the one confirmed action,
because it resets the shared account for every MoonBot process on that
machine; disabling the reader on this core does not log anyone out.

Cargo.lock gains only the qrcode crate and its own entries.
The docstring audit over the three merged goals: the core-Telegram
auth-controls helper now states that its liveness input already folds
in the freshness latch, and the replay-source predicate no longer
mentions the removed tape snapping.
@kirillDevPro
kirillDevPro merged commit 087a17b into main Sep 13, 2026
6 checks passed
@kirillDevPro
kirillDevPro deleted the feat/moonproto-telegram-ms-buy-refresh branch September 13, 2026 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant