TurboWarp-WebRTC-QRCode-Pairing

A TurboWarp extension that pairs WebRTC peers by carrying the offer and the answer optically, as QR codes.

How the workflow runs

  1. The integration machine creates an offer and cycles its QR codes on the projection.
  2. A camera machine reads the codes in any order until it has them all, accepts the offer, and shows the answer QR codes on its screen.
  3. An operator photographs every answer code with a smartphone and carries the images back.
  4. The integration machine scans those images, accepts the answer, and reports the connection.

No signaling server and no app on the smartphone: showing the photographed image is enough.

Before you start

A projected pairing code is visible to everyone who can see the projection. The QR hash detects damage; it does not authenticate the other machine.

Documentation

TurboWarp-WebRTC-QRCode-Pairing: complete block reference

All 31 blocks are documented below, including compatibility blocks and blocks available through optional features. Select a block to read its behavior, arguments, default values, and menu choices. Each block has a permanent link.

start offer pairing [SESSION] as [LOCAL_PEER] to [REMOTE_PEER]

Creates a WebRTC offer for the integration machine and prepares it as a Structured Append sequence of QR codes.

Block type: COMMAND. Opcode: startOfferPairing. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1
LOCAL_PEERSTRINGhub
REMOTE_PEERSTRINGcamera-1

start answer pairing [SESSION] as [LOCAL_PEER]

Waits for an offer on the camera machine. Leave the name empty to adopt the name the offer assigns.

Block type: COMMAND. Opcode: startAnswerPairing. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1
LOCAL_PEERSTRING

receive pairing message [TEXT] for [SESSION]

Accepts a whole pairing message as text, such as one pasted or carried some other way. Camera scanning reads the QR codes of a sequence itself.

Block type: COMMAND. Opcode: ingestPairingQrText. Permanent link

ArgumentTypeDefault valueMenu choices
TEXTSTRING
SESSIONSTRINGpairing-1

scan pairing QR for [SESSION] from camera [CAMERA_ID]

Reads QR codes from the named camera, in any order, until the exchange has every code of the sequence. Codes of other sequences are reported and ignored.

Block type: COMMAND. Opcode: scanPairingQrFromCamera. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1
CAMERA_IDSTRINGdefault

received parts of [SESSION]

Returns how many distinct codes of the incoming sequence have been read.

Block type: REPORTER. Opcode: pairingReceivedParts. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

required parts of [SESSION]

Returns how many codes the incoming sequence has, or zero before the first code arrives.

Block type: REPORTER. Opcode: pairingRequiredParts. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

missing parts of [SESSION]

Returns the one-based code numbers that have not been read yet, separated by commas.

Block type: REPORTER. Opcode: pairingMissingParts. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

pairing QR reads of [SESSION]

Returns how many pairing QR codes this session has read, of any result. It rises by one per read, so a change means there is a new result to show.

Block type: REPORTER. Opcode: pairingReadCount. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

last pairing QR read of [SESSION]

Returns what the latest pairing QR code was: accepted (a new code of the sequence), duplicate (a code already read), foreign (a code this exchange cannot use, which is ignored), or an empty string before the first read. QR codes that are not pairing codes are not reported.

Block type: REPORTER. Opcode: pairingLastRead. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

last pairing QR read detail of [SESSION]

Returns the code as "2 / 4" for accepted and duplicate reads, or why a foreign code was ignored as an error code such as message-mismatch (another sequence), stale-exchange or peer-mismatch.

Block type: REPORTER. Opcode: pairingLastReadDetail. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

show pairing QR part [INDEX] of [SESSION] on this sprite

Shows the selected one-based code of the sequence using a temporary sprite skin.

Block type: COMMAND. Opcode: showPairingQrPart. Permanent link

ArgumentTypeDefault valueMenu choices
INDEXNUMBER1
SESSIONSTRINGpairing-1

show next pairing QR part of [SESSION] on this sprite

Shows the next code and wraps from the last back to the first, so a loop with a short wait cycles the whole sequence.

Block type: COMMAND. Opcode: showNextPairingQrPart. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

pairing QR part count of [SESSION]

Returns how many codes are prepared for display, or zero when none are.

