-
Notifications
You must be signed in to change notification settings - Fork 11
feat: Support specifying and displaying team names end-to-end (#122) #132
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR!
Left some comments.
- Another point is that the name of the team looks bigger than the
Team Managementheading. Reduce the size as its breaking the visual hierarchy - Resolve conflicts
| teamData.set(teamIdentifier, { | ||
| teamIdentifier, | ||
| teamLeaderAddress: data.teamLeaderAddress, | ||
| teamName: data.teamName || undefined, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| teamName: data.teamName || undefined, | |
| teamName: data.teamName || teamIdentifier, |
|
|
||
| const attestationData = { | ||
| teamIdentifier: teamIdentifier.toString(), | ||
| teamName: (teamName || (teamIdentifier?.startsWith?.('0x') ? teamIdentifier : '')).toString(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| teamName: (teamName || (teamIdentifier?.startsWith?.('0x') ? teamIdentifier : '')).toString(), | |
| teamName: (teamName || (teamIdentifier).toString(), |
| Team storage newTeam = teams[teamId]; | ||
| newTeam.owner = msg.sender; | ||
| newTeam.huntId = _huntId; | ||
| newTeam.name = _teamName; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need a validation for teamName length to be not more than 20 chars
| try { | ||
| const attestationData = { | ||
| teamIdentifier: teamData?.teamId?.toString() || userWallet.toString(), // team id for teams, user wallet for solo users | ||
| teamName: teamData?.name || (teamData?.teamId ? undefined : userWallet.toString()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| teamName: teamData?.name || (teamData?.teamId ? undefined : userWallet.toString()), | |
| teamName: teamData?.name || userWallet.toString(), |
| {Number(teamData?.memberCount || 0) < Number(teamData?.maxMembers || 0) && teamData?.owner === userWallet && ( | ||
| <Button | ||
| size="sm" | ||
| onClick={async () => { | ||
| try { | ||
| const teamIdStr = teamData?.teamId?.toString?.(); | ||
| if (teamIdStr) { | ||
| await generateInviteAfterTeamCreation(teamIdStr); | ||
| } | ||
| } catch (e) { | ||
| toast.error('Failed to generate invite'); | ||
| } | ||
| }} | ||
| > | ||
| Invite more | ||
| </Button> | ||
| )} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this.
Not having an Invite More button is meant to be.
We explicitly ask the user to save the screenshot of the QR as invites expire after a certain interval.
Summary
This PR adds first-class support for team names across the smart contracts, backend attestations, and frontend UI. Users can now create teams with a name (required, max 20 chars), see the team name throughout the app (Hunt details and leaderboard), and include the team name in attestations for consistent display. The UI presents a minimal header showing the team name and an “Invite more” button when the team is not full and the viewer is the team owner.
Motivation
Changes
Contract (Solidity)
nametoTeamandTeamInfostructs incontracts/src/Khoj.sol.createTeamsignature tocreateTeam(uint256 _huntId, string _teamName).getTeamto returnnameviaTeamInfo.contracts/scripts/deploy.jsto reliably retrievehuntId/teamIdin ethers v6.contracts/hardhat.config.js(usesBASE_SEPOLIA_RPC_URL,PRIVATE_KEY).Contract Tests
contracts/test/Khoj.test.jsto use newcreateTeam(_huntId, _teamName)signature.getTeam.Backend
backend/src/services/sign-protocol.jsteamName: string.attestClueSolvedto accept and includeteamName(fallback to wallet address for solo users).backend/src/server.js/attest-cluenow acceptsteamNameand forwards to the service.backend/src/services/leaderboard.jsteamNamein leaderboard entries for display.Frontend
frontend/src/assets/hunt_abi.tsto reflect newcreateTeamsignature andTeamInfoorder:huntId, teamId, owner, name, maxMembers, memberCount, members.frontend/src/types/hunt.tsTeamto include optionalname.HuntDetails.tsx:createTeam(huntId, teamName).Leaderboard.tsx:teamName(with truncation) if present; falls back to previous logic (solo address or Team #ID).Clue.tsx:teamNameto/attest-clue. Solo fallback to wallet address retained.Breaking changes
createTeamnow requires a second parameter (_teamName). Frontend and any scripts must pass this.TeamInfotuple order updated to includename. Any consumer reading team info must use the new ABI.Deployment and configuration
npx hardhat run contracts/scripts/deploy.js --network baseSepoliaVITE_PUBLIC_BASE_CONTRACT_ADDRESSto the new contract address.teamName. If using a static schema ID, create a new schema and updateSIGN_SCHEMA_IDin env, or re-run the schema creation step and update the ID.Testing
npx hardhat test— all tests pass.teamName.teamNamefallback, so leaderboard still displays a meaningful identifier.Related issues