Skip to content

feat: add transfer progress and import exit protection - #13534

Open
sidmorizon wants to merge 7 commits into
xfrom
codex/prime-transfer-client-error-codes
Open

sidmorizon wants to merge 7 commits into
xfrom
codex/prime-transfer-client-error-codes

Conversation

@sidmorizon

@sidmorizon sidmorizon commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Large wallet transfers can spend a long time on slow networks without showing how much data has arrived. This change adds network-transfer percentages on both devices and protects active transfers and imports from accidental dismissal.

Changes

  • Keep loading feedback during data preparation, then show acknowledged/received byte progress during chunked network transfer. After delivery, the receiving device continues to the wallet/account preview and its separate import progress.
  • Negotiate chunk support with both the relay and peer, and require room for the complete 72 KiB v1 chunk packet allowance. Smaller advertised relay limits select the existing single-message path and its preflight. Use 64 KiB encrypted Base64 chunks with a 64 MiB encoded-payload limit, bounded concurrency, acknowledgement checks, cancellation, and timeouts. Older relays or peers retain the existing single-message transport and loading feedback.
  • Disable transfer direction changes and route gestures during the transfer flow. Add foreground/unlocked reminders, prevent import-dialog drag/overlay dismissal, and require confirmation before leaving an active import. Reserve a task before cancellable preparation, retain its ID through decryption and import, and invalidate it synchronously on confirmed exit. Prevent stale cleanup or a pending exit confirmation from cancelling/reopening a later task; outstanding writes must settle before another import can start. Recheck task ownership before and after each import step, including awaited trace recording, and immediately after mnemonic encoding or TON credential encryption before starting a write. Cancelling during credential preparation cannot create another wallet/account or save a TON credential; an already-started persistence operation is allowed to settle without subsequent writes.
  • Add a guarded Dialog close hook and adapt its cloud-backup callers. Preserve request IDs and C2C reply metadata for parameter (1001) and throttling (1100) errors.
  • Count every chunk attempt against the receiver's 512/second quota before validation. Return one 1100 for excess traffic in a window, then drop subsequent chunks without inspecting payloads or emitting more error responses. Preserve cancellation and per-receiver isolation.
  • Validate canonical Base64 in both the bridge and assembler: complete quartets, legal padding, zero unused padding bits, and padding only in the final chunk. Keep valid 64 KiB sender boundaries and out-of-order assembly.
  • Check the 64 MiB encoded total before beginning chunk transfer. For legacy fallback, measure the full encoded Socket.IO message against a valid advertised relay limit and reject oversized packets before emitting wallet data. When the relay does not advertise a valid limit, preserve the original single-message send behavior without imposing a guessed 10 MiB cap. Include localized size/limit feedback for known limits.
  • Register the four added runtime modules with fixed IDs so strict native union builds complete without relaxing budgets.
  • Include the approved size-limit error in all 19 locales. Existing transfer/import guidance is present in the latest base catalog; generated translations were pulled and verified, not manually edited.

Compatibility

Chunked progress is enabled only when the server and both clients support it. Relay capability support is provided by e2ee-server #28; this App change does not deploy that server update. Legacy transfers retain their existing payload limits and do not gain byte percentages. Size preflight is available only in updated senders and only when the relevant limit is known. Older relays with unadvertised custom limits remain compatible: for example, all four old/new client directions can send 12 MiB through a relay configured for 20 MiB. Unknown-limit legacy sends remain subject to the actual server limit, so an oversized send can still fail at the relay instead of being rejected locally before transmission. Capability-probe failures fall back only for the recognized missing-method response; other errors and timeouts remain failures.

