🤝Widget Integration Guide
The HeyElsa Chat Widget is a React component that provides AI-powered DeFi assistance with wallet interactions through MessagePort communication.
🚀 Installation
Prerequisites
This package requires an npm token for access. Add the following to your .npmrc file:
//registry.npmjs.org/:_authToken=your-npm-token-here
Install Package
npm install @heyelsa/chat-widget
🔧 Integration Setup
Basic Implementation
import { HeyElsaChatWidget, syncWalletState } from '@heyelsa/chat-widget';
import { createWalletAdapter } from "./adapter.ts";
function App() {
const messagePort = createWalletAdapter();
return (
<div>
<HeyElsaChatWidget
keyId="your-unique-dapp-id"
dappName="MyDApp"
messagePort={messagePort}
position="bottom-right"
customStyles={{
primaryColor: "#6366f1"
}}
/>
</div>
);
}
📋 Configuration Props
Props Interface
interface HeyElsaChatWidgetProps {
keyId: string;
dappName: string;
messagePort: MessagePort;
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
onClose?: () => void;
customStyles?: {
primaryColor?: string;
backgroundColor?: string;
textColor?: string;
borderRadius?: string;
};
}
Props Reference
keyId
string
Yes
-
Unique identifier from HeyElsa Dashboard
dappName
string
Yes
-
Display name for your dApp
messagePort
MessagePort
Yes
-
Communication channel for wallet operations
position
string
No
"bottom-right"
Widget position on screen
customStyles
object
No
-
Custom styling options
🔐 Getting Your Key ID
Steps to get your Key ID:
Note: Dashboard access is currently limited and coming soon for public use.
🌉 Adapter Implementation
What is the Adapter?
The adapter handles communication between the widget and your dApp's wallet functionality. You need to implement the createWalletAdapter
function to handle wallet operations.
Implementation Code
export function createWalletAdapter(): MessagePort {
const channel = new MessageChannel();
channel.port1.onmessage = async (event) => {
const request = event.data as WalletRequest;
const response = {
requestId: request.requestId,
success: false,
data: null,
error: undefined
};
try {
const ethereum = (window as any).ethereum;
let result;
switch (request.action) {
case "CONNECT_WALLET":
result = await ethereum.request({ method: 'eth_requestAccounts' });
break;
case "DISCONNECT_WALLET":
// Handle wallet disconnection logic
result = true;
break;
case "GET_ACCOUNTS":
result = await ethereum.request({ method: 'eth_accounts' });
break;
case "GET_CHAIN_ID":
result = await ethereum.request({ method: 'eth_chainId' });
break;
case "GET_BALANCE":
result = await ethereum.request({
method: 'eth_getBalance',
params: [request.params?.address, 'latest']
});
break;
case "SIGN_MESSAGE":
result = await ethereum.request({
method: 'personal_sign',
params: [request.params?.message, request.params?.address]
});
break;
case "SIGN_TRANSACTION":
result = await ethereum.request({
method: 'eth_signTransaction',
params: [request.params?.transaction]
});
break;
case "BROADCAST_TRANSACTION":
result = await ethereum.request({
method: 'eth_sendTransaction',
params: [request.params?.transaction]
});
break;
case "SWITCH_NETWORK":
result = await ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: request.params?.chainId }]
});
break;
default:
throw new Error(`Unsupported action: ${request.action}`);
}
response.success = true;
response.data = result;
} catch (error: any) {
response.error = error?.message;
}
channel.port1.postMessage(response);
};
return channel.port2;
}
Supported Wallet Actions
CONNECT_WALLET
Connect user wallet
-
DISCONNECT_WALLET
Disconnect wallet
-
GET_ACCOUNTS
Get connected accounts
-
GET_CHAIN_ID
Get current chain ID
-
GET_BALANCE
Get wallet balance
{ address: string }
SIGN_MESSAGE
Sign a message
{ message: string, address: string }
SIGN_TRANSACTION
Sign transaction
{ transaction: object }
BROADCAST_TRANSACTION
Send transaction
{ transaction: object }
SWITCH_NETWORK
Switch network
{ chainId: string }
NETWORK_SWITCHED_EVENT
Network switched
{ chainId: string }
🔄 Wallet State Synchronisation
Purpose: Use these methods to send connected wallet status from your dApp to the widget.
Connected State
import { syncWalletState } from '@heyelsa/chat-widget';
const handleWalletConnect = (address: string, chainId: string, balance: string) => {
syncWalletState({
isConnected: true,
address: address,
chainId: chainId,
chainName: 'Ethereum Mainnet',
balance: balance,
nativeCurrency: {
name: 'Ether',
symbol: 'ETH',
decimals: 18
}
});
};
Disconnected State
const handleWalletDisconnect = () => {
syncWalletState({
isConnected: false
});
};
WalletState Interface
interface WalletState {
isConnected: boolean;
address?: string;
chainId?: string;
chainName?: string;
balance?: string;
nativeCurrency?: {
name: string;
symbol: string;
decimals: number;
};
}
Custom Styles
<HeyElsaChatWidget
keyId="advanced-dapp-v1"
dappName="Advanced DeFi Platform"
messagePort={messagePort}
position="bottom-right"
customStyles={{
primaryColor: '#FF0000',
backgroundColor: '#ffffff',
textColor: '#333333',
borderRadius: '20px'
}}
/>
📚 Summary
Key Points to Remember:
Install the package with:
npm install @heyelsa/chat-widget
Get your Key ID from the HeyElsa Dashboard.
Implement the
createWalletAdapter
function to handle wallet operations.Use
syncWalletState
to keep the widget informed about wallet status from your dApp.Customize styling with the
customStyles
prop.Handle wallet events properly for the best user experience.