zeekay c03e9d77db harden(verify): defense-in-depth fail-closed across all 7 SIWx chains
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.
2026-06-24 16:03:51 -07:00

@luxwallet/connect

Multi-chain wallet connect + Sign-In-With-X for EVM, Solana, Bitcoin, TON, XRP, Polkadot.

One vocabulary, one canonical login message (CAIP-122), one verifier. MIT licensed — zero GPL. This is the clean wallet stack; the Uniswap-derived GPL bones stay quarantined in luxfi/exchange.

Why

@luxfi/wallet (Uniswap "Universe" fork) is GPL-3.0 and EVM-only. This package is a from-scratch, permissively-licensed connector that any Hanzo/Lux/Zoo/Pars surface — hanzo.id login, the browser extension, web and mobile apps — can use to authenticate a wallet on any supported chain.

Architecture

connect(chain) ─► Account ─► signLogin(challenge) ─► SignedProof ─► verifyProof()
                  (browser, per-chain connector)      (server, one pure fn)
  • caip122.ts — render/parse the canonical login message. build ∘ parse round-trips.
  • verify.tsverifyProof(proof, expected): parse → enforce domain/nonce/time → dispatch to the per-chain crypto verifier. Pure, fails closed, never throws.
  • <chain>/ — per-chain connector (browser) + verifier (pure crypto).
  • go/walletconnect — Go port of verifyProof, imported by Hanzo IAM so the server verifies identically.

Chain support

Chain Connect lib (license) Login proof Connector Verifier
EVM viem (MIT) — EIP-6963 / window.ethereum EIP-191 personal_sign evm/connect.ts secp256k1 recover
Solana injected provider (Phantom/Solflare/Backpack) ed25519 signMessage solana/connect.ts ed25519
Bitcoin sats-connect (MIT) — Xverse/Leather/Unisat BIP-322 bitcoin/connect.ts legacy + BIP-322
TON @tonconnect/sdk (Apache-2.0) ton_proof ton/connect.ts ed25519 envelope
XRP @crossmarkio/sdk (MIT) — Crossmark signInAndWait xrp/connect.ts secp256k1 + ed25519
Polkadot window.injectedWeb3 (polkadot.js / Talisman / SubWallet) signRaw({type:'bytes'}) polkadot/connect.ts sr25519 + ed25519 + ecdsa

All connect libs are MIT/Apache/ISC — no GPL anywhere in the dependency tree. Polkadot verify uses @polkadot/util-crypto (Apache-2.0, sr25519 via @scure/sr25519 MIT) in TS, and oasisprotocol/curve25519-voi (BSD-3-Clause) in Go — deliberately NOT the LGPL-3.0 ChainSafe/go-schnorrkel. Polkadot's verifier is async (sr25519 needs cryptoWaitReady()); use verifyProofAsync for all chains or verifyPolkadot standalone. The five other chains' verify core stays @noble-pure and synchronous. GemWallet is intentionally not wired: its only client, @gemwallet/api, ships under a custom dual license requiring GemWallet's permission for public/commercial use — incompatible with the MIT/Apache/ISC-only rule. Crossmark covers both XRPL key types, so the XRP path is complete without it.

Architecture: server verify never pulls a wallet lib

The wallet libraries are optional peer dependencies. The server-side verifyProof path imports only @noble/* + bs58:

import { verifyProof } from '@luxwallet/connect/verify';     // zero wallet libs
import { buildSiwxMessage } from '@luxwallet/connect/caip122'; // zero deps

Connectors live behind separate entrypoints, so a server bundle stays clean:

import { loginWithWallet, getConnector } from '@luxwallet/connect/connectors';
import { EvmConnector } from '@luxwallet/connect/evm/connect';

Use

// Server: mint a challenge
import { newChallenge, verifyProof } from '@luxwallet/connect';
const challenge = newChallenge({ domain: 'hanzo.id', uri: 'https://hanzo.id/login' });
// → store challenge.nonce, send challenge to the client

// Server: verify what comes back
const res = verifyProof(proof, { domain: 'hanzo.id', nonce: challenge.nonce });
if (res.ok) { /* res.address is authenticated on res.chain */ }
// Client (browser): connect a wallet and sign the challenge in one call.
import { loginWithWallet } from '@luxwallet/connect/connectors';

const { account, proof } = await loginWithWallet({ chain: 'evm', challenge });
// → POST `proof` to the server, which calls verifyProof(proof, { domain, nonce }).

// Or drive a connector directly:
import { getConnector } from '@luxwallet/connect/connectors';
const c = getConnector('solana');
const acct = await c.connect();             // provider.connect()
const p = await c.signLogin(acct, challenge); // ed25519 signMessage → SignedProof

Develop

pnpm install
pnpm test        # vitest — crypto verifiers run against generated keypairs
pnpm typecheck
pnpm build

License

MIT © Lux Industries Inc.

S
Description
Mirror of github.com/luxwallet/connect
Readme MIT
490 KiB
Languages
TypeScript 55.4%
Go 44.6%