feat: add NIP-43 invite code foundation#650
Conversation
🦋 Changeset detectedLatest commit: 0119664 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
afbfc55 to
1c4b970
Compare
- Add event kinds 8000, 8001, 13534, 28934, 28935, 28936 and tags (member, claim) - Create InviteCode/DBInviteCode types and Nip43Settings interface - Add IInviteCodeRepository interface with create, findByCode, claimCode, findActiveCodes, deleteExpiredCodes - Implement InviteCodeRepository with atomic claimCode via single UPDATE - Add generateInviteCode() using crypto.randomBytes (128-bit entropy) - Create invite_codes migration with CHECK constraints and partial index - Add revokeAdmission() and findAllAdmitted() to UserRepository - Add 27 unit tests with full coverage
1c4b970 to
0119664
Compare
There was a problem hiding this comment.
Pull request overview
This PR introduces foundational invite-code infrastructure to support NIP-43 relay membership workflows, including a new repository for managing invite codes, schema/types to represent them, and constants/settings needed by upcoming join/leave handlers.
Changes:
- Added
InviteCodeRepositorywith code generation, creation, lookup, atomic claim, active-code listing, and expiry cleanup methods. - Added
invite_codesdatabase migration plus corresponding TypeScript types and repository interface. - Extended NIP-43-related event kind/tag constants and added
nip43settings shape.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| test/unit/repositories/invite-code-repository.spec.ts | Adds unit tests covering the new repository behaviors and expected transformations. |
| src/repositories/invite-code-repository.ts | Implements invite-code persistence and atomic claiming logic over invite_codes. |
| src/constants/base.ts | Adds NIP-43 event kinds and tags used by relay access metadata/requests. |
| src/@types/settings.ts | Introduces Nip43Settings and wires it into the global Settings type. |
| src/@types/repositories.ts | Defines IInviteCodeRepository interface for the new repository. |
| src/@types/invite-code.ts | Adds InviteCode and DBInviteCode types for app/DB representations. |
| migrations/20260624_120000_create_nip43_invite_codes_table.js | Creates invite_codes table and adds check constraints + expiry index. |
| .knip.json | Ignores the new repository file in knip analysis. |
| .changeset/nip43-invite-codes.md | Adds a minor changeset describing the new NIP-43 invite-code foundation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| maxUses: number = 1, | ||
| client: DatabaseClient = this.dbClient, | ||
| ): Promise<InviteCode> { | ||
| logger('create invite code: %s (expires: %s, maxUses: %d)', code, expiresAt ?? 'never', maxUses) |
| code: string, | ||
| client: DatabaseClient = this.dbClient, | ||
| ): Promise<InviteCode | undefined> { | ||
| logger('find invite code: %s', code) |
| pubkey: Pubkey, | ||
| client: DatabaseClient = this.dbClient, | ||
| ): Promise<boolean> { | ||
| logger('claim invite code %s for %s', code, pubkey) |
| }) | ||
| .update({ | ||
| use_count: client.raw('use_count + 1'), | ||
| claimed_by: toBuffer(pubkey), |
| afterEach(() => { | ||
| dbClient.destroy() | ||
| sandbox.restore() | ||
| }) |
| table.integer('max_uses').notNullable().defaultTo(1) | ||
| table.integer('use_count').notNullable().defaultTo(0) |
There was a problem hiding this comment.
I think these two fields could just be one called remaining_uses, once it gets to <= 0 the invite can no longer be used.
Description
Invite code infrastructure for NIP-43 relay membership.
claimCode()uses a single atomic UPDATE with WHERE guards (not expired, uses remaining) so concurrent claims on the same code are safe without transactions.claimed_byhas no FK tousersso users don't exist yet at claim time.Related Issue
NIP-43 implementation
Motivation and Context
Need a data layer for NIP-43 join/leave handlers.
How Has This Been Tested?
25 unit tests, full suite 1322 passing.
Types of changes
Checklist: