Skip to content

Canonical handles

How Boon normalizes GitHub and X handles before hashing and settlement.

A Boon recipient is identified by a canonical social handle:

  • github:alice
  • x:bob

Every surface must normalize before hashing. The shared TypeScript package is @boon/normalize, and the contract enforces that keccak256(bytes(displayHandle)) == handleHash.

ProviderInput examplesCanonical output
GitHubGithub:Alice, github: alicegithub:alice
XX:@Bob, x:bobx:bob

GitHub usernames are lowercased, max 39 characters, alphanumeric with single hyphens and no leading/trailing hyphen.

X usernames are lowercased, max 15 characters, alphanumeric or underscore. A leading @ is stripped.

Unsupported schemes such as twitter:, fc:, or a bare alice are rejected in v1.

canonicalHandle = "github:alice"
handleHash = keccak256(utf8(canonicalHandle))
providerHash = keccak256(utf8("github"))

handleHash is the contract escrow key. providerHash is part of the EIP-712 Link voucher so a proof for one provider cannot be replayed as another.

If a client hashes a non-canonical string, funds can land in escrow under a handle no recipient can prove. Always call the shared normalization package or a repo implementation that follows the same test vectors.