diff --git a/JamiDaemon.js b/JamiDaemon.js
index 1a32f4b..587a477 100755
--- a/JamiDaemon.js
+++ b/JamiDaemon.js
@@ -17,60 +17,63 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
-"use strict"
+'use strict';
 
-import Account from './model/Account.js'
-import Conversation from './model/Conversation.js'
-import {createRequire} from 'module';
-import path from "path";
+import Account from './model/Account.js';
+import Conversation from './model/Conversation.js';
+import { createRequire } from 'module';
+import path from 'path';
 
 const require = createRequire(import.meta.url);
 
 class JamiDaemon {
-    constructor(onMessage) {
-        this.accounts = []
-        this.lookups = []
-        this.tempAccounts = []
-        this.dring = require(path.join(process.cwd(), "jamid.node"))
-        this.dring.init({
-            AccountsChanged: () => {
-                console.log("AccountsChanged")
-                const newAccounts = []
-                JamiDaemon.vectToJs(this.dring.getAccountList()).forEach(accountId => {
-                    for (const account of this.accounts) {
-                        if (account.getId() === accountId) {
-                            newAccounts.push(account)
-                            return
-                        }
-                    }
-                    newAccounts.push(new Account(accountId,
-                        JamiDaemon.mapToJs(this.dring.getAccountDetails(accountId)),
-                        JamiDaemon.mapToJs(this.dring.getVolatileAccountDetails(accountId))
-                    ))
-                })
-                this.accounts = newAccounts
-            },
-            AccountDetailsChanged: (accountId, details) => {
-                console.log(`AccountDetailsChanged ${accountId}`)
-                const account = this.getAccount(accountId)
-                if (!account) {
-                    console.log(`Unknown account ${accountId}`)
-                    return
-                }
-                account.details = details
-            },
-            VolatileDetailsChanged: (accountId, details) => {
-                console.log(`VolatileDetailsChanged ${accountId}`)
-                const account = this.getAccount(accountId)
-                if (!account) {
-                    console.log(`Unknown account ${accountId}`)
-                    return
-                }
-                account.volatileDetails = details
-            },
-            IncomingAccountMessage: (accountId, from, message) => {
-                console.log(`Received message: ${accountId} ${from} ${message["text/plain"]}`)
-/*
+  constructor(onMessage) {
+    this.accounts = [];
+    this.lookups = [];
+    this.tempAccounts = [];
+    this.dring = require(path.join(process.cwd(), 'jamid.node'));
+    this.dring.init({
+      AccountsChanged: () => {
+        console.log('AccountsChanged');
+        const newAccounts = [];
+        JamiDaemon.vectToJs(this.dring.getAccountList()).forEach((accountId) => {
+          for (const account of this.accounts) {
+            if (account.getId() === accountId) {
+              newAccounts.push(account);
+              return;
+            }
+          }
+          newAccounts.push(
+            new Account(
+              accountId,
+              JamiDaemon.mapToJs(this.dring.getAccountDetails(accountId)),
+              JamiDaemon.mapToJs(this.dring.getVolatileAccountDetails(accountId))
+            )
+          );
+        });
+        this.accounts = newAccounts;
+      },
+      AccountDetailsChanged: (accountId, details) => {
+        console.log(`AccountDetailsChanged ${accountId}`);
+        const account = this.getAccount(accountId);
+        if (!account) {
+          console.log(`Unknown account ${accountId}`);
+          return;
+        }
+        account.details = details;
+      },
+      VolatileDetailsChanged: (accountId, details) => {
+        console.log(`VolatileDetailsChanged ${accountId}`);
+        const account = this.getAccount(accountId);
+        if (!account) {
+          console.log(`Unknown account ${accountId}`);
+          return;
+        }
+        account.volatileDetails = details;
+      },
+      IncomingAccountMessage: (accountId, from, message) => {
+        console.log(`Received message: ${accountId} ${from} ${message['text/plain']}`);
+        /*
                 if (parser.validate(message["text/plain"]) === true) {
                     console.log(message["text/plain"])
                 } else {
@@ -80,473 +83,435 @@
                     io.to(user.socketId).emit('receivedMessage', message["text/plain"])
                     //io.emit('receivedMessage', message["text/plain"])
                 }*/
-            },
-            RegistrationStateChanged: (accountId, state, code, detail) => {
-                console.log("RegistrationStateChanged: " + accountId + " " + state + " " + code + " " + detail)
-                const account = this.getAccount(accountId)
-                if (account) {
-                    account.registrationState = state
-                } else {
-                    console.log(`Unknown account ${accountId}`)
-                }
-                const ctx = this.tempAccounts[accountId]
-                if (ctx) {
-                    if (state === "REGISTERED") {
-                        account.details = JamiDaemon.mapToJs(this.dring.getAccountDetails(accountId))
-                        ctx.resolve(accountId)
-                        delete this.tempAccounts[accountId]
-                    } else if (state === "ERROR_AUTH") {
-                        this.dring.removeAccount(accountId)
-                        ctx.reject(state)
-                        delete this.tempAccounts[accountId]
-                    }
-                }
-            },
-            RegisteredNameFound: (accountId, state, address, name) => {
-                console.log(`RegisteredNameFound: ${accountId} ${state} ${address} ${name}`)
-                let lookups
-                if (accountId) {
-                    const account = this.getAccount(accountId)
-                    if (!account) {
-                        console.log(`Unknown account ${accountId}`)
-                        return
-                    }
-                    if (state == 0) {
-                        const contact = account.getContactFromCache(address)
-                        if (!contact.isRegisteredNameResolved())
-                            contact.setRegisteredName(name)
-                    }
-                    lookups = account.lookups
-                } else {
-                    lookups = this.lookups
-                }
-                let index = lookups.length - 1
-                while (index >= 0) {
-                    const lookup = lookups[index]
-                    if ((lookup.address && lookup.address === address) || (lookup.name && lookup.name === name)) {
-                        lookup.resolve({address, name, state})
-                        lookups.splice(index, 1)
-                    }
-                    index -= 1
-                }
-            },
-            NameRegistrationEnded: (accountId, state, name) => {
-                console.log(`NameRegistrationEnded: ${accountId} ${state} ${name}`)
-                const account = this.getAccount(accountId)
-                if (account) {
-                    if (state === 0)
-                        account.volatileDetails['Account.registeredName'] = name
-                    if (account.registeringName) {
-                        account.registeringName.resolve(state)
-                        delete account.registeringName
-                    }
-                } else {
-                    console.log(`Unknown account ${accountId}`)
-                }
-            },
-            // Conversations
-            ConversationReady: (accountId, conversationId) => {
-                console.log(`conversationReady: ${accountId} ${conversationId}`)
-                const account = this.getAccount(accountId)
-                if (!account) {
-                    console.log(`Unknown account ${accountId}`)
-                    return
-                }
-                let conversation = account.getConversation(conversationId)
-                if (!conversation) {
-                    const members = JamiDaemon.vectMapToJs(this.dring.getConversationMembers(accountId, conversationId))
-                    members.forEach(member => member.contact = account.getContactFromCache(member.uri))
-                    conversation = new Conversation(conversationId, accountId, members)
-                    account.addConversation(conversation)
-                }
-            },
-            ConversationRemoved: (accountId, conversationId) => {
-                console.log(`conversationRemoved: ${accountId} ${conversationId}`)
-                const account = this.getAccount(accountId)
-                if (!account) {
-                    console.log(`Unknown account ${accountId}`)
-                    return
-                }
-                account.removeConversation(conversationId)
-            },
-            ConversationLoaded: (id, accountId, conversationId, messages) => {
-                console.log(`conversationLoaded: ${accountId} ${conversationId}`)
-                const account = this.getAccount(accountId)
-                if (!account) {
-                    console.log(`Unknown account ${accountId}`)
-                    return
-                }
-                const conversation = account.getConversation(conversationId)
-                if (conversation) {
-                    //conversation.addLoadedMessages(messages)
-                    const request = conversation.requests[id]
-                    if (request) {
-                        request.resolve(messages)
-                    }
-                }
-            },
-            MessageReceived: (accountId, conversationId, message) => {
-                console.log(`messageReceived: ${accountId} ${conversationId}`)
-                console.log(message)
-                const account = this.getAccount(accountId)
-                if (!account) {
-                    console.log(`Unknown account ${accountId}`)
-                    return
-                }
-                const conversation = account.getConversation(conversationId)
-                if (conversation) {
-                    conversation.addMessage(message)
-                    if (onMessage)
-                        onMessage(account, conversation, message)
-                }
-            },
-            ConversationRequestReceived: (accountId, conversationId, request) => {
-                console.log(`conversationRequestReceived: ${accountId} ${conversationId}`)
-                const account = this.getAccount(accountId)
-                if (!account) {
-                    console.log(`Unknown account ${accountId}`)
-                    return
-                }
-            },
-            ConversationMemberEvent: (accountId, conversationId, member, event) => {
-                console.log(`conversationMemberEvent: ${accountId} ${conversationId}`)
-                const account = this.getAccount(accountId)
-                if (!account) {
-                    console.log(`Unknown account ${accountId}`)
-                    return
-                }
-            },
-            OnConversationError: (accountId, conversationId, code, what) => {
-                console.log(`onConversationError: ${accountId} ${conversationId}`)
-                const account = this.getAccount(accountId)
-                if (!account) {
-                    console.log(`Unknown account ${accountId}`)
-                    return
-                }
-            },
-            // Calls
-            CallStateChanged: (callId, state, code) => {
-                console.log(`CallStateChanged: ${callId} ${state} ${code}`)
-            },
-            IncomingCall: (accountId, callId, peerUri) => {
-                console.log(`IncomingCall: ${accountId} ${callId} ${peerUri}`)
-            },
-            ConferenceCreated: (confId) => {
-                console.log(`ConferenceCreated: ${confId}`)
-            },
-            ConferenceChanged: (confId, state) => {
-                console.log(`ConferenceChanged: ${confId}`)
-
-            },
-            ConferenceRemoved: (confId) => {
-                console.log(`ConferenceRemoved: ${confId}`)
-
-            },
-            OnConferenceInfosUpdated: (confId, info) => {
-                console.log(`onConferenceInfosUpdated: ${confId}`)
-
-            }
-        })
-
-        JamiDaemon.vectToJs(this.dring.getAccountList()).forEach(accountId => {
-            const account = new Account(accountId,
-                JamiDaemon.mapToJs(this.dring.getAccountDetails(accountId)),
-                JamiDaemon.mapToJs(this.dring.getVolatileAccountDetails(accountId))
-            )
-
-            account.contacts = JamiDaemon.vectMapToJs(
-              this.dring.getContacts(accountId)
-            );
-
-            JamiDaemon.vectToJs(this.dring.getConversations(accountId)).forEach(conversationId => {
-                const members = JamiDaemon.vectMapToJs(this.dring.getConversationMembers(accountId, conversationId))
-                console.log("\n\nXMEMBERS: ", members)
-                members.forEach(member => {
-                    member.contact = account.getContactFromCache(member.uri)
-                    if (!member.contact.isRegisteredNameResolved()) {
-                        if (!member.uri) return
-                        console.log(`lookupAddress ${accountId} ${member.uri}`, member)
-                        member.contact.setRegisteredName(new Promise((resolve, reject) =>
-                            account.lookups.push({address: member.uri, resolve, reject})
-                        ).then(result => {
-                            if (result.state == 0)
-                                return result.name
-                            else if (result.state == 1)
-                                return undefined
-                            else
-                                return null
-                        }))
-                        this.dring.lookupAddress(accountId, "", member.uri)
-                    }
-                })
-                const conversation = new Conversation(conversationId, accountId, members)
-                conversation.setInfos(JamiDaemon.mapToJs(this.dring.conversationInfos(accountId, conversationId)))
-                account.addConversation(conversation)
-            })
-            account.setDevices(
-            );
-
-            this.accounts.push(account);
-        })
-    }
-
-    addAccount(accountConfig) {
-        const params = this.accountDetailsToNative(accountConfig)
-        params.set("Account.type", "RING")
-        return new Promise((resolve, reject) => {
-            const accountId = this.dring.addAccount(params)
-            this.tempAccounts[accountId] = { resolve, reject }
-        })
-    }
-
-    getDevices(accountId){
-        return JamiDaemon.mapToJs(this.dring.getKnownRingDevices(accountId));
-    }
-
-    getAccount(accountId) {
-        for (let i = 0; i < this.accounts.length; i++) {
-            const account = this.accounts[i]
-            if (account.getId() === accountId)
-                return account
+      },
+      RegistrationStateChanged: (accountId, state, code, detail) => {
+        console.log('RegistrationStateChanged: ' + accountId + ' ' + state + ' ' + code + ' ' + detail);
+        const account = this.getAccount(accountId);
+        if (account) {
+          account.registrationState = state;
+        } else {
+          console.log(`Unknown account ${accountId}`);
         }
-        return undefined
-    }
-    getAccountList() {
-        return this.accounts
-    }
-    registerName(accountId, password, name) {
-        return new Promise((resolve, reject) => {
-            if (!name)
-                return reject(new Error("Invalid name"))
-            const account = this.getAccount(accountId)
-            if (!account)
-                return reject(new Error("Can't find account"))
-            if (account.registeringName)
-                return reject(new Error("Username already being registered"))
-            if (this.dring.registerName(accountId, password, name)) {
-                account.registeringName = { name, resolve, reject }
-            }
-        })
-    }
-
-    getConversation(accountId, conversationId) {
-        const account = this.getAccount(accountId)
-        if (account)
-            return account.getConversation(conversationId)
-        return null
-    }
-    getAccountDetails(accountId) {
-        return JamiDaemon.mapToJs(this.dring.getAccountDetails(accountId))
-    }
-    setAccountDetails(accountId, details) {
-        this.dring.setAccountDetails(accountId, this.mapToNative(details))
-    }
-    getAudioOutputDeviceList() {
-        return JamiDaemon.vectToJs(this.dring.getAudioOutputDeviceList())
-    }
-    getVolume(deviceName) {
-        return this.dring.getVolume(deviceName)
-    }
-    setVolume(deviceName, volume) {
-        return this.dring.setVolume(deviceName, volume)
-    }
-
-    lookupName(accountId, name) {
-        const p = new Promise((resolve, reject) => {
-            if (accountId) {
-                const account = this.getAccount(accountId)
-                if (!account) {
-                    reject(new Error("Can't find account"))
-                } else {
-                    account.lookups.push({ name, resolve, reject })
-                }
-            } else {
-                this.lookups.push({ name, resolve, reject })
-            }
-        })
-        this.dring.lookupName(accountId || '', '', name)
-        return p
-    }
-
-    lookupAddress(accountId, address) {
-        console.log(`lookupAddress ${accountId} ${address}`)
-        const p = new Promise((resolve, reject) => {
-            if (accountId) {
-                const account = this.getAccount(accountId)
-                if (!account) {
-                    reject(new Error("Can't find account"))
-                } else {
-                    account.lookups.push({ address, resolve, reject })
-                }
-            } else {
-                this.lookups.push({ address, resolve, reject })
-            }
-        })
-        this.dring.lookupAddress(accountId || '', '', address)
-        return p
-    }
-
-    stop() {
-        this.dring.fini()
-    }
-
-    addContact(accountId, contactId) {
-        this.dring.addContact(accountId, contactId)
-        const details = JamiDaemon.mapToJs(this.dring.getContactDetails(accountId, contactId))
-        if (details.conversationId) {
-            const account = this.getAccount(accountId)
-            if (account) {
-                let conversation = account.getConversation(details.conversationId)
-                if (!conversation) {
-                    const members = JamiDaemon.vectMapToJs(this.dring.getConversationMembers(accountId, details.conversationId))
-                    members.forEach(member => member.contact = account.getContactFromCache(member.uri))
-                    conversation = new Conversation(details.conversationId, accountId, members)
-                    account.addConversation(conversation)
-                }
-            }
+        const ctx = this.tempAccounts[accountId];
+        if (ctx) {
+          if (state === 'REGISTERED') {
+            account.details = JamiDaemon.mapToJs(this.dring.getAccountDetails(accountId));
+            ctx.resolve(accountId);
+            delete this.tempAccounts[accountId];
+          } else if (state === 'ERROR_AUTH') {
+            this.dring.removeAccount(accountId);
+            ctx.reject(state);
+            delete this.tempAccounts[accountId];
+          }
         }
-        return details
-    }
-
-    removeContact(accountId, contactId){
-        //bool ban false
-        this.dring.removeContact(accountId, contactId, false);
-    }
-
-    blockContact(accountId, contactId){
-        //bool ban true
-        this.dring.removeContact(accountId, contactId, true);
-    }
-
-    getContactDetails(accountId, contactId){
-        return JamiDaemon.mapToJs(this.dring.getContactDetails(accountId, contactId))
-    }
-
-    getDefaultModerators(accountId) {
-        const account = this.getAccount(accountId)
+      },
+      RegisteredNameFound: (accountId, state, address, name) => {
+        console.log(`RegisteredNameFound: ${accountId} ${state} ${address} ${name}`);
+        let lookups;
+        if (accountId) {
+          const account = this.getAccount(accountId);
+          if (!account) {
+            console.log(`Unknown account ${accountId}`);
+            return;
+          }
+          if (state == 0) {
+            const contact = account.getContactFromCache(address);
+            if (!contact.isRegisteredNameResolved()) contact.setRegisteredName(name);
+          }
+          lookups = account.lookups;
+        } else {
+          lookups = this.lookups;
+        }
+        let index = lookups.length - 1;
+        while (index >= 0) {
+          const lookup = lookups[index];
+          if ((lookup.address && lookup.address === address) || (lookup.name && lookup.name === name)) {
+            lookup.resolve({ address, name, state });
+            lookups.splice(index, 1);
+          }
+          index -= 1;
+        }
+      },
+      NameRegistrationEnded: (accountId, state, name) => {
+        console.log(`NameRegistrationEnded: ${accountId} ${state} ${name}`);
+        const account = this.getAccount(accountId);
+        if (account) {
+          if (state === 0) account.volatileDetails['Account.registeredName'] = name;
+          if (account.registeringName) {
+            account.registeringName.resolve(state);
+            delete account.registeringName;
+          }
+        } else {
+          console.log(`Unknown account ${accountId}`);
+        }
+      },
+      // Conversations
+      ConversationReady: (accountId, conversationId) => {
+        console.log(`conversationReady: ${accountId} ${conversationId}`);
+        const account = this.getAccount(accountId);
         if (!account) {
-            console.log(`Unknown account ${accountId}`)
-            return {}
+          console.log(`Unknown account ${accountId}`);
+          return;
         }
-        return JamiDaemon.vectToJs(this.dring.getDefaultModerators(accountId))
-            .map(contactId => account.getContactFromCache(contactId))
+        let conversation = account.getConversation(conversationId);
+        if (!conversation) {
+          const members = JamiDaemon.vectMapToJs(this.dring.getConversationMembers(accountId, conversationId));
+          members.forEach((member) => (member.contact = account.getContactFromCache(member.uri)));
+          conversation = new Conversation(conversationId, accountId, members);
+          account.addConversation(conversation);
+        }
+      },
+      ConversationRemoved: (accountId, conversationId) => {
+        console.log(`conversationRemoved: ${accountId} ${conversationId}`);
+        const account = this.getAccount(accountId);
+        if (!account) {
+          console.log(`Unknown account ${accountId}`);
+          return;
+        }
+        account.removeConversation(conversationId);
+      },
+      ConversationLoaded: (id, accountId, conversationId, messages) => {
+        console.log(`conversationLoaded: ${accountId} ${conversationId}`);
+        const account = this.getAccount(accountId);
+        if (!account) {
+          console.log(`Unknown account ${accountId}`);
+          return;
+        }
+        const conversation = account.getConversation(conversationId);
+        if (conversation) {
+          //conversation.addLoadedMessages(messages)
+          const request = conversation.requests[id];
+          if (request) {
+            request.resolve(messages);
+          }
+        }
+      },
+      MessageReceived: (accountId, conversationId, message) => {
+        console.log(`messageReceived: ${accountId} ${conversationId}`);
+        console.log(message);
+        const account = this.getAccount(accountId);
+        if (!account) {
+          console.log(`Unknown account ${accountId}`);
+          return;
+        }
+        const conversation = account.getConversation(conversationId);
+        if (conversation) {
+          conversation.addMessage(message);
+          if (onMessage) onMessage(account, conversation, message);
+        }
+      },
+      ConversationRequestReceived: (accountId, conversationId, request) => {
+        console.log(`conversationRequestReceived: ${accountId} ${conversationId}`);
+        const account = this.getAccount(accountId);
+        if (!account) {
+          console.log(`Unknown account ${accountId}`);
+          return;
+        }
+      },
+      ConversationMemberEvent: (accountId, conversationId, member, event) => {
+        console.log(`conversationMemberEvent: ${accountId} ${conversationId}`);
+        const account = this.getAccount(accountId);
+        if (!account) {
+          console.log(`Unknown account ${accountId}`);
+          return;
+        }
+      },
+      OnConversationError: (accountId, conversationId, code, what) => {
+        console.log(`onConversationError: ${accountId} ${conversationId}`);
+        const account = this.getAccount(accountId);
+        if (!account) {
+          console.log(`Unknown account ${accountId}`);
+          return;
+        }
+      },
+      // Calls
+      CallStateChanged: (callId, state, code) => {
+        console.log(`CallStateChanged: ${callId} ${state} ${code}`);
+      },
+      IncomingCall: (accountId, callId, peerUri) => {
+        console.log(`IncomingCall: ${accountId} ${callId} ${peerUri}`);
+      },
+      ConferenceCreated: (confId) => {
+        console.log(`ConferenceCreated: ${confId}`);
+      },
+      ConferenceChanged: (confId, state) => {
+        console.log(`ConferenceChanged: ${confId}`);
+      },
+      ConferenceRemoved: (confId) => {
+        console.log(`ConferenceRemoved: ${confId}`);
+      },
+      OnConferenceInfosUpdated: (confId, info) => {
+        console.log(`onConferenceInfosUpdated: ${confId}`);
+      },
+    });
+
+    JamiDaemon.vectToJs(this.dring.getAccountList()).forEach((accountId) => {
+      const account = new Account(
+        accountId,
+        JamiDaemon.mapToJs(this.dring.getAccountDetails(accountId)),
+        JamiDaemon.mapToJs(this.dring.getVolatileAccountDetails(accountId))
+      );
+
+      account.contacts = JamiDaemon.vectMapToJs(this.dring.getContacts(accountId));
+
+      JamiDaemon.vectToJs(this.dring.getConversations(accountId)).forEach((conversationId) => {
+        const members = JamiDaemon.vectMapToJs(this.dring.getConversationMembers(accountId, conversationId));
+        console.log('\n\nXMEMBERS: ', members);
+        members.forEach((member) => {
+          member.contact = account.getContactFromCache(member.uri);
+          if (!member.contact.isRegisteredNameResolved()) {
+            if (!member.uri) return;
+            console.log(`lookupAddress ${accountId} ${member.uri}`, member);
+            member.contact.setRegisteredName(
+              new Promise((resolve, reject) => account.lookups.push({ address: member.uri, resolve, reject })).then(
+                (result) => {
+                  if (result.state == 0) return result.name;
+                  else if (result.state == 1) return undefined;
+                  else return null;
+                }
+              )
+            );
+            this.dring.lookupAddress(accountId, '', member.uri);
+          }
+        });
+        const conversation = new Conversation(conversationId, accountId, members);
+        conversation.setInfos(JamiDaemon.mapToJs(this.dring.conversationInfos(accountId, conversationId)));
+        account.addConversation(conversation);
+      });
+      account.setDevices();
+
+      this.accounts.push(account);
+    });
+  }
+
+  addAccount(accountConfig) {
+    const params = this.accountDetailsToNative(accountConfig);
+    params.set('Account.type', 'RING');
+    return new Promise((resolve, reject) => {
+      const accountId = this.dring.addAccount(params);
+      this.tempAccounts[accountId] = { resolve, reject };
+    });
+  }
+
+  getDevices(accountId) {
+    return JamiDaemon.mapToJs(this.dring.getKnownRingDevices(accountId));
+  }
+
+  getAccount(accountId) {
+    for (let i = 0; i < this.accounts.length; i++) {
+      const account = this.accounts[i];
+      if (account.getId() === accountId) return account;
     }
+    return undefined;
+  }
+  getAccountList() {
+    return this.accounts;
+  }
+  registerName(accountId, password, name) {
+    return new Promise((resolve, reject) => {
+      if (!name) return reject(new Error('Invalid name'));
+      const account = this.getAccount(accountId);
+      if (!account) return reject(new Error("Can't find account"));
+      if (account.registeringName) return reject(new Error('Username already being registered'));
+      if (this.dring.registerName(accountId, password, name)) {
+        account.registeringName = { name, resolve, reject };
+      }
+    });
+  }
 
