Skip to Content
Dial v1 live 🎉
SdkDial Profile

Dial Profile

Every wallet address on Dial has an associated profile used for calls, messaging, and all communication features. Profiles provide human-readable identity information tied to your wallet.

Profile Overview

A Dial Profile includes:

  • Display Name - Your preferred name shown to others
  • Avatar - Profile picture/image
  • Bio - Short description
  • Status - Current availability status
  • Links - Social media and Web3 profiles
  • Preferences - Communication settings

Getting Started

View Your Profile

const profile = await userDialer.profile.get(); console.log(profile.displayName); // "Alice.eth" console.log(profile.avatar); // "https://..." console.log(profile.status); // "online"

View Another User’s Profile

const bobProfile = await userDialer.profile.getProfile({ walletAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb' }); console.log(bobProfile.displayName); console.log(bobProfile.bio);

Profile Object

interface DialProfile { walletAddress: string; displayName: string; avatar?: string; bio?: string; status: 'online' | 'away' | 'busy' | 'offline'; customStatus?: string; links?: { twitter?: string; github?: string; discord?: string; website?: string; ens?: string; }; preferences?: ProfilePreferences; createdAt: Date; updatedAt: Date; } interface ProfilePreferences { allowCalls: boolean; allowMessages: boolean; allowGroupInvites: boolean; showOnlineStatus: boolean; notificationSettings: NotificationSettings; }

Updating Your Profile

Update Display Name

await userDialer.profile.update({ displayName: 'Alice.eth' });

Update Avatar

// Upload from file await userDialer.profile.updateAvatar({ file: avatarFile // File or Blob }); // Or use URL await userDialer.profile.update({ avatar: 'https://example.com/avatar.jpg' });

Update Bio

await userDialer.profile.update({ bio: 'Building the future of Web3 communication 🚀' });

Update Multiple Fields

await userDialer.profile.update({ displayName: 'Alice.eth', bio: 'Web3 developer & builder', links: { twitter: '@alice_eth', github: 'alice', website: 'https://alice.com' } });

Status Management

Set Status

// Predefined statuses await userDialer.profile.setStatus('online'); await userDialer.profile.setStatus('away'); await userDialer.profile.setStatus('busy'); await userDialer.profile.setStatus('offline'); // Custom status message await userDialer.profile.setStatus('online', { customMessage: 'In a meeting until 3pm' });

Get Status

const status = await userDialer.profile.getStatus(); console.log(status.current); // 'online' console.log(status.message); // 'In a meeting until 3pm'

Listen for Status Changes

userDialer.on('profile:status', ({ walletAddress, status }) => { console.log(`${walletAddress} is now ${status}`); });

Privacy & Preferences

Communication Preferences

await userDialer.profile.updatePreferences({ allowCalls: true, allowMessages: true, allowGroupInvites: false, // Don't allow group invites from strangers showOnlineStatus: true });

Block List Management

// Block a user await userDialer.profile.blockUser('0x...'); // Unblock a user await userDialer.profile.unblockUser('0x...'); // Get blocked users const blockedUsers = await userDialer.profile.getBlockedUsers();

Privacy Settings

await userDialer.profile.updatePrivacy({ profileVisibility: 'public', // 'public', 'contacts', 'private' callPrivacy: 'contacts', // Who can call you messagePrivacy: 'everyone', // Who can message you lastSeenVisibility: 'contacts' // Who can see when you were last online });

Notification Settings

Configure Notifications

await userDialer.profile.updateNotificationSettings({ calls: { enabled: true, sound: true, vibrate: true, showPreview: true }, messages: { enabled: true, sound: true, vibrate: true, showPreview: false // Hide message content in notifications }, groupMessages: { enabled: true, mentionsOnly: true // Only notify when mentioned }, voicemail: { enabled: true, sound: true } });

Do Not Disturb

// Enable DND await userDialer.profile.enableDoNotDisturb({ until: new Date('2024-12-01T09:00:00'), // Optional end time allowContacts: true, // Allow calls/messages from contacts allowEmergency: true // Allow emergency contacts }); // Disable DND await userDialer.profile.disableDoNotDisturb();

Profile Verification

ENS Integration

// Link ENS name await userDialer.profile.linkENS({ ensName: 'alice.eth' }); // Profile automatically shows verified ENS const profile = await userDialer.profile.get(); console.log(profile.links.ens); // 'alice.eth' console.log(profile.verified.ens); // true

Social Verification

// Verify Twitter await userDialer.profile.verifyTwitter({ handle: '@alice_eth' }); // Verify GitHub await userDialer.profile.verifyGithub({ username: 'alice' });

Contact Management

Add Contact

await userDialer.profile.addContact({ walletAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb', nickname: 'Bob', // Optional custom name tags: ['friend', 'web3'] // Optional tags });

Get Contacts

const contacts = await userDialer.profile.getContacts(); contacts.forEach(contact => { console.log(contact.walletAddress); console.log(contact.profile.displayName); console.log(contact.nickname); // Your custom nickname });

Update Contact

await userDialer.profile.updateContact({ walletAddress: '0x...', nickname: 'Bobby', tags: ['friend', 'developer'], notes: 'Met at ETHDenver 2024' });

Remove Contact

await userDialer.profile.removeContact('0x...');

Search for Users

// Search by display name const results = await dial.registry.searchProfiles({ query: 'alice', limit: 20 }); results.forEach(profile => { console.log(profile.walletAddress); console.log(profile.displayName); });

Search by ENS

const profile = await dial.registry.getProfileByENS('alice.eth'); console.log(profile.walletAddress);

Profile Events

Subscribe to profile-related events:

// Profile updated userDialer.on('profile:updated', (profile) => { console.log('Profile updated:', profile); }); // Status changed userDialer.on('profile:status', ({ walletAddress, status }) => { console.log(`${walletAddress} status: ${status}`); }); // Contact added userDialer.on('profile:contact:added', (contact) => { console.log('New contact:', contact); }); // Contact removed userDialer.on('profile:contact:removed', ({ walletAddress }) => { console.log('Contact removed:', walletAddress); });

Complete Example: React Profile Component

import { useState, useEffect } from 'react'; import { DialProfile } from '@dial/sdk'; export function ProfileEditor({ userDialer }) { const [profile, setProfile] = useState<DialProfile | null>(null); const [displayName, setDisplayName] = useState(''); const [bio, setBio] = useState(''); const [status, setStatus] = useState<'online' | 'away' | 'busy' | 'offline'>('online'); useEffect(() => { loadProfile(); }, [userDialer]); const loadProfile = async () => { const currentProfile = await userDialer.profile.get(); setProfile(currentProfile); setDisplayName(currentProfile.displayName); setBio(currentProfile.bio || ''); setStatus(currentProfile.status); }; const handleSave = async () => { await userDialer.profile.update({ displayName, bio }); await userDialer.profile.setStatus(status); // Reload profile await loadProfile(); }; const handleAvatarUpload = async (file: File) => { await userDialer.profile.updateAvatar({ file }); await loadProfile(); }; if (!profile) return <div>Loading...</div>; return ( <div className="profile-editor"> <h2>Edit Profile</h2> <div className="avatar-section"> <img src={profile.avatar} alt="Avatar" /> <input type="file" accept="image/*" onChange={(e) => { const file = e.target.files?.[0]; if (file) handleAvatarUpload(file); }} /> </div> <div className="form-field"> <label>Display Name</label> <input type="text" value={displayName} onChange={(e) => setDisplayName(e.target.value)} placeholder="Your display name" /> </div> <div className="form-field"> <label>Bio</label> <textarea value={bio} onChange={(e) => setBio(e.target.value)} placeholder="Tell us about yourself" rows={4} /> </div> <div className="form-field"> <label>Status</label> <select value={status} onChange={(e) => setStatus(e.target.value as any)} > <option value="online">Online</option> <option value="away">Away</option> <option value="busy">Busy</option> <option value="offline">Offline</option> </select> </div> <button onClick={handleSave}>Save Changes</button> <div className="profile-info"> <p>Wallet: {profile.walletAddress}</p> <p>Member since: {profile.createdAt.toLocaleDateString()}</p> </div> </div> ); }

Profile Storage

Profiles are stored on-chain with optional decentralized storage:

  • On-chain: Basic profile data (name, status)
  • IPFS: Avatar images and media
  • s3worm: Additional metadata and preferences

All profile data is associated with your wallet address and can be updated at any time.

Wallet-Based Identity

Dial Profiles leverage wallet addresses as the core identity:

  • âś… No email required - Your wallet is your identity
  • âś… No phone number required - Web3-native communication
  • âś… Cross-platform - Same profile across all apps using Dial
  • âś… Self-sovereign - You own and control your data
  • âś… Portable - Take your profile anywhere

Next Steps

Last updated on