Skip to content

v1.1.0

Latest

Choose a tag to compare

@x88 x88 released this 04 Jul 09:58
81ccdf5

go-mhda v1.1.0

URN grammar 1.1: the chain identity drops the coin type, and the URN gains an
optional wallet domain. This is a format-changing release — strings produced
by 1.0.0 do not round-trip unchanged (see Migration below).

Breaking changes

  • Chain identity is the (nt, ci) pair. Chain.String() / Chain.Key()
    now return nt:<network>:ci:<chain_id>. The chain key remains a strict
    prefix of every canonical NSS. NewChain takes two arguments:
    NewChain(networkType, chainId).
  • ct is no longer required — or part of the identity. The SLIP-44 coin
    type is optional metadata: parsed from any position, emitted after ci in
    decimal, never included in Key()/String(). For HD addresses the coin
    already lives in the derivation path; the standalone component exists as an
    annotation for consumers that need the registry value without parsing a
    path. New accessors: Chain.CoinType(), Chain.HasCoinType(),
    Chain.SetCoinType(), Chain.ClearCoinType(). ErrMissingCoinType is
    gone.
  • ChainFromKey is strict. A chain key must be the canonical identity
    string, byte for byte. A key carrying ct (the pre-1.1 format) fails with
    the dedicated ErrCoinTypeInChainKey; any other residue — non-identity
    components, unknown tokens, reordering, non-canonical case — fails with
    ErrInvalidChainKey. ChainFromNSS stays lenient for extracting the chain
    from a full address NSS.
  • Network type values renamed to the commonly accepted network names,
    lowercase: bitcoin, tron, avalanche, solana, xrpl, stellar,
    aptos, cardano, algorand. Unchanged: evm, cosmos, near, sui,
    ton. There are no aliases — the old short names are rejected.
  • ParseURNRx removed. The regex variant silently truncated
    case-preserving values, applied last-wins to duplicate components and
    dropped components past its match cap — behaviours the canonical parser
    rejects loudly. One grammar, one parser.
  • NewAddress validates its optional params. They ride the same setters
    as parsed input and panic on an invalid value (matching the
    NewDerivationPath precedent). The parse entry points never panic.
  • ATOM is 118. The previous constant (168) belongs to Helleniccoin in
    the SLIP-44 registry; 118 also matches the coin level of CIP-11 paths.

New

  • Wallet domain. Two optional, independent, free-form components bind an
    address to a wallet context: wt — the client or protocol the address is
    exposed through (web3, metamask, tonconnect, …), and wi — a wallet
    instance identifier (a UUID, an HD root key fingerprint, …). They are
    emitted last in the canonical order
    nt:ci[:ct][:dt][:dp][:aa][:af][:ap][:as][:wt][:wi], participate in the
    serialised NSS and its hashes when set, and are orthogonal to validation.
    Accessors WalletType() / WalletId() are part of the MHDA interface.
  • Coin type registry extended with 34 modern SLIP-44 registrations (DOT,
    KSM, FIL, EGLD, FLOW, HBAR, ICP, XTZ, KAS, MINA, CSPR, STRK, SEI, INJ,
    OSMO, RUNE, XCH, CKB, STX, ZIL, VET, EOS, LUNA, BCH, ETC, BERA, HYPE,
    MOVE, MON and others), all verified against the registry.

Parser hardening

  • NSS values are enforced to printable ASCII (0x21–0x7E): control bytes,
    whitespace of any kind and non-ASCII bytes are rejected. Trimming is
    ASCII-only — a Unicode space is malformed input, never decoration to strip.
  • Free-form values (ci, ap, as, wt, wi) are case-preserving and
    round-trip verbatim; enum values normalise to lowercase.
  • The free-form setters reject values that would corrupt the serialised NSS:
    : (component injection on re-parse), ? / # (RFC 8141 truncation),
    whitespace and non-ASCII. New sentinel: ErrInvalidValue.
  • ct accepts its two documented spellings only — plain decimal and
    0x-prefixed hex. Legacy octal, 0o/0b prefixes and digit-group
    underscores are rejected.

Migration

  • Regenerate persisted chain keys and URNs; there is no compatibility layer
    by design. Old keys fail loudly in ChainFromKey (ErrCoinTypeInChainKey),
    and the renamed network values make pre-1.1 strings with short names fail
    at the network check.
  • Full address NSS forms that carry ct still parse (it is valid optional
    metadata) and re-serialise with ct in the canonical position after ci.

Testing

go test, go vet, gofmt clean. The golden corpus was rewritten for the
1.1 grammar and extended with wallet-domain, strict chain-key and hardening
suites; the fuzzers run clean with refreshed seeds. SPEC.md is updated in
lockstep. The C++ port (censync/mhda 1.1.0) mirrors this release bit for bit,
verified by a differential harness over ~50k inputs.