- Delete unused bloom.ts module (leftover from topic-based discovery)
- Remove maxTopicsPerOffer configuration (no longer used)
- Remove unused info field from Offer types
- Simplify generateOfferHash() to only hash SDP (remove topics param)
- Update outdated comments referencing deprecated features
- Remove backward compatibility topics field from answer responses
This completes the migration to V2 service-based architecture by
removing all remnants of the V1 topic-based system.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Delete existing service before creating new one
- Prevents UNIQUE constraint error on (username, service_fqn)
- Enables seamless service republishing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Change 'answererPeerId' to 'answererId'
- Change 'answerSdp' to 'sdp'
- Add 'topics' field (empty array) for client compatibility
This ensures the server response matches the expected format
in the client's AnsweredOffer interface.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The error handler was referencing variables (username, serviceFqn, offers)
that were declared inside the try block. If an error occurred before these
were defined, the error handler itself would fail, resulting in non-JSON
responses that caused "JSON.parse: unexpected character" errors on the client.
Fixed by:
- Declaring variables at function scope
- Initializing offers as empty array
- Using destructuring assignment for username/serviceFqn
This ensures the error handler can always access these variables safely,
even if an early error occurs, and will always return proper JSON responses.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The service publishing endpoint was using validateUsernameClaim which
expects the message format "claim:{username}:{timestamp}", but clients
send "publish:{username}:{serviceFqn}:{timestamp}".
Added validateServicePublish function to properly validate service
publishing signatures with the correct message format.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Switch from sync verify() to async verifyAsync() to work with
hashes.sha512Async which uses WebCrypto API.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- d1.ts: Use global crypto.randomUUID() instead of importing from 'crypto'
- sqlite.ts: Use 'node:crypto' import for Node.js compatibility
This fixes the Cloudflare Workers deployment error:
"The package 'crypto' wasn't found on the file system but is built into node"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
@noble/ed25519 v3.0.0 requires explicit SHA-512 hash function setup
before using any cryptographic operations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add POST /services endpoint for publishing services with username verification
- Add DELETE /services/:serviceId endpoint for unpublishing services
- Add GET /services/:serviceFqn endpoint for service discovery
- Add POST /usernames/claim endpoint with Ed25519 signature verification
- Add POST /usernames/renew endpoint for extending username TTL
- Add GET /usernames/:username endpoint for checking username availability
- Add username expiry tracking and cleanup (365-day default TTL)
- Add service-to-offer relationship tracking
- Add signature verification for username operations
- Update storage schema for usernames and services tables
- Add comprehensive README documentation for V2 APIs
- Update version to 0.8.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Always generate cryptographically random 128-bit peer IDs to prevent peer ID hijacking vulnerability. This ensures peer IDs are secure through collision resistance rather than relying on expiration-based protection.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add info field to Offer and CreateOfferRequest types
- Validate info field: optional, max 128 characters
- Include info field in all public API responses
- Update README with info field documentation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update /register endpoint to accept optional custom peer ID
- Add validation: 1-128 chars, non-empty, must be unique
- Return 409 Conflict if peer ID already in use
- Remove outdated API.md documentation
- Update README.md with new register endpoint format
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Document secret parameter in POST /offers endpoint
- Document secret parameter in POST /offers/:offerId/answer endpoint
- Document hasSecret flag in GET /offers/by-topic response
- Add Protected Offers feature to features list
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added optional startsWith parameter to GET /topics endpoint:
- Filters topics by prefix using SQL LIKE operator
- Updated storage interface and implementations (SQLite & D1)
- Added query param documentation
- Returns startsWith in response when used
Version bumped to 0.1.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Removed PUT /offers/:offerId/heartbeat endpoint
- Removed updateOfferLastSeen() from storage interface and implementations
- last_seen column is still in DB but not used for cleanup
- Cleanup only uses expires_at, so heartbeat was non-functional
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added hash-id.ts utility for SHA-256 content hashing
- Offer IDs now generated from hash of {sdp, topics} (sorted)
- Removed peerId from hash (inferred from authentication)
- Server generates deterministic IDs for idempotent offer creation
- Updated SQLite and D1 storage implementations
- Removed optional id field from CreateOfferRequest
- Same offer content always produces same ID
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>