Skip to main content

User Management

Manage user subscriptions, notification preferences, channel configurations, and topic organization. This section covers the complete user workflow from initial subscription to advanced notification management.

Prerequisites

Before managing users, ensure you have completed these steps:

  1. App Registration: Register your app with Dialect (see the registration guide if you need to set this up)

User Management Workflow Overview

Dialect's user management follows a three-step process:

  1. User Subscription: User subscribes to your app (via notification widget or SDK) and automatically gets IN_APP notifications
  2. Channel Management: User can add email and Telegram channels for additional notification delivery methods
  3. Topic Organization: Configure notification categories and topics that users can selectively subscribe to

Step 1: Subscription Management

Before a user can receive messages, they have to be subscribed to your service.

Subscribe user

Create a subscription for a user's wallet address to your app. This automatically enables them to receive IN_APP notifications.

// Step 1: User subscribes to your app (gets IN_APP notifications automatically)
const subscription = await dialectSolanaSdk.wallet.dappAddresses.create({
addressId: address.id,
enabled: true,
dappPublicKey,
});

Enabling & disabling a subscription

Enable/disable a subscription programmatically:

const updatedSubscription = await dialectSolanaSdk.wallet.dappAddresses.update({
dappAddressId: subscription.id,
enabled: false,
});

Getting subscriptions by id

Retrieve a specific subscription using its unique ID:

const specificSubscription = await dialectSolanaSdk.wallet.dappAddresses.find({
dappAddressId: subscription.id,
});

Getting subscriptions by wallet

Retrieve all subscriptions for a wallet address:

const allSubscriptions = await dialectSolanaSdk.wallet.dappAddresses.findAll({
dappPublicKey, // optional parameter
addressIds: [address.id], // optional parameter
});

Getting subscribers by app

Not available via SDK. Use the API method below for server-side subscriber management.

Deleting a subscription

Remove a subscription completely:

await dialectSolanaSdk.wallet.dappAddresses.delete({
dappAddressId: subscription.id,
});

Step 2: Channel Management

After subscribing to your app, users can add additional notification channels like email and Telegram. Users manage addresses via the Dialect data service, where they may add, verify, update & remove addresses for these various channels.

Add User Email Address

Add an email address for a user to receive notifications via email. The address will need to be verified before notifications can be sent.

// Step 2: User can add additional channels like email or Telegram
const address = await dialectSolanaSdk.wallet.addresses.create({
type: AddressType.Email,
value: "address@mailservice.com",
});

Verify an address

Dialect uses verification codes to verify ownership of web2 channels such as email and Telegram. These codes are sent to the address in question.

// Verify address (email or telegram). Constraint: there are
// 3 attempts to verify address, otherwise use call below to send new
// verification code
const verifiedAddress = await dialectSolanaSdk.wallet.addresses.verify({
addressId: address.id,
code: "1337",
});

If you did not receive the verification code, or if you failed to enter the correct value after several attempts, you can send a new code via the following call:

// Resend verification code. Constraint: you must wait 60 sec before
// resending the code.
await dialectSolanaSdk.wallet.addresses.resendVerificationCode({
addressId: address.id,
});

Get addresses owned by a wallet

Retrieve address information for a wallet. This shows all the notification channels (email, Telegram) that a user has configured.

// Find all addresses owned by wallet
const allAddresses = await dialectSolanaSdk.wallet.addresses.findAll();

// Find specific address owned by wallet
const specificAddress = await dialectSolanaSdk.wallet.addresses.find({
addressId: address.id,
});

You can also check email subscription status using the hook:

import { AddressType } from '@dialectlabs/sdk';
import { useNotificationChannelDappSubscription } from '@dialectlabs/react-sdk';

// Check email subscription status
const {
enabled: emailEnabled,
isFetchingSubscriptions: emailFetching,
} = useNotificationChannelDappSubscription({
addressType: AddressType.Email,
dappAddress: DAPP_ADDRESS,
});

if (!emailFetching) {
console.log('Email subscribed:', emailEnabled);
}

Subscribe to specific channels

Use the useNotificationChannelDappSubscription hook to manage email subscriptions:

import { AddressType } from '@dialectlabs/sdk';
import { useNotificationChannelDappSubscription } from '@dialectlabs/react-sdk';

// Subscribe to email notifications for your dapp
const {
enabled: emailEnabled,
isToggling: emailToggling,
toggleSubscription: toggleEmailSubscription,
} = useNotificationChannelDappSubscription({
addressType: AddressType.Email,
dappAddress: DAPP_ADDRESS,
});

// Enable email notifications
await toggleEmailSubscription({ enabled: true });

Unsubscribe from specific channels

Use the same useNotificationChannelDappSubscription hook to disable email notifications:

import { AddressType } from '@dialectlabs/sdk';
import { useNotificationChannelDappSubscription } from '@dialectlabs/react-sdk';

const {
enabled: emailEnabled,
isToggling: emailToggling,
toggleSubscription: toggleEmailSubscription,
} = useNotificationChannelDappSubscription({
addressType: AddressType.Email,
dappAddress: DAPP_ADDRESS,
});