-    addDefaultModerator(accountId, uri) {
-        this.dring.setDefaultModerator(accountId, uri, true)
+  getConversation(accountId, conversationId) {
+    const account = this.getAccount(accountId);
+    if (account) return account.getConversation(conversationId);
+    return null;
+  }
+  getAccountDetails(accountId) {
+    return JamiDaemon.mapToJs(this.dring.getAccountDetails(accountId));
+  }
+  setAccountDetails(accountId, details) {
+    this.dring.setAccountDetails(accountId, this.mapToNative(details));
+  }
+  getAudioOutputDeviceList() {
+    return JamiDaemon.vectToJs(this.dring.getAudioOutputDeviceList());
+  }
+  getVolume(deviceName) {
+    return this.dring.getVolume(deviceName);
+  }
+  setVolume(deviceName, volume) {
+    return this.dring.setVolume(deviceName, volume);
+  }
+
+  lookupName(accountId, name) {
+    const p = new Promise((resolve, reject) => {
+      if (accountId) {
+        const account = this.getAccount(accountId);
+        if (!account) {
+          reject(new Error("Can't find account"));
+        } else {
+          account.lookups.push({ name, resolve, reject });
+        }
+      } else {
+        this.lookups.push({ name, resolve, reject });
+      }
+    });
+    this.dring.lookupName(accountId || '', '', name);
+    return p;
+  }
+
+  lookupAddress(accountId, address) {
+    console.log(`lookupAddress ${accountId} ${address}`);
+    const p = new Promise((resolve, reject) => {
+      if (accountId) {
+        const account = this.getAccount(accountId);
+        if (!account) {
+          reject(new Error("Can't find account"));
+        } else {
+          account.lookups.push({ address, resolve, reject });
+        }
+      } else {
+        this.lookups.push({ address, resolve, reject });
+      }
+    });
+    this.dring.lookupAddress(accountId || '', '', address);
+    return p;
+  }
+
+  stop() {
+    this.dring.fini();
+  }
+
+  addContact(accountId, contactId) {
+    this.dring.addContact(accountId, contactId);
+    const details = JamiDaemon.mapToJs(this.dring.getContactDetails(accountId, contactId));
+    if (details.conversationId) {
+      const account = this.getAccount(accountId);
+      if (account) {
+        let conversation = account.getConversation(details.conversationId);
+        if (!conversation) {
+          const members = JamiDaemon.vectMapToJs(this.dring.getConversationMembers(accountId, details.conversationId));
+          members.forEach((member) => (member.contact = account.getContactFromCache(member.uri)));
+          conversation = new Conversation(details.conversationId, accountId, members);
+          account.addConversation(conversation);
+        }
+      }
     }
+    return details;
+  }
 
-    removeDefaultModerator(accountId, uri) {
-        this.dring.setDefaultModerator(accountId, uri, false)
+  removeContact(accountId, contactId) {
+    //bool ban false
+    this.dring.removeContact(accountId, contactId, false);
+  }
+
+  blockContact(accountId, contactId) {
+    //bool ban true
+    this.dring.removeContact(accountId, contactId, true);
+  }
+
+  getContactDetails(accountId, contactId) {
+    return JamiDaemon.mapToJs(this.dring.getContactDetails(accountId, contactId));
+  }
+
+  getDefaultModerators(accountId) {
+    const account = this.getAccount(accountId);
+    if (!account) {
+      console.log(`Unknown account ${accountId}`);
+      return {};
     }
+    return JamiDaemon.vectToJs(this.dring.getDefaultModerators(accountId)).map((contactId) =>
+      account.getContactFromCache(contactId)
+    );
+  }
 
-    sendMessage(accountId, conversationId, message) {
-        this.dring.sendMessage(accountId, conversationId, message, "")
-    }
+  addDefaultModerator(accountId, uri) {
+    this.dring.setDefaultModerator(accountId, uri, true);
+  }
 
-    loadMessages(accountId, conversationId, fromMessage) {
-        const account = this.getAccount(accountId)
-        if (!account)
-            throw new Error('Unknown account')
-        const conversation = account.getConversation(conversationId)
-        if (!conversation)
-            throw new Error(`Unknown conversation ${conversationId}`)
+  removeDefaultModerator(accountId, uri) {
+    this.dring.setDefaultModerator(accountId, uri, false);
+  }
 
-        return new Promise((resolve, reject) => {
-            if (!conversation.requests)
-                conversation.requests = {}
-            const requestId = this.dring.loadConversationMessages(accountId, conversationId, fromMessage || "", 32)
-            conversation.requests[requestId] = {resolve, reject}
-        })
-    }
+  sendMessage(accountId, conversationId, message) {
+    this.dring.sendMessage(accountId, conversationId, message, '');
+  }
 
-    boolToStr(bool) {
-        return bool ? "true" : "false"
-    }
+  loadMessages(accountId, conversationId, fromMessage) {
+    const account = this.getAccount(accountId);
+    if (!account) throw new Error('Unknown account');
+    const conversation = account.getConversation(conversationId);
+    if (!conversation) throw new Error(`Unknown conversation ${conversationId}`);
 
-    accountDetailsToNative(account) {
-        const params = new this.dring.StringMap()
-        if (account.managerUri)
-            params.set("Account.managerUri", account.managerUri)
-        if (account.managerUsername)
-            params.set("Account.managerUsername", account.managerUsername)
-        if (account.archivePassword) {
-            params.set("Account.archivePassword", account.archivePassword)
-        }/* else {
+    return new Promise((resolve, reject) => {
+      if (!conversation.requests) conversation.requests = {};
+      const requestId = this.dring.loadConversationMessages(accountId, conversationId, fromMessage || '', 32);
+      conversation.requests[requestId] = { resolve, reject };
+    });
+  }
+
+  boolToStr(bool) {
+    return bool ? 'true' : 'false';
+  }
+
+  accountDetailsToNative(account) {
+    const params = new this.dring.StringMap();
+    if (account.managerUri) params.set('Account.managerUri', account.managerUri);
+    if (account.managerUsername) params.set('Account.managerUsername', account.managerUsername);
+    if (account.archivePassword) {
+      params.set('Account.archivePassword', account.archivePassword);
+    } /* else {
             console.log("archivePassword required")
             return
         }*/
-        if (account.alias)
-            params.set("Account.alias", account.alias)
-        if (account.displayName)
-            params.set("Account.displayName", account.displayName)
-        if (account.enable !== undefined)
-            params.set("Account.enable", this.boolToStr(account.enable))
-        if (account.autoAnswer !== undefined)
-            params.set("Account.autoAnswer", this.boolToStr(account.autoAnswer))
-        if (account.autoAnswer !== undefined)
-            params.set("Account.autoAnswer", this.boolToStr(account.autoAnswer))
-        if (account.ringtonePath)
-            params.set("Account.ringtonePath", account.ringtonePath)
-        if (account.ringtoneEnabled !== undefined)
-            params.set("Account.ringtoneEnabled", this.boolToStr(account.ringtoneEnabled))
-        if (account.videoEnabled !== undefined)
-            params.set("Account.videoEnabled", this.boolToStr(account.videoEnabled))
-        if (account.useragent) {
-            params.set("Account.useragent", account.useragent)
-            params.set("Account.hasCustomUserAgent", "TRUE")
-        } else {
-            params.set("Account.hasCustomUserAgent", "FALSE")
-        }
-        if (account.audioPortMin)
-            params.set("Account.audioPortMin", account.audioPortMin)
-        if (account.audioPortMax)
-            params.set("Account.audioPortMax", account.audioPortMax)
-        if (account.videoPortMin)
-            params.set("Account.videoPortMin", account.videoPortMin)
-        if (account.videoPortMax)
-            params.set("Account.videoPortMax", account.videoPortMax)
-        if (account.localInterface)
-            params.set("Account.localInterface", account.localInterface)
-        if (account.publishedSameAsLocal !== undefined)
-            params.set("Account.publishedSameAsLocal", this.boolToStr(account.publishedSameAsLocal))
-        if (account.localPort)
-            params.set("Account.localPort", account.localPort)
-        if (account.publishedPort)
-            params.set("Account.publishedPort", account.publishedPort)
-        if (account.rendezVous !== undefined)
-            params.set("Account.rendezVous", this.boolToStr(account.rendezVous))
-        if (account.upnpEnabled !== undefined)
-            params.set("Account.upnpEnabled", this.boolToStr(account.upnpEnabled))
-        return params
+    if (account.alias) params.set('Account.alias', account.alias);
+    if (account.displayName) params.set('Account.displayName', account.displayName);
+    if (account.enable !== undefined) params.set('Account.enable', this.boolToStr(account.enable));
+    if (account.autoAnswer !== undefined) params.set('Account.autoAnswer', this.boolToStr(account.autoAnswer));
+    if (account.autoAnswer !== undefined) params.set('Account.autoAnswer', this.boolToStr(account.autoAnswer));
+    if (account.ringtonePath) params.set('Account.ringtonePath', account.ringtonePath);
+    if (account.ringtoneEnabled !== undefined)
+      params.set('Account.ringtoneEnabled', this.boolToStr(account.ringtoneEnabled));
+    if (account.videoEnabled !== undefined) params.set('Account.videoEnabled', this.boolToStr(account.videoEnabled));
+    if (account.useragent) {
+      params.set('Account.useragent', account.useragent);
+      params.set('Account.hasCustomUserAgent', 'TRUE');
+    } else {
+      params.set('Account.hasCustomUserAgent', 'FALSE');
     }
-    static vectToJs(vect) {
-        const len = vect.size()
-        const outputArr = new Array(len)
-        for (let i = 0; i < len; i++)
-            outputArr[i] = vect.get(i)
-        return outputArr
-    }
-    static mapToJs(m) {
-        const outputObj = {}
-        JamiDaemon.vectToJs(m.keys())
-            .forEach(k => outputObj[k] = m.get(k))
-        return outputObj
-    }
-    static vectMapToJs(vectMap) {
-        const len = vectMap.size()
-        const outputArr = new Array(len)
-        for (let i = 0; i < len; i++)
-            outputArr[i] = JamiDaemon.mapToJs(vectMap.get(i))
-        return outputArr
-    }
+    if (account.audioPortMin) params.set('Account.audioPortMin', account.audioPortMin);
+    if (account.audioPortMax) params.set('Account.audioPortMax', account.audioPortMax);
+    if (account.videoPortMin) params.set('Account.videoPortMin', account.videoPortMin);
+    if (account.videoPortMax) params.set('Account.videoPortMax', account.videoPortMax);
+    if (account.localInterface) params.set('Account.localInterface', account.localInterface);
+    if (account.publishedSameAsLocal !== undefined)
+      params.set('Account.publishedSameAsLocal', this.boolToStr(account.publishedSameAsLocal));
+    if (account.localPort) params.set('Account.localPort', account.localPort);
+    if (account.publishedPort) params.set('Account.publishedPort', account.publishedPort);
+    if (account.rendezVous !== undefined) params.set('Account.rendezVous', this.boolToStr(account.rendezVous));
+    if (account.upnpEnabled !== undefined) params.set('Account.upnpEnabled', this.boolToStr(account.upnpEnabled));
+    return params;
+  }
+  static vectToJs(vect) {
+    const len = vect.size();
+    const outputArr = new Array(len);
+    for (let i = 0; i < len; i++) outputArr[i] = vect.get(i);
+    return outputArr;
+  }
+  static mapToJs(m) {
+    const outputObj = {};
+    JamiDaemon.vectToJs(m.keys()).forEach((k) => (outputObj[k] = m.get(k)));
+    return outputObj;
+  }
+  static vectMapToJs(vectMap) {
+    const len = vectMap.size();
+    const outputArr = new Array(len);
+    for (let i = 0; i < len; i++) outputArr[i] = JamiDaemon.mapToJs(vectMap.get(i));
+    return outputArr;
+  }
 
-    mapToNative(map){
-        const ret = new this.dring.StringMap()
-        for (const [key, value] of Object.entries(map))
-            ret.set(key, value)
-        return ret
-    }
+  mapToNative(map) {
+    const ret = new this.dring.StringMap();
+    for (const [key, value] of Object.entries(map)) ret.set(key, value);
+    return ret;
+  }
 }
 
-export default JamiDaemon
+export default JamiDaemon;
