🤝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

Install
npm install @heyelsa/chat-widget

🔧 Integration Setup

Basic Implementation

Basic React Integration (example)
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

Prop
Type
Required
Default
Description

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:

1

Visit Dashboard

Open the HeyElsa Dashboard at: https://dashboard.widget.heyelsa.dev/widgets

2

Create Widget Instance

Create a new widget instance for your dApp.

3

Copy Key ID

Copy the generated Key ID and use it as the keyId prop in your integration.

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

createWalletAdapter.ts
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

Action
Description
Parameters

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

Sync 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

Sync 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

Custom Styles Example
<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.