Skip to content

Migration guide sends readers to a third-party package for hex/base64 the SDK already exports #1631

Description

@oceans404

Problem

docs/UINT8ARRAY_MIGRATION.md:32-44 is the recipe table for the most-hit break in v17: .toString("hex") on SDK bytes, which silently returns comma-joined decimals. Every row of that table prescribes a function from a third-party package:

Before (Buffer) After (Uint8Array)
buf.toString("hex") uint8ArrayToHex(bytes)
buf.toString("base64") uint8ArrayToBase64(bytes)
Buffer.from(hex, "hex") hexToUint8Array(hex)

The prose above the table names the source: "The uint8array-extras package (which the SDK itself uses) covers most of these." True, and the SDK depends on it directly. But we re-export none of it, so following our own guide means adding a dependency to repair the single most common line in the release. The alternative the guide offers is Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength), which puts a Buffer back into code that v17 just freed from it.

The SDK already ships this conversion. Verified against 17.0.0-rc.1 from npm:

import { xdr } from "@stellar/stellar-sdk";

xdr.encodeBytes(new Uint8Array([0xde, 0xad, 0xbe, 0xef]), "hex");     // "deadbeef"
xdr.encodeBytes(new Uint8Array([0xde, 0xad, 0xbe, 0xef]), "base64");  // "3q2+7w=="
xdr.decodeBytes("deadbeef", "hex");                                    // Uint8Array

encodeBytes and decodeBytes are deliberate named exports from src/xdr/index.ts:38. They carry no JSDoc and appear in no reference doc or guide, so a reader has no way to find them.

The table also omits a case that needs no helper at all: XDR values answer toXdr("hex") and toXdr("base64") directly, typed to return string.

Goal

A reader following the migration guide fixes .toString("hex") with something the SDK ships, and adds no dependency.

Scope

Docs, plus JSDoc on two existing exports. No API change.

This is deliberately separated from #1611, which proposes better-named byte helpers (bytesToHex and friends, including URL-safe base64) exported from /base. That is an API design question. This issue is not blocked by it: the guide can be correct today against xdr.encodeBytes, and if #1611 lands, the table gets updated once more to the nicer names. Base64url stays with #1611, since encodeBytes does not cover it.

Requirements

  • docs/UINT8ARRAY_MIGRATION.md:32-44 names SDK exports for the hex and base64 rows instead of uint8array-extras.
  • The table shows value.toXdr("hex") / value.toXdr("base64") for XDR values, which need no helper.
  • Rows with no SDK equivalent (concat, compare, readUInt32BE) keep their current advice, so the table stays honest about what the SDK does not cover.
  • The Buffer.from(...) escape hatch is kept but marked as a stopgap, since it reintroduces the dependency v17 removed.
  • encodeBytes returns Uint8Array | string, so a hex call currently needs as string. Either note the cast in the guide or add per-format overloads.
  • encodeBytes and decodeBytes get JSDoc, so hover and the reference docs describe them.

Why it matters

This is the fix path for the break that fails silently and therefore reaches production. Anything that adds friction to it (discovering a package, adding a dependency, or reaching for a Buffer polyfill) costs more than a normal docs gap.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status
    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions