# Extensible Message Interface

Sending.Network provides an extension plug-in platform, enabling developers to enrich the messaging features by interacting with third-party dapps or smart contracts.

Currently, Sending.Network has 3 built-in plugin projects: *message-type-plugin*, *did-method-plugin* and *social-graph-plugin*, and developers are free to develop other plugin projects. Plugin projects are lightweight, pluggable, and easy to deploy. The following sections introduce how to compile and deploy *message-type-plugin* plugin projects in environments like Web, IOS, and Android.

## 1. JavaScript

### 1.1 Compile and install

{% hint style="info" %}
Please contact <developer@sending.network> for the wasm files.
{% endhint %}

At the root directory of message-type-plugin

```bash
// generate the wasm package of the plugin project
cd message-type-plugin
./build-wasm.sh
```

A package called `message-type-plugin.wasm` will be found in the directory `web/`.

At the root directory of the Radix main project

```bash
// generate the wasm package of the Radix main project
cd radix
./build-wasm.sh

// generate service worker sw.js
cd web/
yarn install
yarn build
```

A package called *server.wasm* will be found in the directory `web/`. *sw\.js* will be generated in the `web/dist/`.

### 1.2 Deploy and Register

#### **1.2.1 Deploy**

Replace the *sw\.js* and two wasm packages with the newly built ones, clear the web page cache data and refresh it.

#### **1.2.2 Register the Plugin**&#x20;

By launching the `message-type-plugin.wasm`, the plugin will be automatically registered into Radix main Process. However, you can also register/unregister the plugin by executing console scripts. In the console of your Chrome browser, run the following scripts to register/unregister trading Dapp plugins like Lucky Box and Peer Swap.

```javascript
//Register LuckyBox
fetch('http://pluginoperate/register_plugin', {
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            'type': 'MessageType',
            'name': 'LuckyBox',
            'http_base_url': 'http://messagetypeplugin'
        })
    })
        .then(response => response.json())
        .then(response => console.log(JSON.stringify(response)));
        
//Unregister LuckyBox
fetch('http://pluginoperate/unregister_plugin', {
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            'type': 'MessageType',
            'name': 'LuckyBox'
        })
    })
        .then(response => response.json())
        .then(response => console.log(JSON.stringify(response)));
        
//Register PeerSwap
fetch('http://pluginoperate/register_plugin', {
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            'type': 'MessageType',
            'name': 'PeerSwap',
            'http_base_url': 'http://messagetypeplugin'
        })
    })
        .then(response => response.json())
        .then(response => console.log(JSON.stringify(response)));
        
//Unregister PeerSwap
fetch('http://pluginoperate/unregister_plugin', {
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            'type': 'MessageType',
            'name': 'PeerSwap'
        })
    })
        .then(response => response.json())
        .then(response => console.log(JSON.stringify(response)));
```

### 1.3. Use the Plugin

Plugin features can be used by calling the interfaces from the frontend.

For instance, `http://localhost/_api/media/v3/query_message_type` this interface can return all of the supported trading Dapp message types.

The frontend can fetch all of the registered plugins by calling this API.

## 2. iOS & Android

### 2.1 Compile the Plugin Project

At the root directory of *message-type-plugin:*

```bash
// iOS
cd message-type-plugin
bash build/gobind-plugin/build.sh -i

//Android
cd message-type-plugin
bash build/gobind-plugin/build.sh -a
```

Then integrate the generated packages into your iOS or Android SDK.

## 3. Dapp Callback

In Web3 trading Dapps, there are always some scenes that you need to call a JS API to query data like a user profile. In Sending.Network, trading Dapps like LuckyBox and PeerSwap will fetch user profiles and interact with the P2P nodes. The following section provides a generic guide on how to call a JS API from third-party Dapps.

### 3.1 Preparation

1. Install `postmate`

```bash
yarn add postmate
```

### 3.2 API Provider (Web applications that provide APIs to Dapps)

1. Provide an *iframe* container to load Dapps:

   <pre class="language-html"><code class="lang-html"><strong>&#x3C;div className="iframeContainer" ref={frameContainerRef}>&#x3C;/div>
   </strong></code></pre>
2. Create an *iframe* and load Dapp:

   ```javascript
   const postmateRef = new Postmate({
         url,
         container: frameContainerRef.current,
         classListArray: ["iframe"],
       });
   ```
3. Define an API for Dapps:

   ```javascript
     const actionMethods = (payload) => {
       if (payload.action === "api名称") {
         //  fetch data
         let data = fetch('**')
         //  callback and return the data to DApps
         payload.callback({
           id: payload.id,
           data,
         });
       }
     }  

   const bindPostmate = () => {
       postmateRef.then((child) => {
         child.on("message.sending.me", ({ payload }) => {
           if (payload?.id) {
             payload.callback = (data) => {
               child.call("message.sending.me", data);
             };
           }
           actionMethods(payload);
         });
       });
     };
   ```

### 3.3 Call an API

1. Define a JS class to perform callback:

   ```typescript
   class SdmCallback {
       static callbacks: any = {}

       static addCallback(id:any, cb:any) {
         console.log(`add callback: \nid: ${id}\ncb:${cb}\n`);
         this.callbacks[id] = cb
       };
       static executeCallback(id: any, error: any, value: any) {
           console.log(`executing callback: \nid: ${id}\nvalue: ${value}\nerror: ${error}\n`)

           let callback = this.callbacks[id]

           if (error) {
               console.log(`executing error callback: \nid: ${id}\nvalue: ${value}\nerror: ${error}\n`)
               callback(error)
           } else {
               console.log(`executing success callback: \nid: ${id}\nvalue: ${value}\nerror: ${error}\n`)
               callback(value)
           }

           delete this.callbacks[id]
       };
   }
   ```
2. Expose your model to the Parent. Property values may be functions, promises, or regular values.

   ```javascript
       const postmate = new Postmate.Model({
         "message.sending.me": ({id, error, data}: any )=>{
           SdmCallback.executeCallback(id, error, data)
         }
       });
   ```
3. Call the Parent's API

   ```javascript
       postmate.then((parent)=>{
         const { id = Math.floor((Math.random() * 200000) + 1) } = {}
         SdmCallback.addCallback(id, callback)
         parent.emit('message.sending.me', {
           payload: {
             action: 'getMyProfile',
             id,
           }
         });
       })
   ```


---

# 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://sending-network.gitbook.io/sending.network/sdk-documentation/extensible-message-interface.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.
