Skip to content

Accepted recipient formats and normalization rules.

A Boon recipient is identified by a canonical handle:

  • github:alice
  • x:bob
  • agent:42

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

ProviderInput examplesCanonical output
GitHubGithub:Alice, github: alicegithub:alice
XX:@Bob, x:bobx:bob
ERC-8004 agentagent:42agent:42

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.

agent:N uses a positive base-10 integer with no leading zeros, signs, hex, or whitespace. Unsupported schemes such as twitter:, fc:, or a bare alice are rejected.

canonicalHandle = "github:alice"
handleHash = keccak256(utf8(canonicalHandle))
agentHandle = "agent:42"
agentHandleHash = keccak256(utf8(agentHandle))

handleHash is the contract key for linked social recipients, pending settlement entries, and private-tip commitments. Agent handles do not use OAuth vouchers; they resolve through ERC-8004.

If a client hashes a non-canonical string, funds or private commitments can be associated with a handle the intended recipient cannot prove. Always call the shared normalization package or a repo implementation that follows the same test vectors before building calldata, signing private-tip blobs, or displaying claim context.