Enable XMTP subscriptions using a wallet connection
This tutorial will show you how to create a simple Subscribe button with consent that enables users to subscribe to your messages or notifications.
📥 Need a quick reference? Check out this GitHub repo: xmtp-subscribe
Considerations
Before diving into the code let's consider important aspects while integrating consent features. For example, before making an allow or block action you should synchronize the updated consent list in order to prevent overwriting network consent from another app. For more details head to these sections of our docs:
- Understand user consent preferences: This section provides a comprehensive understanding of how user consent preferences are set, including but not limited to, direct actions within the app, settings adjustments, and responses to prompts.
- Use consent preferences to respect user intent: Your app should aim to handle consent preferences appropriately because they are an expression of user intent.
- Synchronize user consent preferences:All apps that use the user consent feature must adhere to the logic described in this section to keep the consent list on the network synchronized with local app user consent preferences, and vice versa.
Tutorial
Import libraries
Import the necessary XMTP and Ethereum packages. These libraries enable you to create an XMTP client and interact with the Ethereum blockchain.
import React, { useEffect, useState } from "react";
import { Client } from "@xmtp/xmtp-js";
import { ethers } from "ethers";
The receiver of the subscription is you. In this case, we'll make it a random wallet generated by ethers
, but you could send your own wallet address as a prop.
Subscribe with your wallet
The connectWallet
function facilitates the connection to the user's Ethereum wallet.
let wallet = await connectWallet();
let client = await Client.create(wallet, { env: env });
Refresh the consent list
To ensure we're working with the most up-to-date information, refresh the consent list.
// Refresh the consent list to make sure your application is up-to-date with the
await client.contacts.refreshConsentList();
Retrieve the current consent state
After refreshing, we get the current consent state of the subscriber. Valid values are allowed
, blocked
, or unknown
.
// Get the consent state of the subscriber
let state = client.contacts.consentState(client.address);
Update the consent state
Based on the current state, either allow or block the subscriber.
// If the state is unknown or denied, allow the subscriber
if (state == "unknown" || state == "denied") {
await client.contacts.allow([senderAddress]);
}
- If the state is
unknown
orblocked
, we change it toallowed
usingclient.contacts.allow([address])
and call theonSubscribe
function if it exists. - If the state is
allowed
, we don't change the consent and call theonUnsubscribe
function if it exists.
Callbacks
The onSubscribe
and onUnsubscribe
functions are called when the consent state is updated. If you wrap your code around a component, you can use these functions to update your local state or to send a message to your subscribers.
// Define a SubscribeButton component that uses the onSubscribe and onUnsubscribe callbacks
function SubscribeButton({ onSubscribe, onUnsubscribe }) {
// ... other component logic
// Example usage of onSubscribe and onUnsubscribe within the component
const handleSubscribe = (address) => {
// Perform subscription logic...
onSubscribe(address); // Call the onSubscribe callback
};
const handleUnsubscribe = (address) => {
// Perform unsubscription logic...
onUnsubscribe(address); // Call the onUnsubscribe callback
};
return (
<div>
<button onClick={() => handleSubscribe("subscriberAddress")}>
Subscribe
</button>
<button onClick={() => handleUnsubscribe("subscriberAddress")}>
Unsubscribe
</button>
</div>
);
}
// Usage of SubscribeButton component with onSubscribe and onUnsubscribe callbacks
<SubscribeButton
onSubscribe={(address) => {
// Update local db or send a message to the subscriber
}}
onUnsubscribe={(address) => {
// Update local db or send a message to the subscriber
}}
/>;
Always synchronize consent states: Before updating consent preferences on the network, ensure you refresh the consent list with refreshConsentList
. Update the network's consent list only in these scenarios:
- User Denies Contact: Set to
denied
if a user blocks or unsubscribes. - User Allows Contact: Set to
allowed
if a user subscribes or enables notifications. - Legacy Preferences: Align the network with any existing local preferences.
- User Response: Set to
allowed
if the user has engaged in conversation.
Neglecting these guidelines can result in consent state conflicts and compromise user privacy.
Conclusion
Consent has really evolved through the years. It started with email, then email marketing, and was the wild west until laws like GPDR stepped in. This is new chapter in the history of consent in a new era for privacy, portability, and ownership.
Example repo
You can find a complete example of this tutorial in the xmtp-subscribe repo.