// Disable email notifications
await toggleEmailSubscription({ enabled: false });

// Check current subscription status
console.log('Email notifications enabled:', emailEnabled);
console.log('Currently toggling:', emailToggling);

Update an address

You can update an address at any time. All of your subscriptions will remain intact, but won't be sent until you re-verify.

// Update address value
const updatedAddress = await dialectSolanaSdk.wallet.addresses.update({
addressId: address.id,
value: "updated.address@example.com",
});

Remove an address

You can delete an address at any time. This will remove all subscriptions associated with that address.

// Delete address
await dialectSolanaSdk.wallet.addresses.delete({
addressId: address.id,
});

Push Notifications

Push Notifications require a more complex setup and you can find a full walkthrough in the API section.

Step 3: Topic Management

Create and manage notification topics to organize and categorize your app's notifications. Topics help users subscribe to specific types of alerts they care about.

Create a new notification type

Define a new category of notifications for your app. Each notification type represents a specific kind of alert that users can subscribe to independently.

// Create a new notification type
const dapp = await dialectSolanaSdk.dapps.find();

if (!dapp) {
throw new IllegalStateError(
"Dapp doesn't exist, please create dapp before using it"
);
}

const notificationType = await dapp.notificationTypes.create({
humanReadableId: "announcements",
name: "Announcements",
orderingPriority: 0,
trigger: "Notification description or triggering event/conditions",
defaultConfig: {
enabled: true,
},
});

Update an existing notification type

Modify the properties of an existing notification type, such as changing its name or trigger description. This is useful when refining your notification categories.

const allNotificationTypes = await dapp.notificationTypes.findAll();

if (allNotificationTypes.length < 1) return;

const notificationType = allNotificationTypes[0];

const patched = await dapp.notificationTypes.patch(notificationType.id, {
name: "New feature announcements",
});

Get all topics

Retrieve all notification types (topics) for your app:

const dapp = await dialectSolanaSdk.dapps.find();
const allNotificationTypes = await dapp.notificationTypes.findAll();

// Or find a specific topic by human-readable ID
const specificTopic = await dapp.notificationTypes.find({
humanReadableId: "price-alerts"
});

Subscribe to topics

Use the useNotificationSubscriptions hook to manage topic subscriptions:

import { useNotificationSubscriptions } from '@dialectlabs/react-sdk';

const {
subscriptions,
update,
isFetching,
isUpdating,
} = useNotificationSubscriptions({
dappAddress: DAPP_ADDRESS,
});

// Subscribe to a specific topic
const subscribeToTopic = async (topicId: string) => {
await update({
notificationTypeId: topicId,
config: {
enabled: true,
},
});
};

// Example: Subscribe to price alerts topic
await subscribeToTopic('price-alerts-topic-id');

Unsubscribe from topics

Use the same useNotificationSubscriptions hook to unsubscribe from topics:

import { useNotificationSubscriptions } from '@dialectlabs/react-sdk';

const {
subscriptions,
update,
isUpdating,
} = useNotificationSubscriptions({
dappAddress: DAPP_ADDRESS,
});

// Unsubscribe from a specific topic
const unsubscribeFromTopic = async (topicId: string) => {
await update({
notificationTypeId: topicId,
config: {
enabled: false,
},
});
};

// Example: Unsubscribe from price alerts topic
await unsubscribeFromTopic('price-alerts-topic-id');

Get topic subscription status

Use the useNotificationSubscriptions hook to get topic subscription status:

import { useNotificationSubscriptions } from '@dialectlabs/react-sdk';

const {
subscriptions,
isFetching,
} = useNotificationSubscriptions({
dappAddress: DAPP_ADDRESS,
});

// Check if a specific topic is subscribed
const isTopicSubscribed = (topicId: string) => {
const subscription = subscriptions.find(
(sub) => sub.notificationType.id === topicId
);
return subscription?.subscription?.config?.enabled || false;
};

// Get all subscribed topics
const subscribedTopics = subscriptions.filter(
(sub) => sub.subscription?.config?.enabled
);

if (!isFetching) {
console.log('Price alerts subscribed:', isTopicSubscribed('price-alerts-topic-id'));
console.log('All subscribed topics:', subscribedTopics);
}

Best Practices

💡 User Experience Tips:

  • Start users with a simple subscription, then let them add channels as needed
  • Create meaningful notification types that users actually want to subscribe to
  • Good topics are specific enough to be useful but broad enough to generate regular content
  • Always respect user preferences and make unsubscribing easy

💡 Technical Tips:

  • Always subscribe users to your app first using dappAddresses.create() before adding additional notification channels
  • Implement proper error handling for address verification flows
  • Use batch operations when managing multiple users to avoid rate limits

Next Steps

Now that you understand user management concepts, you're ready to implement notification components:

  1. NotificationsButton - Complete done-for-you solution
  2. Notifications - Standalone component for custom integration

The components handle all the user management workflows described above, providing your users with intuitive interfaces for managing their notification preferences.