Connect to a Mini-App
What are Mini-Apps?β
Mini-Apps are dApps that run in an iframe of a parent page that hosts them. You can see examples of Mini-Apps in action on universaleverything.io.
The Challenge with Mini-Appsβ
Traditionally, users would need to connect to each Mini-App individually through:
- Connect buttons
- Web3 modals
- WalletConnect processes
This makes the user experience cumbersome.
Introducing the UP Providerβ
The up-provider solves this by giving Mini-Apps a way for the user visiting the parent page, to connect to the Mini-App directly with one-click.
Additionally, the Mini-App has access to context addresses
, which in the case of universaleverything.io is the Universal Profile under which the Mini-App is hosted in the Grid.
The up-provider is a EIP-1193 compatible provider, meaning it will work with all major web3 libraries. For examples using viem, web3.js or ethers, see the readme of the up-provider.
Installationβ
npm install @lukso/up-provider
Example implementation using Reactβ
Here's a step-by-step guide to implement UP Provider connection in your React application:
- First, import the necessary dependencies:
import { createClientUPProvider } from '@lukso/up-provider';
- Create a provider instance outside your component:
const provider = createClientUPProvider();
- To implement the UP Provider connection in your component, you can use the following code:
// Track connected accounts
const [accounts, setAccounts] = useState<Array<`0x${string}`>>([]);
const [contextAccounts, setContextAccounts] = useState<Array<`0x${string}`>>(
[],
);
const [profileConnected, setProfileConnected] = useState(false);
// Helper to check connection status
const updateConnected = useCallback(
(_accounts: Array<`0x${string}`>, _contextAccounts: Array<`0x${string}`>) => {
setProfileConnected(_accounts.length > 0 && _contextAccounts.length > 0);
},
[],
);
useEffect(() => {
async function init() {
try {
const _accounts = provider.accounts as Array<`0x${string}`>;
setAccounts(_accounts);
const _contextAccounts = provider.contextAccounts;
updateConnected(_accounts, _contextAccounts);
} catch (error) {
console.error('Failed to initialize provider:', error);
}
}
// Handle account changes
const accountsChanged = (_accounts: Array<`0x${string}`>) => {
setAccounts(_accounts);
updateConnected(_accounts, contextAccounts);
};
const contextAccountsChanged = (_accounts: Array<`0x${string}`>) => {
setContextAccounts(_accounts);
updateConnected(accounts, _accounts);
};
init();
// Set up event listeners
provider.on('accountsChanged', accountsChanged);
provider.on('contextAccountsChanged', contextAccountsChanged);
// Cleanup listeners
return () => {
provider.removeListener('accountsChanged', accountsChanged);
provider.removeListener('contextAccountsChanged', contextAccountsChanged);
};
}, [accounts[0], contextAccounts[0], updateConnected]);
Understanding the Implementationβ
Provider Creationβ
The createClientUPProvider()
function creates a new instance of the UP Provider. This should be done outside your component to maintain a single instance.
State variablesβ
This implementation gives you access to:
accounts
: Array of connected accounts, in our case the universal profile of the visitorcontextAccounts
: Array of context accounts, which in our case is the universal profile on universaleverything.io where the mini-app is hosted under.profileConnected
: Boolean indicating if a user is connected to the mini-app
Event Handlingβ
The provider emits two important events:
accountsChanged
: Triggered when the connected accounts change, this is universal profile of the visitorcontextAccountsChanged
: Triggered when the context accounts change, this is the universal profile on universaleverything.io where the mini-app is hosted under.
Cleanupβ
Clean up the event listeners when unmounting to prevent memory leaks.