Slatepack: node-independent manual transaction transport#2076
Open
Maxnflaxl wants to merge 10 commits into
Open
Slatepack: node-independent manual transaction transport#2076Maxnflaxl wants to merge 10 commits into
Maxnflaxl wants to merge 10 commits into
Conversation
Adds TxParameterID::ManualTransport (private, never serialized) and a virtual BaseMessageEndpoint::AcceptsMessage hook. The SBBS endpoint now skips transactions flagged for manual transport, so they can be routed over the upcoming Slatepack armored transport instead. Groundwork for reviving offline transaction exchange.
Adds slatepack::Armor/Unarmor - a Slatepack-style ASCII-armored envelope (BEGINSLATEPACK. ... .ENDSLATEPACK.) wrapping a version+type header, an arbitrary payload, and a 4-byte double-SHA256 error-detection code, base58 encoded and whitespace-grouped for readability. Tolerant of surrounding text and reflowed whitespace on parse. Includes the TxNegotiation payload (recipient WalletID + SBBS ciphertext) and its serialization. The codec is deliberately dependency-free (no Rules/global state) so it unit-tests against wallet_core alone. Network discrimination is handled downstream by channel matching, not an armor-header byte.
An IWalletMessageEndpoint that routes ManualTransport-flagged transactions off SBBS: outgoing negotiation messages are queued and surfaced as armored Slatepack strings via a callback, and Inject() feeds a pasted Slatepack back through the standard ProcessMessage path (channel match + decrypt + hand to the negotiator). Mirrors the WalletNetworkViaBbs structure (own-address subscription, address-change observer) minus the node/BbsProcessor parts, reviving the deleted cold-wallet endpoint pattern with armored strings in place of DB shuttling.
… exchange test The integration test exposed that a private (>=128) ManualTransport flag never crosses the wire, so the receiver's side of a manual tx fell back to SBBS for its S2 reply - the exchange only half-avoided the node. Fix: - move ManualTransport to a public tx parameter (119), - include it in the negotiation message when set (simple_transaction), - whitelist it as externally-settable so the peer adopts it and routes its own replies via Slatepack too. Adds slatepack_exchange_test: two node-connected wallets complete a simple transfer entirely over armored Slatepacks with no SBBS endpoint carrying the negotiation, asserting both S1 and S2 crossed the manual transport and the funds moved.
Registers a SlatepackEndpoint alongside the SBBS one in the live wallet client; outgoing manual-transport negotiation messages surface via a new onSlatepackReady(txID, armored) callback, and a pasted Slatepack is fed back in through the async importSlatepack() -> onSlatepackImportResult(ok, error). This is the bridge the desktop UI drives.
Import decrypts and previews a Slatepack without continuing the transaction; the user confirms (Send) or discards (Cancel). Harden SlatepackEndpoint against cancel/failure notifications and ProcessStoredMessages replays, and report a decrypted tx summary for the UI.
Maxnflaxl
force-pushed
the
feat/slatepack
branch
from
July 18, 2026 10:21
88af8b5 to
d4b022e
Compare
…ck import command
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.
Summary
Adds Slatepack, an armored, copy-pastable transport for Beam transaction negotiation that needs no SBBS relay or node connectivity. It revives the node-independent exchange that Beam lost when the cold-wallet feature was removed in Jan 2020 (
973d826d5). Closes the long-standing request in #593.A Slatepack is an ASCII-armored envelope:
The body is
version(1) + type(1) + payload + checksum(4), base58-encoded. It is safe to paste into chat, email, a file, or a QR code, and a damaged or wrong blob fails fast on the checksum / version / type discriminators.Design
Queued-message endpoint, not Grin-style explicit slate states. A Slatepack wraps one internal negotiation message; importing one feeds it through the same consumer path an SBBS message takes, so the entire existing transaction machinery (simple, max-privacy, offline/voucher) works over the new transport by construction — no duplicated negotiation plumbing.
TxParameterID::ManualTransport(public param119,bool) flags a transaction for manual routing. It is whitelisted inIsTxParameterExternalSettableand propagated to the peer, so the peer also routes its replies manually instead of leaking them back onto SBBS.BaseMessageEndpoint::AcceptsMessageis a new routing hook: the SBBS endpoint skipsManualTransporttransactions, andSlatepackEndpointhandles only those — both endpoints run at once without duplicating traffic.SlatepackEndpointqueues each outgoing negotiation message and surfaces it as an armored string via a callback; a pasted Slatepack is decrypted for a preview first (amount / fee / addresses) and only handed to the wallet on explicit confirm.Security notes
proto::Bbs::Encryptpath, so a Slatepack posted in a public channel reveals only its type and size.Testing
slatepack_test— armor round-trip, whitespace tolerance, and rejection of truncated / checksum-corrupted / wrong-version / wrong-type blobs.slatepack_exchange_test— two wallets complete a full S1/S2 negotiation with no SBBS, exchanging Slatepacks only.Follow-up
The desktop UI ships as a separate PR against
beam-uithat bumps the beam submodule to this branch's merge commit. That PR must not merge until this one does.