|
| 1 | +# Sendtags System: Complete Guide |
| 2 | + |
| 3 | +## What Are Sendtags? |
| 4 | + |
| 5 | +**Sendtags** (also called "tags") are unique usernames in the Send app that serve as human-readable identifiers for users. Think of them as "/handles" similar to Twitter usernames, but for cryptocurrency payments and social features. Users can send money to each other using sendtags instead of long wallet addresses. |
| 6 | + |
| 7 | +### Key Characteristics |
| 8 | +- **Unique**: Each sendtag is globally unique across the Send app |
| 9 | +- **User-friendly**: Alphanumeric strings (1-20 characters, A-Z, a-z, 0-9, underscore) |
| 10 | +- **Payment identifiers**: Send money using "/alice" instead of wallet addresses |
| 11 | +- **Social identity**: Appear in activity feeds, profiles, and social interactions |
| 12 | +- **Multiple per user**: Each user can own up to 5 sendtags under their Send account |
| 13 | +- **Main tag**: Users designate one confirmed tag as their primary identity |
| 14 | + |
| 15 | +### Example Use Cases |
| 16 | +- Sending money: "Send $10 to /alice" |
| 17 | +- Social features: "/bob liked your transaction" |
| 18 | +- Profile identity: Users choose a primary "main" sendtag for their public profile |
| 19 | + |
| 20 | +## System Architecture |
| 21 | + |
| 22 | +The sendtag system uses a three-table design that provides flexibility and proper data relationships: |
| 23 | + |
| 24 | +### Core Tables |
| 25 | +1. **`tags`** - Stores the actual sendtag data (name, status, timestamps) |
| 26 | +2. **`send_account_tags`** - Junction table linking users' send accounts to their tags |
| 27 | +3. **`send_accounts`** - User accounts with a reference to their main tag |
| 28 | + |
| 29 | +### Relationship Model |
| 30 | +``` |
| 31 | +User → Send Account → Send Account Tags → Tags |
| 32 | + ↑ ↑ |
| 33 | + └─── main_tag_id ──────────────────┘ |
| 34 | +``` |
| 35 | + |
| 36 | +This design allows: |
| 37 | +- Users to own multiple tags through the junction table |
| 38 | +- Easy addition/removal of tag associations |
| 39 | +- Automatic tag recycling when users release tags |
| 40 | +- Clean separation between tag ownership and tag existence |
| 41 | + |
| 42 | +## Tag Status Lifecycle |
| 43 | + |
| 44 | +Each tag has a status that controls its availability and usage: |
| 45 | + |
| 46 | +### Status Types |
| 47 | +- **`pending`** - Tag claimed but payment not confirmed (30-minute expiration) |
| 48 | +- **`confirmed`** - Tag paid for and verified on blockchain |
| 49 | +- **`available`** - Previously owned tag that was released for reuse |
| 50 | + |
| 51 | +### Lifecycle Flow |
| 52 | +1. **Creation**: User claims a tag → status becomes `pending` |
| 53 | +2. **Payment**: User pays and transaction is verified → status becomes `confirmed` |
| 54 | +3. **Usage**: Only `confirmed` tags can be used for payments and set as main tag |
| 55 | +4. **Release**: User deletes tag association → status becomes `available` (if no other owners) |
| 56 | +5. **Recycling**: Another user can claim `available` tags |
| 57 | + |
| 58 | +### Business Rules |
| 59 | +- Users can own maximum 5 tags at once |
| 60 | +- Only confirmed tags work for payments and social features |
| 61 | +- Pending tags expire after 30 minutes without payment |
| 62 | +- Tag names are globally unique (case-insensitive) |
| 63 | +- Available tags preserve their name but clear ownership |
| 64 | + |
| 65 | +## Security Model |
| 66 | + |
| 67 | +The system uses PostgreSQL Row Level Security (RLS) to ensure data privacy and integrity: |
| 68 | + |
| 69 | +### Tag Visibility |
| 70 | +- Users can only see tags they own through the junction table relationship |
| 71 | +- Anonymous users cannot see any private tag data |
| 72 | +- Confirmed tags may appear in public search results |
| 73 | + |
| 74 | +### Tag Operations |
| 75 | +- **Creation**: Users can only create tags for their own send accounts |
| 76 | +- **Updates**: Users can only modify their own pending tags |
| 77 | +- **Deletion**: Two-tier system - pending tags can be deleted directly, confirmed tags must be released through the junction table |
| 78 | + |
| 79 | +### Data Integrity |
| 80 | +- Foreign key constraints prevent orphaned references |
| 81 | +- Triggers automatically manage main tag assignment and succession |
| 82 | +- Business logic enforced at database level prevents invalid states |
| 83 | + |
| 84 | +## Main Tag Feature |
| 85 | + |
| 86 | +The main tag system designates one confirmed tag as a user's primary identity: |
| 87 | + |
| 88 | +### Automatic Assignment |
| 89 | +- When a user's first tag is confirmed, it automatically becomes their main tag |
| 90 | +- No manual intervention required for basic functionality |
| 91 | +- Ensures all users with confirmed tags have a main tag |
| 92 | + |
| 93 | +### Manual Selection |
| 94 | +- Users can change their main tag to any of their confirmed tags |
| 95 | +- Only confirmed tags are eligible to be main tags |
| 96 | +- Changes take effect immediately |
| 97 | + |
| 98 | +### Succession Logic |
| 99 | +- If a user's main tag is deleted, the system automatically promotes their next oldest confirmed tag |
| 100 | +- If no other confirmed tags exist, main_tag_id is set to NULL |
| 101 | +- Prevents users from being left without a main tag when they have other options |
| 102 | + |
| 103 | +## Key Operations |
| 104 | + |
| 105 | +### Tag Creation |
| 106 | +When users create a new tag: |
| 107 | +1. System checks if an `available` tag with that name exists and claims it |
| 108 | +2. If no available tag exists, creates a new tag record |
| 109 | +3. Creates association in `send_account_tags` junction table |
| 110 | +4. Enforces 5-tag limit per user |
| 111 | +5. New tag starts in `pending` status |
| 112 | + |
| 113 | +### Tag Confirmation |
| 114 | +When payment is verified: |
| 115 | +1. Backend verifies blockchain transaction receipt |
| 116 | +2. Updates tag status from `pending` to `confirmed` |
| 117 | +3. Creates activity feed entries |
| 118 | +4. Links to payment receipt for audit trail |
| 119 | +5. If this is user's first confirmed tag, automatically sets as main tag |
| 120 | + |
| 121 | +### Tag Release |
| 122 | +Users can release tags in two ways: |
| 123 | +1. **Cancel pending tags**: Direct deletion removes unpaid reservations |
| 124 | +2. **Release confirmed tags**: Deleting from junction table releases ownership |
| 125 | + - If no other users own the tag, it becomes `available` for others |
| 126 | + - If it was the main tag, system automatically assigns new main tag |
| 127 | + - Tag name is preserved for potential reuse |
| 128 | + |
| 129 | +## Integration Points |
| 130 | + |
| 131 | +### Activity Feed |
| 132 | +- Tag confirmation creates activity entries visible to user's network |
| 133 | +- Tag operations include relevant metadata (transaction hashes, timestamps) |
| 134 | +- Social features use confirmed tags for user identification |
| 135 | + |
| 136 | +### Payment System |
| 137 | +- Confirmed tags serve as payment identifiers in send flows |
| 138 | +- Receipt system links tag confirmations to blockchain transactions |
| 139 | +- Payment validation prevents unauthorized tag confirmations |
| 140 | + |
| 141 | +### Search Functionality |
| 142 | +- Global search includes confirmed tags with fuzzy matching |
| 143 | +- Search results respect user privacy settings |
| 144 | +- Trigram indexing provides fast partial name matching |
| 145 | + |
| 146 | +### Referral System |
| 147 | +- Tag confirmation can establish referral relationships |
| 148 | +- First tag registration may include referral codes |
| 149 | +- Referral tracking contributes to user rewards and verification |
| 150 | + |
| 151 | +## For Developers |
| 152 | + |
| 153 | +### API Patterns |
| 154 | +Most tag operations work through existing endpoints with automatic main tag handling. Only one new endpoint is needed: |
| 155 | + |
| 156 | +```typescript |
| 157 | +// Update main tag (only new API needed) |
| 158 | +PUT /api/send-accounts/{id} |
| 159 | +{ main_tag_id: tagId } |
| 160 | + |
| 161 | +// Existing patterns continue to work: |
| 162 | +POST /api/tags - creates tag, auto-assigns main if first |
| 163 | +DELETE /api/send-account-tags/{id} - releases tag, auto-reassigns main if needed |
| 164 | +``` |
| 165 | + |
| 166 | +### Query Patterns |
| 167 | +```typescript |
| 168 | +// Get user's tags with main tag indicator |
| 169 | +const tags = await supabase |
| 170 | + .from('tags') |
| 171 | + .select(` |
| 172 | + *, |
| 173 | + is_main:send_accounts!inner(main_tag_id) |
| 174 | + `) |
| 175 | + .eq('send_accounts.user_id', userId) |
| 176 | +``` |
| 177 | + |
| 178 | +### Key Constraints |
| 179 | +- Tag names: 1-20 characters, alphanumeric + underscore only |
| 180 | +- User limit: 5 active tags maximum |
| 181 | +- Main tag: Must be one of user's confirmed tags |
| 182 | +- Case sensitivity: Tag names are case-insensitive (stored as citext) |
| 183 | +- Uniqueness: Tag names are globally unique |
| 184 | + |
| 185 | +### Migration Considerations |
| 186 | +For existing users, run migration to assign main tags: |
| 187 | +- Sets main_tag_id to user's oldest confirmed tag |
| 188 | +- New users get automatic assignment via triggers |
| 189 | +- No breaking changes to existing APIs |
| 190 | + |
| 191 | +### Testing Requirements |
| 192 | +The system includes comprehensive test coverage for: |
| 193 | +- Tag creation and confirmation flows with payment verification |
| 194 | +- Main tag assignment and succession logic |
| 195 | +- RLS policies ensuring proper data isolation |
| 196 | +- Business rule enforcement (limits, validation, uniqueness) |
| 197 | +- Integration with activity feeds and receipt systems |
| 198 | + |
| 199 | +This architecture provides a robust, scalable foundation for the sendtag system while maintaining simplicity for developers and users. |
0 commit comments