Skip to content

Feat/membership nft indexer#34

Open
coderolisa wants to merge 2 commits into
Adamantine-guild:mainfrom
coderolisa:feat/membership-nft-indexer
Open

Feat/membership nft indexer#34
coderolisa wants to merge 2 commits into
Adamantine-guild:mainfrom
coderolisa:feat/membership-nft-indexer

Conversation

@coderolisa

Copy link
Copy Markdown

closes #14

Adds a comprehensive indexing worker that synchronizes on-chain membership
state from the MembershipNFT contract into the access API database.

## Implementation

### Core Components
- **Indexer Worker** (apps/access-api/src/workers/indexer.ts)
  - Consumes MembershipMinted, MembershipRenewed, and MembershipSuspended events
  - Processes events in configurable batches (default: 1000 blocks)
  - Persists checkpoint to IndexerCheckpoint table for resumable indexing
  - Idempotent: safe to re-run without creating duplicate records
  - Graceful shutdown on SIGTERM/SIGINT

### Smart Contract
- **MembershipNFT** (contracts/src/MembershipNFT.sol)
  - ERC-721 based membership token with expiry and suspension
  - Multi-community support via communityId mapping
  - Admin-controlled minting and renewal
  - Emits events suitable for off-chain indexing

### Database Schema
- Added IndexerCheckpoint model for tracking last processed block
- Updated Membership model to include tokenId for contract mapping
- Supports tracking chainId and contractAddress for multi-chain future

### Configuration
- Added RPC_URL, INDEXER_START_BLOCK, INDEXER_BATCH_SIZE to .env.example
- Added indexer script to package.json: npm run indexer

### Documentation
- Comprehensive INDEXER.md with architecture, usage, and troubleshooting
- Updated README.md with indexer section and configuration

### Testing
- Unit tests for indexer configuration and event processing
- All Solidity contract tests passing (3/3)
- Tests cover idempotency, checkpoint management, and error handling

## Event Processing

### MembershipMinted
- Creates/updates Wallet, Community, Member, and Membership records
- Sets membership state based on expiry (active/expired)
- Links tokenId to membership for contract state tracking

### MembershipRenewed
- Updates membership expiresAt and renewedAt timestamps
- Transitions state from expired back to active if applicable
- Gracefully handles missing tokenId (logs warning, continues)

### MembershipSuspended
- Sets membership state to suspended when isSuspended=true
- Restores state (active/expired) when isSuspended=false
- Preserves expiry information during suspension

## Features
- ✅ Reads configured chain ID, contract address, and RPC URL
- ✅ Creates/updates wallet, member, and membership records
- ✅ Updates membership expiry on renewal
- ✅ Updates suspension state
- ✅ Persists last processed block checkpoint
- ✅ Idempotent database writes
- ✅ Batch processing with configurable size
- ✅ Graceful shutdown support
- ✅ Comprehensive error handling and logging
- ✅ Unit tests with documentation

## Usage

```bash
# Configure environment
export RPC_URL="http://localhost:8545"
export MEMBERSHIP_NFT_ADDRESS="0x..."
export CHAIN_ID=31337

# Run indexer
npm run indexer
```

## Dependencies
- ethers@^6.13.0 for contract interaction
- @guildpass/contracts for ABI and addresses
- Foundry dependencies: forge-std, openzeppelin-contracts@v5.0.0

## Acceptance Criteria Met
- [x] Indexer reads configured chain ID, contract address, and RPC URL
- [x] MembershipMinted creates or updates wallet, member, and membership records
- [x] MembershipRenewed updates membership expiry
- [x] MembershipSuspended updates suspension state
- [x] Indexer persists last processed block checkpoint
- [x] Tests cover event decoding and idempotent database writes
- [x] Comprehensive documentation

Resolves #[issue-number]
- PR_SUMMARY.md: Comprehensive PR description with all changes
- QUICK_START_INDEXER.md: Step-by-step local testing guide
@Lakes41

Lakes41 commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Good Day, Please do include a description of the changes made to the repository as included in the PR Template

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.

Implement on-chain event indexing for memberships

3 participants