Validation

  • Import cancellation follow-up: 31 tests passed across the real import-service and exit-confirmation suites. Before the fix, 11 cases reproduced writes after cancellation; after the fix all pass. Coverage includes HD decryption (both local-password paths), mnemonic encoding, imported-account decryption/export/fallback, TON decryption/password/encryption, cancellation during pre-write tracing, an in-flight wallet write, normal completion, and preservation of active credential errors.

  • Required commit gate and PR local gate pass: lint, formatting, TypeScript, background API contracts, and native-storage/context checks.

  • Earlier transfer/service validation: 90 tests passed, covering missing/invalid/advertised relay limits, a 12 MiB legacy send with an unknown or sufficient limit, rejection before emit for a known 10 MiB limit, exact packet overhead, chunk capability negotiation, flood guards, canonical Base64, cancellation, timeouts, and import task ownership. Dialog and import-exit regression suites passed in the preceding implementation.

  • Latest real Socket.IO source matrix: 54/54 transfers passed across WebSocket-only, polling-only, and polling-to-WebSocket upgrade. New/old relays at 20 MiB each passed all four new/old client directions with 12 MiB payloads (24 cases); both default 10 MiB relays also passed the four directions and v5.18 receiver fallback (30 cases). Tests verify exact delivered bytes, expected legacy/chunk path, live connections, and task cleanup. Relay source revisions: 2c8f19c (PR fix icon color #28) and 91612c3 (old main). Crypto, authenticated pairing, storage/import, and UI are fixtures; these tests do not run installed historical binaries or native split runtimes.

  • Real bridge source matrix: 12 old/new client combinations across WebSocket, polling, and upgrade transports; six Chrome cross-origin/credentials checks; actual 32 MiB transfers in both directions. All pass against e2ee-server fix icon color #28 at 7ef9de7. These are synthetic-data/source-fixture tests, not every historical client binary.

  • Previous head 5249472a12 passed strict iOS union build, fixed-ID map validation, and three-bundle architecture checks: main 2671/3000 modules, 13.27/13.8 MiB; background 2444/2600 modules, 18.38/19.5 MiB. The main budget change to 13.8 MiB comes from x; this PR does not modify budget thresholds. All existing module IDs from both branches are retained.

  • Size-limit copy uploaded, pulled, and verified in all 19 Monorepo v5 locales; final module scan reports no missing translations.

  • Real Socket.IO regression probe: a 32 KiB relay now accepts the same 32,568-byte payload through the production sender method without disconnecting. The default 10 MiB relay still transfers 12 MiB via chunks and 9 MiB via legacy fallback; advertised 20 MiB legacy transfer remains supported. A separate Dialog close-path reproduction confirms error cleanup completes after Cancel is chosen on the pending exit confirmation.

  • git diff --check passes. Device UI was not rerun for this follow-up.

  • The preceding head e5d8dbe0b8 passed all 25 GitHub checks, including Native startup graph budget. The import-cancellation follow-up 3c08d91109 triggers a fresh CI run; its local checks and regression results are listed above.

Related work

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 17, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-17T11:14:53.411183Z 2fdbeaa Manual request
🔒 Security Review Completed 2026-09-22T15:06:45.362733Z 6c96b72 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@sidmorizon

Copy link
Copy Markdown
Contributor Author

@codex review

@sidmorizon

Copy link
Copy Markdown
Contributor Author

@codex security review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2fdbeaaca5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@sidmorizon sidmorizon changed the title fix: distinguish prime transfer client validation errors feat: add transfer progress and import exit protection Sep 17, 2026
@sidmorizon
sidmorizon marked this pull request as draft September 18, 2026 02:22
@sidmorizon
sidmorizon marked this pull request as ready for review September 22, 2026 14:57
@sidmorizon
sidmorizon enabled auto-merge (squash) September 22, 2026 14:57
@sidmorizon

Copy link
Copy Markdown
Contributor Author

View Devin Review ↗️

@sidmorizon

Copy link
Copy Markdown
Contributor Author

@sidmorizon

Copy link
Copy Markdown
Contributor Author

Claude review session: https://claude.ai/code/session_01VYspWvpVdXJnPy7XpXjZJ3

Comment on lines +457 to +460
if (taskUUID) {
await backgroundApiProxy.servicePrimeTransfer.resetImportProgress({
taskUUID,
});

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 P2: Cancelled imports continue writing wallets

Severity: non-severe

When exit is confirmed during credential preparation, resetImportProgress invalidates the task but the pending import resumes into a write. The HD and imported-account paths do not recheck ownership between awaited decryption and their database operations. Wallets or accounts can appear after cancellation.

This branch has not been deployed

No deployments
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