Skip to Content
Dial v1 live šŸŽ‰
SdkGated Video Rooms

Gated Video Rooms

Create token-gated video rooms accessible only to NFT holders, token holders, or DAO members.

Overview

Gated rooms allow you to:

  • šŸŽ« NFT-gated: Access for specific NFT holders
  • šŸ’Ž Token-gated: Require minimum token balance
  • šŸ›ļø DAO-gated: Members-only spaces
  • šŸ” Multi-gate: Combine multiple conditions

Creating a Gated Room

NFT-Gated Room

const room = await dial.gatedRooms.create({ name: 'Exclusive Holder Meetup', maxParticipants: 100, gateType: 'nft', gate: { collection: '0x...', // NFT collection address chain: 'ethereum', minQuantity: 1 } }); console.log('Gated room URL:', room.url);

Token-Gated Room

const room = await dial.gatedRooms.create({ name: '$DIAL Holders Only', maxParticipants: 50, gateType: 'token', gate: { token: '0x...', // Token contract address chain: 'solana', minBalance: '1000', // Minimum balance required decimals: 9 } });

DAO-Gated Room

const room = await dial.gatedRooms.create({ name: 'DAO Governance Call', maxParticipants: 200, gateType: 'dao', gate: { daoAddress: '0x...', // DAO contract address chain: 'ethereum', proposalThreshold: true // Requires ability to create proposals } });

Multi-Gated Room

const room = await dial.gatedRooms.create({ name: 'Elite Community', maxParticipants: 20, gateType: 'multi', gates: [ { type: 'nft', collection: '0x...', chain: 'ethereum' }, { type: 'token', token: '0x...', chain: 'solana', minBalance: '5000' } ], gateLogic: 'OR' // 'AND' or 'OR' });

Gate Types

NFT Gate Options

interface NFTGate { collection: string; // Contract address chain: 'ethereum' | 'solana' | 'polygon' | 'base'; minQuantity?: number; // Minimum NFTs to own specificTokenIds?: string[]; // Specific token IDs traits?: { traitType: string; value: string; }[]; }

Token Gate Options

interface TokenGate { token: string; // Token contract address chain: 'ethereum' | 'solana' | 'polygon' | 'base'; minBalance: string; // Minimum token balance decimals: number; snapshot?: Date; // Balance at specific time }

DAO Gate Options

interface DAOGate { daoAddress: string; chain: 'ethereum' | 'solana'; proposalThreshold?: boolean; // Must be able to create proposals votingPower?: string; // Minimum voting power }

Joining Gated Rooms

Check Access

const hasAccess = await dial.gatedRooms.checkAccess({ roomId: room.id, walletAddress: '0x...' }); if (hasAccess.allowed) { console.log('Access granted!'); } else { console.log('Access denied:', hasAccess.reason); }

Join Room

try { await dial.gatedRooms.join({ roomId: room.id, walletAddress: '0x...', signature: await wallet.signMessage('Join gated room') }); } catch (error) { if (error.code === 'ACCESS_DENIED') { console.log('You do not meet the requirements'); } }

Verification Process

The SDK automatically verifies gate conditions:

// Verification flow const verification = await dial.gatedRooms.verify({ roomId: room.id, walletAddress: '0x...' }); console.log('Verification status:', verification.status); console.log('Requirements met:', verification.requirementsMet); console.log('Missing requirements:', verification.missingRequirements);

Managing Gated Rooms

Update Gate Requirements

await dial.gatedRooms.updateGate(roomId, { gate: { collection: '0x...', // New collection minQuantity: 2 // Updated requirement } });

Add Whitelist

// Add specific addresses to whitelist await dial.gatedRooms.addToWhitelist(roomId, [ '0x...', '0x...' ]); // Remove from whitelist await dial.gatedRooms.removeFromWhitelist(roomId, ['0x...']);

Temporary Access Passes

// Create temporary pass const pass = await dial.gatedRooms.createPass({ roomId: room.id, recipientAddress: '0x...', expiresAt: new Date('2025-12-31'), maxUses: 5 }); console.log('Pass URL:', pass.url);

Room Analytics

const analytics = await dial.gatedRooms.getAnalytics(roomId); console.log('Total participants:', analytics.totalParticipants); console.log('Unique holders:', analytics.uniqueHolders); console.log('Access attempts:', analytics.accessAttempts); console.log('Denied attempts:', analytics.deniedAttempts);

Complete Example: React Gated Room Component

import { useState, useEffect } from 'react'; import { DialClient } from '@dial/sdk'; import { useAccount, useSignMessage } from 'wagmi'; export function GatedRoomAccess({ dial, roomId }) { const { address } = useAccount(); const { signMessageAsync } = useSignMessage(); const [room, setRoom] = useState(null); const [access, setAccess] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { checkAccess(); }, [roomId, address]); const checkAccess = async () => { if (!address) return; setLoading(true); // Get room details const roomDetails = await dial.gatedRooms.get(roomId); setRoom(roomDetails); // Check access const accessStatus = await dial.gatedRooms.checkAccess({ roomId, walletAddress: address }); setAccess(accessStatus); setLoading(false); }; const joinRoom = async () => { try { const signature = await signMessageAsync({ message: 'Join gated room' }); await dial.gatedRooms.join({ roomId, walletAddress: address, signature }); // Redirect to room window.location.href = room.url; } catch (error) { console.error('Failed to join:', error); } }; if (loading) { return <div>Checking access...</div>; } if (!access?.allowed) { return ( <div className="access-denied"> <h2>šŸ”’ Access Restricted</h2> <p>{room.name}</p> <div className="requirements"> <h3>Requirements:</h3> {room.gate.type === 'nft' && ( <p> Hold at least {room.gate.minQuantity} NFT(s) from{' '} {room.gate.collection} </p> )} {room.gate.type === 'token' && ( <p> Hold at least {room.gate.minBalance} tokens </p> )} </div> {access?.missingRequirements && ( <div className="missing"> <h4>You're missing:</h4> <ul> {access.missingRequirements.map((req, i) => ( <li key={i}>{req}</li> ))} </ul> </div> )} </div> ); } return ( <div className="access-granted"> <h2>āœ… Access Granted</h2> <p>{room.name}</p> <button onClick={joinRoom}>Join Room</button> </div> ); }

Advanced Features

Dynamic Gates

Update gate requirements based on conditions:

// Gate changes based on time await dial.gatedRooms.createScheduledGate({ roomId, schedule: [ { from: '2025-01-01T00:00:00Z', to: '2025-06-01T00:00:00Z', gate: { /* early access gate */ } }, { from: '2025-06-01T00:00:00Z', gate: { /* general access gate */ } } ] });

Tiered Access

// Create tiers with different privileges await dial.gatedRooms.createTiers(roomId, [ { name: 'Diamond', gate: { token: '0x...', minBalance: '10000' }, privileges: ['host', 'recording', 'priority_audio'] }, { name: 'Gold', gate: { token: '0x...', minBalance: '5000' }, privileges: ['priority_audio'] }, { name: 'Silver', gate: { token: '0x...', minBalance: '1000' }, privileges: [] } ]);

Snapshot Verification

Verify holdings at a specific block/time:

const room = await dial.gatedRooms.create({ name: 'Snapshot Holders', gateType: 'token', gate: { token: '0x...', minBalance: '1000', snapshot: { blockNumber: 12345678, chain: 'ethereum' } } });

Next Steps

Last updated on