← Book map

Chapter 05 · Transport

Flags are the table of contents

The envelope is the stable outer shape; the request adds the reply channel. Both are just buffers whose flags tell the parser what comes next.

Envelope to generic request A generic envelope carries version, flags, optional signature, request id, created at, salt, app id and details. A generic request adds response URIs, an encryption address and a preferred handler. GenericEnvelope version flags signature? requestID? createdAt? salt? appOrDelegatedID? details: OrdinalVDXFObject[] GenericRequest extends GenericEnvelope responseURIs? encryptResponseToAddress? preferredHandler Flags 128, 256 and 512 exist only on the request layer — the response has no way to ask for a callback.

FIGURE 5.1 · The composition, not inheritance-by-accident.

The envelope is the stable core

GenericEnvelope exists so that every request and response shares one outer shape. Version, flags, optional signature, optional request id, optional timestamp, optional salt, optional app or delegated identity, and a details array. The flags are the table of contents for the bytes that follow.

FLAG_SIGNED                1     signature present
FLAG_HAS_REQUEST_ID        2     requestID present
FLAG_HAS_CREATED_AT        4     createdAt present
FLAG_MULTI_DETAILS         8     more than one detail object
FLAG_IS_TESTNET           16     VRSCTEST semantics
FLAG_HAS_SALT             32     salt present
FLAG_HAS_APP_OR_DELEGATED_ID 64  acting on behalf of an app/identity
FLAG_DETAILS_ARE_ENCRYPTED 1024  details are an AEAD payload

GenericRequest adds the reply channel

The three request-only flags are the interesting ones, because they describe how the response comes back: FLAG_HAS_RESPONSE_URIS (128) carries one or more POST destinations, FLAG_HAS_ENCRYPT_RESPONSE_TO_ADDRESS (256) asks for the response to be encrypted to a Sapling address, and FLAG_HAS_PREFERRED_HANDLER (512) picks the wallet application (0 = Verus Mobile, 1 = Valu mobile).

Deeplink and QR are the same bytes

toWalletDeeplinkUri()  →  verus://1/<base64url(toBuffer())>
toQrString()           →  <base64url(toBuffer())>
fromWalletDeeplinkUri  ←  parses protocol, version, payload
fromQrString           ←  parses payload only

This is the moment the library stops being abstract: a QR code in the Verus mobile app is exactly a base64url-encoded buffer produced by this class. Nothing is signed at the URL level; the URL is just a carrying case.

If a scanner rejects a deeplink, check the version segment before anything else — the parser requires verus://1/ exactly, and a mismatched count of path segments throws "Unrecognized URL format".

Reading the code

src/vdxf/classes/envelope/GenericEnvelope.ts   # flags, details, salt, signature
src/vdxf/classes/request/GenericRequest.ts     # + responseURIs, encryptResponseToAddress, handler
src/vdxf/classes/ResponseURI.ts                # uri + type (POST)
src/constants/deeplink.ts                      # "verus", version 1, handler ids