# 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

{% code title="Install" %}

```bash
npm install @heyelsa/chat-widget
```

{% endcode %}

🔧 Integration Setup

Basic Implementation

{% code title="Basic React Integration (example)" %}

```tsx
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>
  );
}
```

{% endcode %}

📋 Configuration Props

Props Interface

```ts
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:

{% stepper %}
{% step %}

### Visit Dashboard

Open the HeyElsa Dashboard at: <https://dashboard.widget.heyelsa.dev/widgets>
{% endstep %}

{% step %}

### Create Widget Instance

Create a new widget instance for your dApp.
{% endstep %}

{% step %}

### Copy Key ID

Copy the generated Key ID and use it as the `keyId` prop in your integration.
{% endstep %}
{% endstepper %}

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

{% code title="createWalletAdapter.ts" %}

```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;
}
```

{% endcode %}

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

{% code title="Sync Connected State" %}

```ts
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
    }
  });
};
```

{% endcode %}

Disconnected State

{% code title="Sync Disconnected State" %}

```ts
const handleWalletDisconnect = () => {
  syncWalletState({
    isConnected: false
  });
};
```

{% endcode %}

WalletState Interface

```ts
interface WalletState {
  isConnected: boolean;
  address?: string;
  chainId?: string;
  chainName?: string;
  balance?: string;
  nativeCurrency?: {
    name: string;
    symbol: string;
    decimals: number;
  };
}
```

Custom Styles

{% code title="Custom Styles Example" %}

```tsx
<HeyElsaChatWidget
  keyId="advanced-dapp-v1"
  dappName="Advanced DeFi Platform"
  messagePort={messagePort}
  position="bottom-right"
  customStyles={{
    primaryColor: '#FF0000',
    backgroundColor: '#ffffff',
    textColor: '#333333',
    borderRadius: '20px'
  }}
/>
```

{% endcode %}

📚 Summary

Key Points to Remember:

* Install the package with:

```bash
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.
