Connect a Universal Profile
There are several methods to connect to a Universal Profile, each catering to different developer requirements and scenarios. Below, we detail the most common approaches and explain why a developer might prefer one over the others.
Connecting to the Universal Profile Browser Extension will trigger the following connection screen:
The Universal Profile Extension returns the address of the connected Universal Profile. Making transactions is the same as with any wallet, you just use the profile address as a from
in your transactions.
Connect with EIP-6963β
If you want to implement Injected Provider Discovery you can visit our Example EIP-6963 Test dApp.
Using EIP-6963 Provider Discovery is the latest industry standardization, solving previous connectivity issues when having multiple wallet extensions installed at the same time.
You can listen to eip6963:announceProvider
events following the EIP-6963: Multi Injected Provider standardization to facilitate a more versatile connection to multiple wallet extensions. This method is beneficial for developers who require the ability to maintain low-level control over how different extensions are targeted and managed within their dApp.
- ethers
- web3
import { ethers } from 'ethers';
let providers = [];
window.addEventListener("eip6963:announceProvider", (event) => {
providers.push(event.detail);
});
// Request installed providers
window.dispatchEvent(new Event("eip6963:requestProvider"));
...
// pick a provider to instantiate (providers[n].info)
const provider = new ethers.BrowserProvider(providers[0].provider);
const accounts = await provider.eth.requestAccounts();
console.log('Connected with', accounts[0]);
import Web3 from "web3";
let providers = [];
window.addEventListener("eip6963:announceProvider", (event) => {
providers.push(event.detail);
});
// Request installed providers
window.dispatchEvent(new Event("eip6963:requestProvider"));
...
// pick a provider to instantiate (providers[n].info)
const provider = new Web3(providers[0].provider);
const accounts = await provider.eth.requestAccounts();
console.log('Connected with', accounts[0]);
Since the Universal Profile Browser Extension is compatible with EIP-6963 Multi Injected Provider, it works out of the box with tools like Wagmi or RainbowKit. If you use Wagmi or RainbowKit, the π extension will appear in the list of available wallets. See the example image below with RainbowKit.
Multi-Provider Librariesβ
You can use third-party libraries to connect to various wallet extensions with ease. Here are some options:
- Web3Modal : Documentation
- Web3-Onboard : Documentation
Both libraries come with built-in UI elements and allow you to support multiple extensions without them all supporting EIP-6963.
- Wallet Connect
- Web3 Onboard
Image | Description |
---|---|
Image | Description |
---|---|
You can check out the implementation of both libraries within our dApp Boilerplate. You can change between multiple provider methods on the fly using the provider switcher component.
Installationβ
- Wallet Connect
- Web3 Onboard
You can install the Web3 Modal using different configurations. The default package utilizes the Ethers.js library, which will be used in this example:
npm i @web3modal/ethers ethers
You can install Web3-Onboard on the dApp using their core library, including all UI elements and hooks. In order to support the Universal Profile Browser Extension, you will have to install the @lukso/web3-onboard
configuration that can be integrated as injected wallet.
npm i @web3-onboard/core @lukso/web3-onboard-config @web3-onboard/injected-wallets
Setupβ
After the installation, you can proceed to configure the library to support the LUKSO network and your dApp.
- Wallet Connect
- Web3 Onboard
// Import the necessary components
import { createWeb3Modal, defaultConfig } from '@web3modal/ethers/react';
// Setup the Metadata
const walletConnectMetadata = {
name: 'Example dApp',
description: 'dApp using Wallet Connect',
url: 'https://my.dapp.domain',
icons: ['https://my.dapp.domain/icon.svg'],
};
// Initialize the Configuration Element
const walletConnectConfig = defaultConfig({
metadata: walletConnectMetadata,
});
// Define the supported networks
const supportedChains = [
// https://docs.lukso.tech/networks/testnet/parameters
{
chainId: 4021,
name: 'LUKSO Testnet',
currency: 'LYXt',
explorerUrl: 'https://explorer.execution.testnet.lukso.network/',
rpcUrl: 'https://4201.rpc.thirdweb.com/',
},
];
// Define chain images for the network screen
const walletConnectChainImages = {
42: 'https://my.dapp.domain/lyx_symbol.svg',
4201: 'https://my.dapp.domain/lyx_symbol.svg',
};
// Create the Web3 Modal Instance
const walletConnectInstance = createWeb3Modal({
ethersConfig: walletConnectConfig,
chains: supportedChains,
'YOUR_PROJECT_ID', // Import the project ID from https://cloud.walletconnect.com
chainImages: walletConnectChainImages,
featuredWalletIds: ['NONE'], // OPTIONAL: Only show wallets that are installed by the user
});
Be aware that anyone implementing Web3-Onboard can modify the download link to the extension.
The Web3-Onboard configuration and calls should be set up as a global context
or component
, accessible to every page or component of your application layout that is interacting with the blockchain.
import Onboard, { OnboardAPI } from "@web3-onboard/core";
import { ConnectModalOptions } from "@web3-onboard/core/dist/types";
import injectedModule from "@web3-onboard/injected-wallets";
import luksoModule from "@lukso/web3-onboard-config";
// Initialize the LUKSO provider from this library
const luksoProvider = luksoModule();
// Set up the injected wallet interface
const injectedWallets = injectedModule({
// Add custom wallets here that you want to inject into Web3-Onboard
custom: [luksoProvider],
// OPTIONAL: Add sorting for supported wallets
sort: (wallets) => {
const sorted = wallets.reduce<any[]>((sorted, wallet) => {
// Universal Profiles will be placed at the top of the wallet connection screen
// Add other injected wallet names here to adjust their order
if (wallet.label === "Universal Profiles") {
sorted.unshift(wallet);
} else {
sorted.push(wallet);
}
return sorted;
}, []);
return sorted;
},
// OPTIONAL: Specify wallets that should still be displayed in the list,
// even when unavailable in the browser
displayUnavailable: ["Universal Profiles"],
});
// Define the download link for the extension
const UP_BROWSER_EXTENSION_URL =
"https://chrome.google.com/webstore/detail/universal-profiles/abpickdkkbnbcoepogfhkhennhfhehfn?hl";
// OPTIONAL: Set up the app description of the Web3-Onboard connection window
const appInfo = {
name: "My LUKSO App",
// Pictures can either be a valid image URL or SVG as string.
// The icon shows behind the extension picture on the right side while connecting
icon: "/my_app_icon.svg",
// The logo shows left of the wallet list, indicating the used app
logo: "<svg> ... </svg>",
description: "My LUKSO App using Web3-Onboard",
recommendedInjectedWallets: [
// Add other injected wallets and their download links
// to take users directly to the installation screen
{
name: "Universal Profiles",
url: UP_BROWSER_EXTENSION_URL,
},
],
};
// OPTIONAL: Set up global installation notices
const connectionOptions: ConnectModalOptions = {
iDontHaveAWalletLink: UP_BROWSER_EXTENSION_URL,
removeWhereIsMyWalletWarning: true,
};
// Create the Web3-Onboard Component
const web3OnboardComponent: OnboardAPI = Onboard({
wallets: [injectedWallets],
// Define at least one network to interact with using the Universal Profile Browser Extension
chains: [{
id: 4021,
token: "LYXt",
label: "LUKSO Testnet", // https://docs.lukso.tech/networks/testnet/parameters
rpcUrl: "https://4201.rpc.thirdweb.com/",
}],,
// OPTIONAL COMPONENTS:
appMetadata: appInfo,
connect: connectionOptions,
});
Connectβ
- Wallet Connect
- Web3 Onboard
To set and access the Wallet Connect provider within your dApp, you can call the integrated open()
method provided by the createWeb3Modal
instance. The library will show a connection window with all supported wallets. You can then fetch the active account and set it as the default provider within your dApp.
- ethers
- web3
// Trigger the connection process and screen
await walletConnectInstance.open();
// Subscribe to provider events, to track the connection
walletConnectInstance.subscribeProvider(
({ provider, address, isConnected, error }) => {
if (error) {
console.log('Wallet Connect Error:', error);
return;
}
// If access was granted
if (isConnected && provider && address) {
const provider = new ethers.BrowserProvider(provider);
walletConnectInstance.close();
}
},
);
// Trigger the connection process and screen
await walletConnectInstance.open();
// Subscribe to provider events, to track the connection
walletConnectInstance.subscribeProvider(
({ provider, address, isConnected, error }) => {
if (error) {
console.log('Wallet Connect Error:', error);
return;
}
// If access was granted
if (isConnected && provider && address) {
const provider = new Web3(provider);
walletConnectInstance.close();
}
},
);
To set and access the Web3-Onboard provider within your dApp, you can call the integrated connectWallet()
method provided by the @web3-onboard/core
library. The library will show a connection window with all supported wallets. You can then fetch the active account and set it as the default provider within your dApp.
- ethers
- web3
// Trigger the connection process and screen
const connectedWallets = await web3OnboardComponent.connectWallet();
if (connectedWallets.length > 0) {
// If a wallet has been connected, set it as default provider
const provider = new ethers.BrowserProvider(connectedWallets[0].provider);
}
// Trigger the connection process and screen
const connectedWallets = await web3OnboardComponent.connectWallet();
if (connectedWallets.length > 0) {
// If a wallet has been connected, set it as default provider
const provider = new Web3(connectedWallets[0].provider);
}
Disconnectβ
- Wallet Connect
- Web3 Onboard
To disconnect your wallet, you have to call the disconnect()
method provided by the createWeb3Modal
instance.
// Close all connections
walletConnectInstance.disconnect();
To disconnect your wallet, you have to call the disconnectWallet()
method provided by the @web3-onboard/core
library. This method requires specifying the wallet you wish to disconnect. You can obtain the necessary information from the state of the Web3-Onboard component, maintaining the current wallet connections.
// Retrieve the current onboard state
const onboardState = web3OnboardComponent.state.get();
// Extract the current connected wallets
const [currentWallet] = onboardState.wallets;
if (currentWallet) {
// If there is an active connection, trigger the disconnect process
await web3OnboardComponent.disconnectWallet({ label: currentWallet.label });
}
Use Provider Injectionβ
You can use the window.lukso
object, tailored for a direct integration with the UP Browser Extension. This approach allows developers to engage directly with the UP Browser Extension without the need to consider compatibility with other extensions.
- ethers
- web3
npm install ethers
npm install web3
- ethers
- web3
import { ethers } from 'ethers';
const provider = new ethers.BrowserProvider(window.lukso);
const accounts = await provider.send('eth_requestAccounts', []);
console.log('Connected with', accounts[0]);
import Web3 from 'web3';
const provider = new Web3(window.lukso);
const accounts = await provider.eth.requestAccounts();
console.log('Connected with', accounts[0]);
Alternatively to the window.lukso
, the equivalent window.ethereum
object can be called within supported browsers, just like other Ethereum wallets. Both follow the EIP-1193 Ethereum Provider JavaScript API. You can use a simple fallback to allow regular wallet connections, if the Universal Profile Browser Extension is not installed:
- ethers
- web3
const provider = new ethers.BrowserProvider(window.lukso || window.ethereum);
const provider = new Web3(window.lukso || window.ethereum);
Sample Implementationsβ
- Check our sample implementations for NextJS on the dApp Boilerplate.
- Test Web3-Onboard in our sandbox environment using up-test-dapp.lukso.tech.
- Find further information in the Web3-Onboard Documentation.
- Find further hooks and implementations in the Web3Modal Documentation