Espanicon is a validator on the ICON network. Their goal is to participate in the chain governance of the network and expand the ICON ecosystem by building projects in it and collaborating with other validators.
Introduction
Interacting with ICON wallets in the browser is an essential part of building decentralized applications on the ICON network. This tutorial will show you how to connect with ICON wallets in the browser using the ICON Provider JS API which is a protocol that wallets in the ICON Blockchain use to allow dapps to communicate with the wallet in the browser. The first section will cover how to do it with vanilla JS, and the second section will cover how to do it using React.
Prerequisites
To follow along with this tutorial, you will need the following:
- An IDE or text editor
- Node.js and npm installed on your computer
- Basic understanding of JavaScript
Understanding Browser Events
The ICON JS provider uses browser events to communicate with ICON wallets (ICONex, Hana). When you send a request to the wallet using window.dispatchEvent()
, you’re essentially dispatching a custom event with a specific name and detail.
The wallet listens for these custom events and responds by dispatching its own custom events with specific names and details. These events are then captured by the event listener you previously register in the browser.
Section 1: Vanilla JavaScript
In this section, we’ll show you how to connect with ICON wallets in the browser using vanilla JavaScript.
To communicate with ICON wallets in the browser using JavaScript, you can use the ICON JS provider and browser events. Here’s how to do it in four simple steps:
Step 1: Register an Event Listener
To communicate with the ICON wallets, you need to register an event listener that listens for events triggered by the wallet.
window.addEventListener('ICONEX_RELAY_RESPONSE', (event) => {
console.log(event.detail);
});
In this example, we’re registering an event listener for ICONEX_RELAY_RESPONSE
events, which are triggered by the ICON wallet when a user performs an action.
Step 2: Send a Request to the Wallet
To send a request to the wallet, you need to create an object with the request data and send it to the wallet using the window.dispatchEvent()
method.
const request = {
type: 'REQUEST_ADDRESS'
};
window.dispatchEvent(new CustomEvent('ICONEX_RELAY_REQUEST', {
detail: request
}
));
In this example, we’re sending a request to the wallet to get the user’s wallet address.
Step 3: Handle the Response from the Wallet
When the user approves the request in the wallet, the ICONEX_RELAY_RESPONSE
event will be triggered, and you can handle the response in the event listener you registered in Step 1.
window.addEventListener('ICONEX_RELAY_RESPONSE', (event) => {
const { type, payload } = event.detail;
if (type === 'RESPONSE_ADDRESS') {
console.log(payload);
}
});
In this example, we’re handling the RESPONSE_ADDRESS
response type and logging the user’s wallet address to the console.
Section 2: React
In this section, we’ll show you how to connect with ICON wallets in the browser using React.
In the sample code provided, we have a React component that communicates with the wallet using events to retrieve the user’s address and display it on the screen.
Step 1: Set up the React component
Create a new React component called App
. In the component, we’ll use the useState
hook to store the user’s address, and the useEffect
hook to listen for events from the wallet.
import { useState, useEffect } from 'react';
function App() {
const [address, setAddress] = useState('');
useEffect(() => {
window.addEventListener('ICONEX_RELAY_RESPONSE', (event) => {
const { type, payload } = event.detail;
if (type === 'RESPONSE_ADDRESS') {
setAddress(payload);
}
});
}, []);
return (
<div>
<div>Wallet Address: {address}</div>
</div>
);
}
export default App;
Step 2: Send a request to the wallet for the user’s address
In order to retrieve the user’s address, we need to send a request to the wallet using the ICONEX_RELAY_REQUEST
event. We can do this by creating a function called handleConnect
that dispatches a custom event with the REQUEST_ADDRESS
type:
function handleConnect() {
window.dispatchEvent(new CustomEvent('ICONEX_RELAY_REQUEST', {
detail: {
type: 'REQUEST_ADDRESS',
},
}));
}
We can then call this function from a button in our component:
return (
<div>
<button onClick={handleConnect}>Connect to Wallet</button>
<div>Wallet Address: {address}</div>
</div>
);
Step 3: Listen for the response from the wallet
After sending the request to the wallet, we need to listen for the response. We can do this using the useEffect hook to add an event listener for the ICONEX_RELAY_RESPONSE event. When the response is received, we can update the address state variable with the user’s address:
useEffect(() => {
function handleResponse(event) {
const { type, payload } = event.detail;
if ( type === 'RESPONSE_ADDRESS') {
setAddress(payload);
}
}
window.addEventListener('ICONEX_RELAY_RESPONSE', handleResponse);
return() => {
window.removeEventListener('ICONEX_RELAY_RESPONSE', handleResponse);
};
}, []);
In the useEffect hook, we’ve added a named function handleResponse
to handle the ICONEX_RELAY_RESPONSE
event, and passed it to addEventListener
. We’ve also added a return function that removes the event listener using removeEventListener
when the component unmounts.
By cleaning up the event listener, we ensure that it’s not active after the component is removed from the DOM, preventing potential memory leaks and bugs.
The []
at the end of the useEffect hook ensures that the event listener is only added once when the component mounts, and not every time the component re-renders.
Step 4: Putting it all together
Here’s the final code that combines all the steps together:
import { useState, useEffect } from 'react';
function App() {
const [address, setAddress] = useState('');
function handleConnect() {
window.dispatchEvent(new CustomEvent('ICONEX_RELAY_REQUEST', {
detail: {
type: 'REQUEST_ADDRESS',
},
}));
}
useEffect(() => {
function handleResponse(event) {
const { type, payload } = event.detail;
if ( type === 'RESPONSE_ADDRESS') {
setAddress(payload);
}
}
window.addEventListener('ICONEX_RELAY_RESPONSE', handleResponse);
return() => {
window.removeEventListener('ICONEX_RELAY_RESPONSE', handleResponse);
};
}, []);
return (
<div>
<button onClick={handleConnect}>Connect to Wallet</button>
<div>Wallet Address: {address}</div>
</div>
);
}
export default App;
With a little bit of CSS sugar on it this is how our button will look like:
Conclusion
Using the ICON JS provider and browser events, you can easily communicate with ICON wallets in the browser using JavaScript. By following the steps outlined in this tutorial, you can send requests to the wallet and handle the responses in your code.