Skip to content

feat(offchain-manager): add Universal Usernames connection methods - #51

Closed
HAPPYS1NGH wants to merge 3 commits into
feat/universal-usernames-packagefrom
feat/offchain-manager-universal-usernames
Closed

HAPPYS1NGH wants to merge 3 commits into
feat/universal-usernames-packagefrom
feat/offchain-manager-universal-usernames

Conversation

@HAPPYS1NGH

Copy link
Copy Markdown
Contributor

Changes

  • Add 11 Universal Usernames methods to the flat offchain client (getUsernameConnection, inspectUsernameParent, validateUsernameEndpoint, saveUsernameConnection, activateUsernameConnection, previewUsername, rotateUsernameCredential, pauseUsernameConnection, resumeUsernameConnection, disconnectUsernameConnection, getUsernameConnectionEvents) plus createUsernameOwnerSession, so brands can run the whole setup from code.
  • Add a provider config option (viem WalletClient, ethers Signer or WalletProvider, same adapter pattern as the avatar SDK). Reads sign one SIWE session and reuse it in memory until it nears expiry or the wallet switches account; a session or wallet can also be passed per call.
  • Sign every change with an EIP-4361 operation signature over a fresh GET /api/v1/auth/nonce: statement Authorize <action> for Universal Usernames on <parentName>, chain 1 or 11155111, 5-minute expiry, resource urn:namespace:uun:<parentNode>:<action>:<expectedRevision>, sent as x-auth-token: siwe:<base64 utf8 message>.<base64 utf8 signature>.
  • Default the SIWE domain to the API host (offchain-manager.namespace.ninja / staging.…), with siweDomain and siweUri overrides for custom deployments.
  • Add UniversalUsernamesError (code, status, details, retryable for UPSTREAM_UNAVAILABLE and RATE_LIMITED) with NotParentOwnerError, ConnectionRevisionConflictError and EndpointValidationError subclasses. The mapping applies only to the new methods and drops the AxiosError, whose config holds the auth token and the endpoint credential.
  • Add the §5.1 API types (UsernameConnection, UsernameConnectionStatus, UsernameConnectionRevision, ParentInspection, UsernameConnectionEvent, UsernameValidationReport and request types); report and issue types are re-exported from @thenamespace/universal-usernames as type-only imports.
  • Add 58 msw tests: path, method, body and headers per method; operation signature contents checked and verified with viem like the API does; session reuse and renewal; wallet adapters and chain checks; 403/404/409/412/422/429/503 mapping; no credential or token in any response, error or fixture.
  • Add a README section for the new methods.

Notes

  • Stacked on feat(universal-usernames): add profile schema, validator and adapter package #50 (@thenamespace/universal-usernames 0.1.0). The API routes are in thenamespace/offchain-manager#61, not deployed yet. Docs: docs(universal-usernames): add integration guide, endpoint reference and adapter template docs#20, whose examples match these signatures.
  • Publish order: @thenamespace/universal-usernames 0.1.0 first, then this package as 1.2.0 through the publish workflow (it bumps the version and changelog, so neither is changed here). The workflow already builds @thenamespace/* workspace dependencies before the package.
  • SIWE library: I format EIP-4361 here instead of using @signinwithethereum/siwe (the avatar SDK's choice). That library checks messages against the EIP-4361 grammar, whose statement rule is ASCII-only, so it throws on Authorize save for Universal Usernames on 🦊.eth. The output matches viem's createSiweMessage byte for byte, which is what offchain-manager parses; the tests parse and verify with viem.
  • New dependencies: @noble/hashes ^1.8.0 (keccak for namehash and EIP-55 checksums, already in the lockfile through siwe-parser; v1 because v2 is ESM-only), @thenamespace/universal-usernames ^0.1.0 (types only, nothing is required at runtime), and viem as a dev dependency for tests (already in the lockfile through mint-manager).
  • The lockfile also picks up engines.node >=18.3.0 for universal-usernames, which feat(universal-usernames): add profile schema, validator and adapter package #50's lockfile still listed as >=18.0.0.
  • Verification: npm ci at the root; in packages/offchain-manager: npm run build, npm test (94 passed, 36 before), npm run type-check, npx tsc --noEmit -p tsconfig.test.json (also enforces that response types have no credential field); README sample type-checked against the source; packages/universal-usernames: npm run build, npm test (229 passed), npm run type-check.
  • Skipped: npm run lint and npm run format, because eslint and prettier aren't installed or configured in this repo (true before this change). No live API test: the routes aren't deployed.
  • Follow-up for offchain-manager#61: siweVerify and the operation signature decoder use atob, which reads the token as Latin-1. ASCII names work, but a Unicode parent name's statement and signature won't match until it decodes UTF-8 (Buffer.from(part, 'base64').toString('utf8')).
  • Follow-up for offchain-manager#61: server nonces expire after 60 s, while operation signatures may live 10 minutes. A slow wallet prompt (hardware wallet, Safe) can outlast the nonce.

🤖 Generated with Claude Code

https://claude.ai/code/session_019oGqmTa3TRAEt8JZnPPL6p

HAPPYS1NGH and others added 3 commits October 30, 2026 18:48
Adds typed methods for the offchain-manager Universal Usernames API to
the flat offchain client: reads use an owner SIWE session, every change
is signed by the owner's wallet with a fresh server nonce and a resource
bound to the parent, action and expected revision. The wallet comes from
the new `provider` config option (viem, ethers or WalletProvider, as in
the avatar SDK) or a per-call override.

API errors map to NotParentOwnerError, ConnectionRevisionConflictError,
EndpointValidationError or a generic UniversalUsernamesError with code,
status, details and a retryable hint. The mapping applies only to the
new methods and never keeps the AxiosError, whose config holds the auth
token and the endpoint credential.

Types for profiles and validation reports come from
`@thenamespace/universal-usernames` (type-only, no runtime import).
EIP-4361 messages are formatted like viem's createSiweMessage so
Unicode parent names stay signable; `@noble/hashes` provides keccak for
namehash and EIP-55 checksums.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019oGqmTa3TRAEt8JZnPPL6p
…s and errors

msw tests for every method's path, method, body and auth header; the
operation signature's statement, resource URN, chain, server nonce and
expiry, verified with viem the way the API verifies them; session reuse
and renewal; wallet adapters and chain checks; 403/404/409/412/422/429/503
error mapping; and that no response, error or fixture carries the
endpoint credential or the auth token.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019oGqmTa3TRAEt8JZnPPL6p
@HAPPYS1NGH

Copy link
Copy Markdown
Contributor Author

Closing: Universal Usernames won't ship an SDK package, docs or skill changes for now. Branch kept.

@HAPPYS1NGH HAPPYS1NGH closed this Nov 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant