# 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.heyelsa.ai/elsa-widget/widget-integration-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
