Liquidswap Widget #
The Liquidswap Widget contains the bulk of the functionality of the liquidswap dex and built-in Pontem wallet. The current article about how to integrate Widget to your app.
About #
The widget is a custom web element that can be embedded in any frontend application, or even in a plain HTML/JS/CSS page. Liquidswap widget leverages the full strength of our @pontem/liquidswap-sdk and can enable token swaps for any other custom dApp, wallet, etc.
Installation #
yarn add @pontem/liquidswap-widget
or
npm install @pontem/liquidswap-widget
Usage #
The function loadWidget
accepts a widget HTML tag name as a string. It can be a custom name, but it must be in the kebab case. We recommend to use the name liquidswap-widget
. The passed name must be exactly the same as the tag name.
React
import React, { useLayoutEffect } from 'react';
import { loadWidget } from '@pontem/liquidswap-widget';
export const Widget = () => {
useLayoutEffect(() => {
loadWidget('liquidswap-widget');
}, []);
return (
<div className="'Your Wrapper className'">
<liquidswap-widget/>
</div>
);
};
Vue
<template>
<div class="'Your Wrapper class name'">
<liquidswap-widget>
</div>
</template>
<script setup lang="ts">
import { loadWidget } from '@pontem/liquidswap-widget';
loadWidget('liquidswap-widget');
</script>
Any other framework / lib
- Make sure to add the html tag
liquidswap-widget
to your app.
<liquidswap-widget></liquidswap-widget>
- Import the
loadWidget
function from npm and run it passing the html tag name in the kebab case;
import { loadWidget } from '@pontem/liquidswap-widget';
loadWidget('liquidswap-widget');
When Loaded #
You can listen to the widget and add extra logic (if necessary) once the widget is embedded:
// customElements defined as a global window object.
customElements.whenDefined('liquidswap-widget').then(() => {
// custom logic goes here
});
Live Example #
Here is a widget code example published in Pontem's GitHub directory:
https://pontem-network.github.io/liquidswap-widget/
Liquidswap Widget as a dApp (native wallet application) #
Liquidswap Widget can be used as an in-wallet dApp.
In that case, the web-custom-element needs several properties:
- Wallet account address;
const dataAccount = '0x15fd61229f6e12b51adbff45b7b74310c7eaf9c24ef8c13b653c8f2a07bc1d14';
- Network info: name and chainId;
const dataNetwork = { name: 'mainnet', chainId: '1' };
- Transaction info: status and hash;
interface ITransactionStatus {
status: 'pending' | 'success' | 'error' | 'rejected';
hash: string | null
};
const transactionStatus: ITransactionStatus = { status: 'pending', hash: null };
- Properties should be passed as strings (data-attributes); thus, in order to pass the variable
Object
, you need to useJSON.stringify()
on theObject
being passed; - Properties will be extruded with
JSON.parse()
inside the widget; - Properties are reactive, so any change to props will update the widget’s internal store;
Also, the widget will dispatch to Custom Events:
‘signAndSubmitTransaction’ - this event will return CustomEvent with the ‘detail’ property containing a ready-for-wallet transaction payload. Simply accept the props inside the handler, and you will find prop ‘detail’ with the full transaction payload;
‘transactionProcessed’ - this event will be fired after the widget accepts the transaction's hash and status and correctly resolves it with
Widget integration React example #
Widget integration React example
import React, { useLayoutEffect, useRef, useState } from 'react';
import { loadWidget } from '@pontem/liquidswap-widget';
export const Widget = () => {
const [dataNetwork, setDataNetwork] = useState(
{ name: 'mainnet', chainId: '1' }
);
const [dataAccount, setDataAccount] = useState(
'0x019b68599dd727829dfc5036dec02464abeacdf76e5d17ce43352533b1b212b8'
);
const [transactionStatus, setTransactionStatus] = useState<{
status: string,
hash: string | null
}>({ status: 'pending', hash: null });
const ref = useRef();
const transactionHandler = (props: CustomEvent) => {
// props.detail will be the contained payload.
};
const processedHandler = (event: CustomEvent) => {
// this event will be fired if a user closes the modal with the transaction status
// with neither success nor error. In this case, we do not need to
// provide a hash or status. Therefore, it should be set to the initial State:
setTransactionStatus({ status: 'pending', hash: null });
};
useLayoutEffect(() => {
loadWidget('liquidswap-widget');
// customElements available as window.customElements
customElements.whenDefined('liquidswap-widget').then(() => {
if (ref.current) {
const nodeElement = ref.current;
nodeElement.addEventListener(
'signAndSubmitTransaction',
transactionHandler
);
nodeElement.addEventListener(
'transactionProcessed',
processedHandler
);
}
});
}, []);
return (
<liquidswap-widget
ref={ref}
data-network={JSON.stringify(dataNetwork)}
data-account={dataAccount}
data-transaction={JSON.stringify(transactionStatus)}
/>
)
};
Note: When these properties are passed to the widget, it treats the Parent element as ‘wallet environment’, so the connect / disconnect wallet flow will be skipped / hidden.