Skip to main content

Connect Wallets

The CONNECT flow simplifies the process of linking wallets and integrating into the Immutable zkEVM network.

Connect flowConnect flow

💡Supported wallets
The Commerce Widget supports Metamask and other blockchain wallets. To use other wallet options you must follow our wallet integration docs.

Getting started

Once you have completed the setup, In order to initiate a flow call the mount() function passing in the id attribute of the target element you wish to mount the widget to, and the parameters required by the CONNECT flow.

import { useEffect } from 'react';
import { checkout } from '@imtbl/sdk';

// Create a Checkout SDK instance
const checkoutSDK = new checkout.Checkout();

export function App() {
// Initialise the Commerce Widget
useEffect(() => {
(async () => {
// Create a factory
const factory = await checkoutSDK.widgets({
config: { theme: checkout.WidgetTheme.DARK, language: 'en' },
});

// Create a widget
const widget = factory.create(checkout.WidgetType.IMMUTABLE_COMMERCE);

// Mount a connect flow, optionally pass any ConnectWidgetParams
widget.mount('mount-point', {
flow: checkout.CommerceFlowType.CONNECT,

// Optionally, set connect behaviour
// blocklistWalletRdns: ['io.metamask'],
// targetWalletRdns: 'io.metamask',
// targetChainId: checkout.ChainId.IMTBL_ZKEVM_MAINNET,
});
})();
}, []);

return <div id="mount-point" />;
}

Parameters

The mount() function will take in a CommerceWidgetConnectFlowParams object.

Widget parameters

Parameters are treated as transient and will be reset after the widget is unmounted.

PropertyTypeDescription
flowCommerceFlowType.CONNECTThe flow type to be used.
targetChainIdChainIdThe target chain to connect to as part of the connection process (defaults to Immutable zkEVM / Immutable zkEVM Testnet)
targetWalletRdnsstring | WalletProviderRdnsThe target wallet to establish a connection with
blocklistWalletRdnsstring[]List of wallets rdns to exclude from the connect

Configuration

When you first create the widget, you can pass an optional configuration object to set it up. For example, passing in the theme or language will create the widget with that theme or language. If these are not passed the configuration will be set by default. You will also have the option to provide the configuration for each of the supported flows.

Widget configuration

Configuration will persist after the widget is unmounted. You can always update a widget's configuration later by calling the update() method.

PropertyDescription
CommerceWidgetConfigurationThe configuration type to be used by the Commerce Widget.
import { checkout } from '@imtbl/sdk';

// When creating the widget, pass in the configuration
// @ts-ignore
const widget = factory.create(checkout.WidgetType.IMMUTABLE_COMMERCE, {
config: {
language: 'en',
theme: checkout.WidgetTheme.DARK,
CONNECT: {}
},
});

// Update the widget config by calling update()
// @ts-ignore
widget.update({
config: {
language: 'ko',
theme: checkout.WidgetTheme.LIGHT,
},
});

For more information on the configurations for the Commerce Widget flow, please review the Widget factory section in our Setup page.

Events

The Commerce Widget emit events events when critical actions have been taken by the user or key states have been reached. Below is a table outlining the key events associated with a CONNECT flow.

Event TypeDescriptionEvent Payload
CommerceEventType.CLOSEThe user clicked the close button on the widget. This should usually be wired up to call the widget's unmount() function.
CommerceEventType.SUCCESSThe user has completed the flow successfully.CommerceSuccessEvent
CommerceEventType.FAILUREThere has been an error in the flow.CommerceFailureEvent

You can use the addListener() function to subscribe to events and provide handlers. Use the removeListener() function to remove the subscription to that event.

import { checkout } from '@imtbl/sdk';

//@ts-ignore
const widget = widgets.create(checkout.WidgetType.IMMUTABLE_COMMERCE, {
config: { theme: checkout.WidgetTheme.DARK },
});

// Add event listeners for the CONNECT flow

widget.addListener(
checkout.CommerceEventType.SUCCESS,
(payload: checkout.CommerceSuccessEvent) => {
// narrow the event to a connect success event
if (payload.type === checkout.CommerceSuccessEventType.CONNECT_SUCCESS) {
const { provider, walletProviderInfo, walletProviderName } = payload.data as checkout.ConnectionSuccess;
console.log('connected', provider, walletProviderInfo, walletProviderName);
}
}
);

widget.addListener(
checkout.CommerceEventType.FAILURE,
(payload: checkout.CommerceFailureEvent) => {
// narrow the event to a connect failure event
if (payload.type === checkout.CommerceFailureEventType.CONNECT_FAILED) {
const { reason } = payload.data;
console.log('connect failed', reason);
}
}
);

widget.addListener(checkout.CommerceEventType.CLOSE, () => {
widget.unmount();
console.log('widget closed');
});

// Remove event listeners for the CONNECT flow

widget.removeListener(checkout.CommerceEventType.SUCCESS);
widget.removeListener(checkout.CommerceEventType.FAILURE);
widget.removeListener(checkout.CommerceEventType.CLOSE);

Sample code

This sample code gives you a good starting point for integrating the CONNECT flow into your application and listening to its events.

import { useEffect, useState } from 'react';
import { checkout } from '@imtbl/sdk';

// create Checkout SDK
const checkoutSDK = new checkout.Checkout();

export function App() {
const [widget, setWidget] =
useState<checkout.Widget<typeof checkout.WidgetType.IMMUTABLE_COMMERCE>>();

// Initialise widget and mount a CONNECT flow
useEffect(() => {
(async () => {
const factory = await checkoutSDK.widgets({
config: { theme: checkout.WidgetTheme.DARK, language: 'en' },
});

const checkoutWidget = factory.create(checkout.WidgetType.IMMUTABLE_COMMERCE);

setWidget(checkoutWidget);
})();
}, []);

// mount widget and add event listeners
useEffect(() => {
if (!widget) return;

widget.mount('mount-point', {
flow: checkout.CommerceFlowType.CONNECT,
});

widget.addListener(
checkout.CommerceEventType.SUCCESS,
(payload: checkout.CommerceSuccessEvent) => {
const { type, data } = payload;

// capture provider after user connects their wallet
if (type === checkout.CommerceSuccessEventType.CONNECT_SUCCESS) {
console.log('connected to ', (data as checkout.ConnectionSuccess).walletProviderName);
// setProvider(data.provider);

// optional, immediately close the widget
// widget.unmount();
}
}
);

// detect when user fails to connect
widget.addListener(
checkout.CommerceEventType.FAILURE,
(payload: checkout.CommerceFailureEvent) => {
const { type, data } = payload;

if (type === checkout.CommerceFailureEventType.CONNECT_FAILED) {
console.log('failed to connect', data.reason);
}
}
);

// remove widget from view when closed
widget.addListener(checkout.CommerceEventType.CLOSE, () => {
widget.unmount();
});

// clean up event listeners
return () => {
widget.removeListener(checkout.CommerceEventType.SUCCESS);
widget.removeListener(checkout.CommerceEventType.DISCONNECTED);
widget.removeListener(checkout.CommerceEventType.CLOSE);
};
}, [widget]);

return <div id="mount-point" />;
}