Skip to main content

Connect a Universal Profile

Universal Profiles can connect to dApps on LUKSO using one of the two UP Apps available:

Connecting your Universal Profile will trigger one the following connection screen.

Example of UP Browser Extension Connection ScreenExample of UP Mobile App Connection Screen
Request Handling

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.

Connection Methods​

There are multiple ways to connect a dApp to Universal Profiles, from high-level libraries to low-level provider access. Choose the method that best fits your application's needs:

OptionDifficultyRecommended for
Third-Party LibrariesEasy 🌢️
Plug in existing connectors and focus on UX.
Most dApps. Provides pre-built components, ready-made modals, with multi-wallet support out of the box and connection logic handled automatically.
Recommended for quick and easy integration while keeping a seamless user experience.
Provider InjectionMedium 🌢️🌢️
Require to manage the window.lukso object.
Lightweight builds needing minimal dependencies and full control over wallet connection logic.
Recommended for full control over the connection logic (e.g: only allow UPs to connect) and to build custom connection modals.
Provider DiscoveryComplex 🌢️🌢️🌢️
Connect multiple wallet extensions simultaneously.
Advanced apps where users run several extensions (e.g., MetaMask + Universal Profile) simultaneously using EIP-6963.
Recommended for handling multiple connected wallets.
info

Currently, only the third-party libraries method can be used to connect the πŸ“± UP Mobile App to a dApp.

Third-Party Libraries​

You can connect to Universal Profile using the following third-party libraries. These libraries simplify dApp development by abstracting complex wallet connection logic:

See flow diagram on how third party libraries handle the connection flow with EIP-6963

Choose your preferred library and follow the configuration steps below. Both options are built on top of Wagmi!

Step 1: Install Dependencies

npm install @rainbow-me/rainbowkit wagmi @tanstack/react-query

Step 2: Configure Wagmi with LUKSO and RainbowKit Connectors

Set up Wagmi configuration with LUKSO network and RainbowKit's Universal Profile wallet connector:

Using the connectors

universalProfilesWallet connector is required to integrate your app with the Universal Profiles Mobile App.

import { WagmiProvider, createConfig, http } from 'wagmi';
import { lukso } from 'wagmi/chains';
import { connectorsForWallets } from '@rainbow-me/rainbowkit';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { universalProfilesWallet } from '@rainbow-me/rainbowkit/wallets';

// Wagmi uses QueryClient to manage cache, background updates, and request deduplication.
// This is required to provide <QueryClientProvider> higher up in your component tree.
const queryClient = new QueryClient();

const config = createConfig({
chains: [lukso],
transports: {
[lukso.id]: http(),
},
connectors: connectorsForWallets(
[
{
groupName: 'Login with Universal Profile',
wallets: [universalProfilesWallet],
},
],
{
appName: 'LUKSO dApp',
projectId: 'YOUR_PROJECT_ID', // Get your project ID from WalletConnect Cloud
},
),
});

Step 3: Wrap Your App with Providers

Import RainbowKit styles and wrap your application with the required providers in the correct order:

import { RainbowKitProvider } from '@rainbow-me/rainbowkit';
import '@rainbow-me/rainbowkit/styles.css';

function App() {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<RainbowKitProvider>
{/*
Place your main application content here.
<YourAppContent />

This ensures that all components within <YourAppContent />
have access to the connected wallet context provided by WagmiProvider,
enabling features like reading connection state or sending transactions.
*/}
</RainbowKitProvider>
</QueryClientProvider>
</WagmiProvider>
);
}

Step 4: Add the Connect Button

Use RainbowKit's pre-built ConnectButton component to handle wallet connections:

import { ConnectButton } from '@rainbow-me/rainbowkit';

function YourAppContent() {
return (
<div>
<ConnectButton />
</div>
);
}

Step 5: Access Connection State

Use Wagmi hooks to read the connected Universal Profile details:

import { useAccount, useChainId } from 'wagmi';

function YourAppContent() {
const { address, isConnected, chain } = useAccount();
const chainId = useChainId();

return (
<div>
<ConnectButton />
{isConnected && (
<div>
<p>Address: {address}</p>
<p>Network: {chain?.name}</p>
<p>Chain ID: {chainId}</p>
</div>
)}
</div>
);
}

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.

npm install viem
import { createWalletClient, custom } from 'viem';
import { lukso } from 'viem/chains';

const client = createWalletClient({
chain: lukso,
transport: custom(window.lukso),
});

const accounts = await client.requestAddresses();
console.log('Connected with', accounts[0]);
Wallet Compatibility

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:

import { createWalletClient, custom } from 'viem';
import { lukso } from 'viem/chains';

const client = createWalletClient({
chain: lukso,
transport: custom(window.lukso || window.ethereum),
});

Provider Discovery​

Example Implementation

If you want to implement Injected Provider Discovery you can visit our Example EIP-6963 Test dApp.

Wallet Compatibility

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.

Step 1: Install Dependencies

npm install viem

Step 2: Implement Provider Discovery

import { createWalletClient, custom } from 'viem';
import { lukso } from 'viem/chains';

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)

// Create a wallet client using the selected provider
const walletClient = createWalletClient({
chain: lukso,
transport: custom(providers[0].provider),
});

const accounts = await walletClient.requestAddresses();
console.log('Connected with', accounts[0]);

Helpful Resources​