Every verifier + the dispatcher now fails closed under any malformed/ adversarial input, never throws/panics, and resists DoS. No new dependency; prod runtime tree stays 4 deps, all MIT (zero copyleft). - src/limits.ts <-> go/walletconnect/limits.go: single bounds module — size caps (message/sig/pubkey/address/extra/lines) + chain<->scheme table (chainAllowsScheme) that rejects every illegitimate (chain,scheme) pair up front, closing cross-chain scheme confusion by construction. sig cap = 20 KiB so it clears a Cardano COSE_Sign1 (embeds the payload, ~2x the message) for a large-but-legal message. - dispatcher gate() + total backstop (TS try/catch, Go defer recover) around verifyProof / verifyProofAsync so any throw/panic below -> rejected proof. - per-verifier input bounds before any hash/decode (verifiers are exported, so each is independently safe, not just via dispatch). - caip122 parse: bound message size + line count before split. - strict base64 in bytes.ts (was lenient atob) — also kills a latent TS/Go divergence (Go StdEncoding is strict). - CBOR depth cap (MAX_CBOR_DEPTH=16) + declared-length<=remaining guard both langs; in Go a stack overflow is fatal/non-recoverable so this is load-bearing. - TON workchain range-checked to int32 in TS (Go already did). Tests: 160 TS (was 112) incl fuzz.test.ts (47, 30k+ random inputs) + Go property/corpus + 3 native Fuzz* (610k/1.2M/1.0M execs clean). Invariants: (A) never throws/panics, (B) never ok for a non-valid proof, with a ranCrypto>0 gate proving the fuzzers reach the crypto layer. All prior tests stay green. Bump @luxwallet/connect 0.1.0 -> 0.1.1.
wallet-connect (Go)
Go port of the @luxwallet/connect login verifier. Mirrors the TypeScript
src/ byte-for-byte so Hanzo IAM (Casdoor, Go) verifies wallet logins
identically to verifyProof: same CAIP-122 message parse, same
domain/nonce/time checks, same EIP-191 digest, same ed25519 check.
Module: github.com/luxwallet/connect/go
Package: walletconnect
API
ParseSiwxMessage/BuildSiwxMessage— CAIP-122 message (mirrorscaip122.ts).VerifyProof(Proof, Expectation) Result— the one server-side entry point (mirrorsverify.ts). Fails closed; never panics.VerifyEVM— EIP-191personal_sign, secp256k1 ecrecover (mirrorsevm/verify.ts).VerifySolana— ed25519 over the message, base58 pubkey address (mirrorssolana/verify.ts).VerifyTon/VerifyBitcoin/VerifyXrp— fail-closed stubs; full ports later.
Result.Reason strings match the TS union exactly: bad-signature,
address-mismatch, domain-mismatch, nonce-mismatch, expired,
not-yet-valid, malformed-message, unsupported-scheme, missing-public-key.
Crypto
EVM secp256k1 + keccak256 come from github.com/luxfi/crypto (the luxfi
package — NOT go-ethereum, NOT ava-labs). ed25519 is stdlib crypto/ed25519;
base58 is github.com/mr-tron/base58.
The verifier path uses pure-Go secp256k1 (luxfi/crypto's !cgo build), so it
needs no C toolchain.
Test
CGO_ENABLED=0 go test ./...
CGO-free is the portable, one-and-only-one-way invocation (no libsecp256k1 C
build required). A bare go test ./... also works on a machine with a healthy
C toolchain.