# Relay serialization The WizardConnect relay transmits messages as JSON, which cannot represent `BigInt` or `Uint8Array` natively. `@wizardconnect/core` provides canonical encoding helpers so dapps and wallets always agree on the wire format. The helpers are split into two layers: - **Generic** (`serialize.ts`) — relay-level type coercion (`toUint8Array`, `toBigInt`, `parseExtendedJson`). Useful for any protocol. - **hdwalletv1** (`protocols/hdwalletv1-serialize.ts`) — transaction-specific serialization (`sourceOutputToRelay`, `transactionToHex`). Tied to the sign-transaction flow. ## Encoding conventions | Native type | Relay format | Example | |---------------|-------------------------------------|---------------------------------| | `Uint8Array` | hex string | `"76a914...88ac"` | | `Uint8Array` | extended format (libauth stringify) | `""` | | `BigInt` | extended format | `""` | Both extended formats are accepted by the deserialization helpers. The serialization helpers produce hex strings for `Uint8Array` and `` for `BigInt`. ## hdwalletv1 serialization (dapp → relay) ### `sourceOutputToRelay(sourceOutput)` Converts a source output with native types to relay-safe JSON: ```typescript import { sourceOutputToRelay } from "@wizardconnect/core/hdwalletv1-serialize"; const relayOutput = sourceOutputToRelay({ outpointTransactionHash: txidBytes, // Uint8Array → hex string outpointIndex: 0, // number (unchanged) unlockingBytecode: new Uint8Array(0), // Uint8Array → hex string sequenceNumber: 0xffffffff, // number (unchanged) valueSatoshis: 200000n, // BigInt → "" lockingBytecode: scriptBytes, // Uint8Array → hex string token: { // optional category: categoryBytes, // Uint8Array → hex string amount: 1000n, // BigInt → "" }, }); // relayOutput is JSON-serializable (no BigInt, no Uint8Array) JSON.stringify(relayOutput); // works ``` ### `transactionToHex(inputs, outputs, version?, locktime?)` Encodes a transaction to hex using libauth's `encodeTransaction`: ```typescript import { transactionToHex } from "@wizardconnect/core/hdwalletv1-serialize"; const txHex = transactionToHex(inputs, outputs); // txHex is a hex string ready for the relay ``` Note: libauth's `encodeTransaction` reverses `outpointTransactionHash` to wire format internally. Pass txids in **display order** (big-endian, as returned by electrum/explorers). ## Deserialization (relay → wallet) ### `toUint8Array(value)` Converts hex strings, extended JSON format, or `Uint8Array` to `Uint8Array`: ```typescript import { toUint8Array } from "@wizardconnect/core"; toUint8Array("76a914...88ac"); // hex string toUint8Array(""); // extended format toUint8Array(existingBytes); // pass-through ``` ### `toBigInt(value)` Converts numeric strings, extended JSON format, numbers, or `bigint` to `bigint`: ```typescript import { toBigInt } from "@wizardconnect/core"; toBigInt(""); // extended format toBigInt("200000"); // numeric string toBigInt(200000); // number toBigInt(200000n); // pass-through ``` ### `parseExtendedJson(jsonString)` Parses a full JSON string, converting all extended-format values in one pass: ```typescript import { parseExtendedJson } from "@wizardconnect/core"; const obj = parseExtendedJson('{"value":"","data":""}'); // obj.value === 200000n // obj.data instanceof Uint8Array ``` ### `isExtendedJsonFormat(str)` Returns `true` if a string contains `` or `` markers. ## Usage in sign requests A typical dapp builds a sign request like this: ```typescript import { RelayMsgAction } from "@wizardconnect/core"; import { sourceOutputToRelay, transactionToHex } from "@wizardconnect/core/hdwalletv1-serialize"; const txHex = transactionToHex(inputs, outputs); const sourceOutputs = inputs.map((input, i) => sourceOutputToRelay({ ...input, valueSatoshis: utxos[i].value, lockingBytecode: utxos[i].script, }) ); const signReq = { action: RelayMsgAction.SignTransactionRequest, time: Math.floor(Date.now() / 1000), sequence: manager.nextSequence(), transaction: { transaction: txHex, sourceOutputs, broadcast: false }, inputPaths: [[0, "receive", 0]], }; ``` The wallet deserializes using `toUint8Array` and `toBigInt` on the received fields.