Block type: REPORTER. Opcode: pairingQrPartCount. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

current pairing QR part of [SESSION]

Returns the one-based code selected for display, or zero when none is selected.

Block type: REPORTER. Opcode: pairingQrCurrentPart. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

pairing QR part [INDEX] of [SESSION] as SVG

Returns the code as SVG markup so a project can display it its own way.

Block type: REPORTER. Opcode: pairingQrPartSvg. Permanent link

ArgumentTypeDefault valueMenu choices
INDEXNUMBER1
SESSIONSTRINGpairing-1

pairing QR part [INDEX] of [SESSION] as data URI

Returns the code as a base64 SVG data URI for costumes and HTML images.

Block type: REPORTER. Opcode: pairingQrPartDataUri. Permanent link

ArgumentTypeDefault valueMenu choices
INDEXNUMBER1
SESSIONSTRINGpairing-1

end pairing QR display of [SESSION]

Restores the sprites this session changed. The session itself stays open.

Block type: COMMAND. Opcode: endPairingQrDisplay. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

pairing phase of [SESSION]

Returns the session phase, such as offer-ready, receiving, answer-ready, connecting, or connected.

Block type: REPORTER. Opcode: pairingPhase. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

pairing connection state of [SESSION]

Returns the WebRTC connection state reported for this session's peer.

Block type: REPORTER. Opcode: pairingConnectionState. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

pairing [SESSION] connected?

Reports whether WebRTC has established the connection for this session.

Block type: BOOLEAN. Opcode: isPairingConnected. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

wait until pairing [SESSION] is connected

Waits for the connection, or fails when the session is cancelled, times out, or fails.

Block type: COMMAND. Opcode: waitUntilPairingConnected. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

pairing error code of [SESSION]

Returns the latest error code, such as hash-mismatch or peer-mismatch, or an empty string.

Block type: REPORTER. Opcode: pairingError. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

pairing error message of [SESSION]

Returns the latest error message. Pairing codes and QR payloads are never included.

Block type: REPORTER. Opcode: pairingErrorMessage. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

local peer of [SESSION]

Returns the name this machine uses for itself in this exchange.

Block type: REPORTER. Opcode: pairingLocalPeer. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

remote peer of [SESSION]

Returns the name this machine uses for the other machine, which is also its WebRTC peer name.

Block type: REPORTER. Opcode: pairingRemotePeer. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

exchange id of [SESSION]

Returns the identifier of the current offer and answer exchange. A retry allocates a new one.

Block type: REPORTER. Opcode: pairingExchangeId. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

remaining seconds of [SESSION]

Returns the seconds left before the exchange times out.

Block type: REPORTER. Opcode: pairingRemainingSeconds. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

pairing sessions

Returns the open session names, separated by commas.

Block type: REPORTER. Opcode: pairingSessions. Permanent link

This block has no arguments.

cancel pairing [SESSION]

Cancels the exchange and releases displays, buffers, and unconnected peers. Established connections stay up.

Block type: COMMAND. Opcode: cancelPairing. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

retry pairing [SESSION]

Starts a new exchange for the same session. QR codes from the previous exchange stop being accepted.

Block type: COMMAND. Opcode: retryPairing. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1

set pairing timeout of [SESSION] to [SECONDS] seconds

Sets how long the exchange waits, measured on this machine's own clock.

Block type: COMMAND. Opcode: setPairingTimeout. Permanent link

ArgumentTypeDefault valueMenu choices
SESSIONSTRINGpairing-1
SECONDSNUMBER600

Repository guide and examples

Fixed input editing

With a compatible TurboWarp GUI, enable fixed-input forms to edit only standard literal fields. Numbers use complete finite JSON number tokens; menu fields use existing choices. Connected reporters and unavailable fields stay read-only and are never evaluated. Saving an unchanged form preserves exact existing raw values, including legacy spellings and unknown choices. Invalid drafts stay in the same editing session; cancel, project/target replacement, or block removal discards them. Disabling the GUI feature flag restores native field editing. This form does not run blocks, open network/audio/key/QR sessions, resolve names, or edit Schema arguments. QR index is a positive integer without a session-derived candidate limit. Timeout remains 1–3600 seconds.