diff --git a/src/fileutils.cpp b/src/fileutils.cpp
index 0a5564af4768825579eacbb0ede16dbf8e3b840b..0d267a4a32645a4a0c48bd419d2254586979c826 100644
--- a/src/fileutils.cpp
+++ b/src/fileutils.cpp
@@ -26,7 +26,9 @@
 
 #include "logger.h"
 #include "fileutils.h"
+#include "archiver.h"
 #include "compiler_intrinsics.h"
+#include <opendht/crypto.h>
 
 #ifdef RING_UWP
 #include <io.h> // for access and close
@@ -404,6 +406,55 @@ readDirectory(const std::string& dir)
     return files;
 }
 
+std::vector<uint8_t>
+readArchive(const std::string& path, const std::string& pwd)
+{
+    RING_DBG("Reading archive from %s", path.c_str());
+
+    std::vector<uint8_t> data;
+    if (pwd.empty()) {
+        data = archiver::decompressGzip(path);
+    } else {
+        // Read file
+        try {
+            data = loadFile(path);
+        } catch (const std::exception& e) {
+            RING_ERR("Error loading archive: %s", e.what());
+            throw;
+        }
+        // Decrypt
+        try {
+            data = archiver::decompress(dht::crypto::aesDecrypt(data, pwd));
+        } catch (const std::exception& e) {
+            RING_ERR("Error decrypting archive: %s", e.what());
+            throw;
+        }
+    }
+    return data;
+}
+
+void
+writeArchive(const std::string& archive_str, const std::string& path, const std::string& password)
+{
+    RING_DBG("Writing archive to %s", path.c_str());
+
+    if (not password.empty()) {
+        // Encrypt using provided password
+        std::vector<uint8_t> data = dht::crypto::aesEncrypt(archiver::compress(archive_str), password);
+        // Write
+        try {
+            saveFile(path, data);
+        } catch (const std::runtime_error& ex) {
+            RING_ERR("Export failed: %s", ex.what());
+            return;
+        }
+    } else {
+        RING_WARN("Unsecured archiving (no password)");
+        archiver::compressGzip(archive_str, path);
+    }
+}
+
+
 FileHandle::FileHandle(const std::string &n) : fd(-1), name(n)
 {}
 
diff --git a/src/fileutils.h b/src/fileutils.h
index 10e65c28d90a13d9b3d6589b849c0df9d97f6c42..790e46eec39b1741e375dad90988702de69e192a 100644
--- a/src/fileutils.h
+++ b/src/fileutils.h
@@ -103,6 +103,9 @@ namespace ring { namespace fileutils {
     std::vector<uint8_t> loadFile(const std::string& path, const std::string& default_dir = {});
     void saveFile(const std::string& path, const std::vector<uint8_t>& data, mode_t mode=0644);
 
+    std::vector<uint8_t> readArchive(const std::string& path, const std::string& password = {});
+    void writeArchive(const std::string& data, const std::string& path, const std::string& password = {});
+
     struct FileHandle {
         int fd;
         const std::string name;
diff --git a/src/ringdht/Makefile.am b/src/ringdht/Makefile.am
index c5244149ab17f017a32d81b89e9f03a7b57b2393..8727a50d6bd4d306d340a8828f2ea3f8417707d4 100644
--- a/src/ringdht/Makefile.am
+++ b/src/ringdht/Makefile.am
@@ -19,7 +19,9 @@ libringacc_la_SOURCES = \
         ringaccount.cpp \
         ringaccount.h \
         sips_transport_ice.cpp \
-        sips_transport_ice.h
+        sips_transport_ice.h \
+        accountarchive.cpp \
+        accountarchive.h
 
 if RINGNS
 libringacc_la_SOURCES += \
diff --git a/src/ringdht/accountarchive.cpp b/src/ringdht/accountarchive.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e6a11cc151b9b6942878707cd757cb2ee607f259
--- /dev/null
+++ b/src/ringdht/accountarchive.cpp
@@ -0,0 +1,108 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *  Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "accountarchive.h"
+#include "account_const.h"
+#include "configurationmanager_interface.h"
+#include "configkeys.h"
+#include "base64.h"
+#include "logger.h"
+
+namespace ring {
+
+void
+AccountArchive::deserialize(const std::vector<uint8_t>& dat)
+{
+    RING_DBG("Loading account archive (%lu bytes)", dat.size());
+
+    // Decode string
+    std::string decoded {dat.begin(), dat.end()};
+    Json::Value value;
+    Json::Reader reader;
+    if (!reader.parse(decoded.c_str(),value)) {
+        RING_ERR("Archive JSON parsing error: %s", reader.getFormattedErrorMessages().c_str());
+        throw std::runtime_error("failed to parse JSON");
+    }
+
+    // Import content
+    try {
+        config = DRing::getAccountTemplate(DRing::Account::ProtocolNames::RING);
+        for (Json::ValueIterator itr = value.begin() ; itr != value.end() ; itr++) {
+            try {
+                const auto key = itr.key().asString();
+                if (key.empty())
+                    continue;
+                if (key.compare(DRing::Account::ConfProperties::TLS::CA_LIST_FILE) == 0) {
+                } else if (key.compare(DRing::Account::ConfProperties::TLS::PRIVATE_KEY_FILE) == 0) {
+                } else if (key.compare(DRing::Account::ConfProperties::TLS::CERTIFICATE_FILE) == 0) {
+                } else if (key.compare(Conf::RING_CA_KEY) == 0) {
+                    ca_key = std::make_shared<dht::crypto::PrivateKey>(base64::decode(itr->asString()));
+                } else if (key.compare(Conf::RING_ACCOUNT_KEY) == 0) {
+                    id.first = std::make_shared<dht::crypto::PrivateKey>(base64::decode(itr->asString()));
+                } else if (key.compare(Conf::RING_ACCOUNT_CERT) == 0) {
+                    id.second = std::make_shared<dht::crypto::Certificate>(base64::decode(itr->asString()));
+                } else if (key.compare(Conf::RING_ACCOUNT_CONTACTS) == 0) {
+                    for (Json::ValueIterator citr = itr->begin() ; citr != itr->end() ; citr++) {
+                        dht::InfoHash h {citr.key().asString()};
+                        if (h != dht::InfoHash{})
+                            contacts.emplace(h, Contact{*citr});
+                    }
+                } else if (key.compare(Conf::ETH_KEY) == 0) {
+                    eth_key = base64::decode(itr->asString());
+                } else if (key.compare(Conf::RING_ACCOUNT_CRL) == 0) {
+                    revoked = std::make_shared<dht::crypto::RevocationList>(base64::decode(itr->asString()));
+                } else
+                    config[key] = itr->asString();
+            } catch (const std::exception& ex) {
+                RING_ERR("Can't parse JSON entry with value of type %d: %s", (unsigned)itr->type(), ex.what());
+            }
+        }
+    } catch (const std::exception& ex) {
+        RING_ERR("Can't parse JSON: %s", ex.what());
+    }
+}
+
+std::string
+AccountArchive::serialize() const
+{
+    Json::Value root;
+
+    for (const auto& it : config)
+        root[it.first] = it.second;
+
+    if (ca_key and *ca_key)
+        root[Conf::RING_CA_KEY] = base64::encode(ca_key->serialize());
+    root[Conf::RING_ACCOUNT_KEY] = base64::encode(id.first->serialize());
+    root[Conf::RING_ACCOUNT_CERT] = base64::encode(id.second->getPacked());
+    root[Conf::ETH_KEY] = base64::encode(eth_key);
+
+    if (revoked)
+        root[Conf::RING_ACCOUNT_CRL] = base64::encode(revoked->getPacked());
+
+    if (not contacts.empty()) {
+        Json::Value& jsonContacts = root[Conf::RING_ACCOUNT_CONTACTS];
+        for (const auto& c : contacts)
+            jsonContacts[c.first.toString()] = c.second.toJson();
+    }
+
+    Json::FastWriter fastWriter;
+    return fastWriter.write(root);
+}
+
+
+}
diff --git a/src/ringdht/accountarchive.h b/src/ringdht/accountarchive.h
new file mode 100644
index 0000000000000000000000000000000000000000..35c1706174f611358fcaee89a1130705b1007231
--- /dev/null
+++ b/src/ringdht/accountarchive.h
@@ -0,0 +1,72 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *  Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include "ringcontact.h"
+#include "fileutils.h"
+
+#include <opendht/crypto.h>
+#include <memory>
+#include <vector>
+#include <map>
+#include <string>
+
+namespace ring {
+
+/**
+ * Crypto material contained in the archive,
+ * not persisted in the account configuration
+ */
+struct AccountArchive
+{
+    /** Account main private key and certificate chain */
+    dht::crypto::Identity id;
+
+    /** Generated CA key (for self-signed certificates) */
+    std::shared_ptr<dht::crypto::PrivateKey> ca_key;
+
+    /** Revoked devices */
+    std::shared_ptr<dht::crypto::RevocationList> revoked;
+
+    /** Ethereum private key */
+    std::vector<uint8_t> eth_key;
+
+    /** Contacts */
+    std::map<dht::InfoHash, Contact> contacts;
+
+    /** Account configuration */
+    std::map<std::string, std::string> config;
+
+    AccountArchive() = default;
+    AccountArchive(const std::vector<uint8_t>& data) { deserialize(data); }
+    AccountArchive(const std::string& path, const std::string& password) { load(path, password); }
+
+    /** Serialize structured archive data to memory. */
+    std::string serialize() const;
+
+    /** Deserialize archive from memory. */
+    void deserialize(const std::vector<uint8_t>& data);
+
+    /** Load archive from file, optionally encrypted with provided password. */
+    void load(const std::string& path, const std::string& password = {}) { deserialize(fileutils::readArchive(path, password)); }
+
+    /** Save archive to file, optionally encrypted with provided password. */
+    void save(const std::string& path, const std::string& password = {}) const { fileutils::writeArchive(serialize(), path, password); }
+};
+
+}
diff --git a/src/ringdht/ringaccount.cpp b/src/ringdht/ringaccount.cpp
index 3c146f6d49c761ddbaf13522ad2705e1f77f7607..d59d4930fffe0b01a3d0a7e639103cadaa2e1322 100644
--- a/src/ringdht/ringaccount.cpp
+++ b/src/ringdht/ringaccount.cpp
@@ -27,6 +27,7 @@
 #include "config.h"
 #endif
 
+#include "accountarchive.h"
 #include "ringcontact.h"
 #include "configkeys.h"
 
@@ -174,30 +175,6 @@ struct RingAccount::KnownDevice
         : certificate(cert), name(n), last_sync(sync) {}
 };
 
-/**
- * Crypto material contained in the archive,
- * not persisted in the account configuration
- */
-struct RingAccount::ArchiveContent
-{
-    /** Account main private key and certificate chain */
-    dht::crypto::Identity id;
-
-    /** Generated CA key (for self-signed certificates) */
-    std::shared_ptr<dht::crypto::PrivateKey> ca_key;
-
-    /** Revoked devices */
-    std::shared_ptr<dht::crypto::RevocationList> revoked;
-
-    /** Ethereum private key */
-    std::vector<uint8_t> eth_key;
-
-    /** Contacts */
-    std::map<dht::InfoHash, Contact> contacts;
-
-    /** Account configuration */
-    std::map<std::string, std::string> config;
-};
 
 /**
  * Device announcement stored on DHT.
@@ -753,7 +730,7 @@ RingAccount::createRingDevice(const dht::crypto::Identity& id)
 }
 
 void
-RingAccount::initRingDevice(const ArchiveContent& a)
+RingAccount::initRingDevice(const AccountArchive& a)
 {
     RING_WARN("[Account %s] creating new Ring device from archive", getAccountID().c_str());
     SIPAccountBase::setAccountDetails(a.config);
@@ -902,99 +879,19 @@ RingAccount::loadIdentity(const std::string& crt_path, const std::string& key_pa
     return id;
 }
 
-RingAccount::ArchiveContent
+AccountArchive
 RingAccount::readArchive(const std::string& pwd) const
 {
     RING_DBG("[Account %s] reading account archive", getAccountID().c_str());
-
-    std::vector<uint8_t> data;
-
-    if (pwd.empty()) {
-        data = archiver::decompressGzip(fileutils::getFullPath(idPath_, archivePath_));
-    } else {
-        // Read file
-        try {
-            data = fileutils::loadFile(archivePath_, idPath_);
-        } catch (const std::exception& e) {
-            RING_ERR("[Account %s] archive loading error: %s", getAccountID().c_str(), e.what());
-            throw;
-        }
-        // Decrypt
-        try {
-            data = archiver::decompress(dht::crypto::aesDecrypt(data, pwd));
-        } catch (const std::exception& e) {
-            RING_ERR("[Account %s] archive decrypt error: %s", getAccountID().c_str(), e.what());
-            throw;
-        }
-    }
-
-    // Unserialize data
-    return loadArchive(data);
+    return AccountArchive(fileutils::getFullPath(idPath_, archivePath_), pwd);
 }
 
-RingAccount::ArchiveContent
-RingAccount::loadArchive(const std::vector<uint8_t>& dat)
-{
-    ArchiveContent c;
-    RING_DBG("Loading account archive (%lu bytes)", dat.size());
-
-    // Decode string
-    std::string decoded {dat.begin(), dat.end()};
-    Json::Value value;
-    Json::Reader reader;
-    if (!reader.parse(decoded.c_str(),value)) {
-        RING_ERR("Archive JSON parsing error: %s", reader.getFormattedErrorMessages().c_str());
-        throw std::runtime_error("failed to parse JSON");
-    }
 
-    // Import content
-    try {
-        c.config = DRing::getAccountTemplate(ACCOUNT_TYPE);
-        for (Json::ValueIterator itr = value.begin() ; itr != value.end() ; itr++) {
-            try {
-                const auto key = itr.key().asString();
-                if (key.empty())
-                    continue;
-                if (key.compare(DRing::Account::ConfProperties::TLS::CA_LIST_FILE) == 0) {
-                } else if (key.compare(DRing::Account::ConfProperties::TLS::PRIVATE_KEY_FILE) == 0) {
-                } else if (key.compare(DRing::Account::ConfProperties::TLS::CERTIFICATE_FILE) == 0) {
-                } else if (key.compare(Conf::RING_CA_KEY) == 0) {
-                    c.ca_key = std::make_shared<dht::crypto::PrivateKey>(base64::decode(itr->asString()));
-                } else if (key.compare(Conf::RING_ACCOUNT_KEY) == 0) {
-                    c.id.first = std::make_shared<dht::crypto::PrivateKey>(base64::decode(itr->asString()));
-                } else if (key.compare(Conf::RING_ACCOUNT_CERT) == 0) {
-                    c.id.second = std::make_shared<dht::crypto::Certificate>(base64::decode(itr->asString()));
-                } else if (key.compare(Conf::RING_ACCOUNT_CONTACTS) == 0) {
-                    for (Json::ValueIterator citr = itr->begin() ; citr != itr->end() ; citr++) {
-                        dht::InfoHash h {citr.key().asString()};
-                        if (h != dht::InfoHash{})
-                            c.contacts.emplace(h, Contact{*citr});
-                    }
-                } else if (key.compare(Conf::ETH_KEY) == 0) {
-                    c.eth_key = base64::decode(itr->asString());
-                } else if (key.compare(Conf::RING_ACCOUNT_CRL) == 0) {
-                    c.revoked = std::make_shared<dht::crypto::RevocationList>(base64::decode(itr->asString()));
-                } else
-                    c.config[key] = itr->asString();
-            } catch (const std::exception& ex) {
-                RING_ERR("Can't parse JSON entry with value of type %d: %s", (unsigned)itr->type(), ex.what());
-            }
-        }
-    } catch (const std::exception& ex) {
-        RING_ERR("Can't parse JSON: %s", ex.what());
-    }
-
-    return c;
-}
-
-
-std::string
-RingAccount::makeArchive(const ArchiveContent& archive) const
+void
+RingAccount::updateArchive(AccountArchive& archive) const
 {
     RING_DBG("[Account %s] building account archive", getAccountID().c_str());
 
-    Json::Value root;
-
     auto details = getAccountDetails();
     for (auto it : details) {
         if (it.first.compare(DRing::Account::ConfProperties::Ringtone::PATH) == 0) {
@@ -1005,61 +902,27 @@ RingAccount::makeArchive(const ArchiveContent& archive) const
             // replace paths by the files content
             if (not it.second.empty()) {
                 try {
-                    root[it.first] = base64::encode(fileutils::loadFile(it.second));
+                    archive.config[it.first] = base64::encode(fileutils::loadFile(it.second));
                 } catch (...) {}
             }
         } else
-            root[it.first] = it.second;
+            archive.config[it.first] = it.second;
     }
-
-    if (archive.ca_key and *archive.ca_key)
-        root[Conf::RING_CA_KEY] = base64::encode(archive.ca_key->serialize());
-    root[Conf::RING_ACCOUNT_KEY] = base64::encode(archive.id.first->serialize());
-    root[Conf::RING_ACCOUNT_CERT] = base64::encode(archive.id.second->getPacked());
-    root[Conf::ETH_KEY] = base64::encode(archive.eth_key);
-
-    if (archive.revoked)
-        root[Conf::RING_ACCOUNT_CRL] = base64::encode(archive.revoked->getPacked());
-
-    if (not contacts_.empty()) {
-        Json::Value& contacts = root[Conf::RING_ACCOUNT_CONTACTS];
-        for (const auto& c : contacts_)
-            contacts[c.first.toString()] = c.second.toJson();
-    }
-
-    Json::FastWriter fastWriter;
-    return fastWriter.write(root);
+    archive.contacts = contacts_;
 }
 
 void
-RingAccount::saveArchive(const ArchiveContent& archive_content, const std::string& pwd)
+RingAccount::saveArchive(AccountArchive& archive, const std::string& pwd)
 {
-    std::string archive_str;
     try {
-        archive_str = makeArchive(archive_content);
+        updateArchive(archive);
+        if (archivePath_.empty())
+            archivePath_ = "export.gz";
+        archive.save(fileutils::getFullPath(idPath_, archivePath_), pwd);
     } catch (const std::runtime_error& ex) {
         RING_ERR("[Account %s] Can't export archive: %s", getAccountID().c_str(), ex.what());
         return;
     }
-
-    if (archivePath_.empty())
-        archivePath_ = "export.gz";
-    auto fullPath = fileutils::getFullPath(idPath_, archivePath_);
-
-    if (not pwd.empty()) {
-        // Encrypt using provided password
-        std::vector<uint8_t> data = dht::crypto::aesEncrypt(archiver::compress(archive_str), pwd);
-        // Write
-        try {
-            fileutils::saveFile(fullPath, data);
-        } catch (const std::runtime_error& ex) {
-            RING_ERR("Export failed: %s", ex.what());
-            return;
-        }
-    } else {
-        RING_WARN("[account %s] unsecured archiving (no password)", getAccountID().c_str());
-        archiver::compressGzip(archive_str, fullPath);
-    }
 }
 
 std::pair<std::vector<uint8_t>, dht::InfoHash>
@@ -1095,7 +958,7 @@ RingAccount::addDevice(const std::string& password)
         std::vector<uint8_t> key;
         dht::InfoHash loc;
         std::string pin_str;
-        ArchiveContent a;
+        AccountArchive a;
         try {
             RING_DBG("[Account %s] exporting Ring account", this_->getAccountID().c_str());
 
@@ -1117,8 +980,8 @@ RingAccount::addDevice(const std::string& password)
             return;
         }
         try {
-            auto archive = this_->makeArchive(a);
-            auto encrypted = dht::crypto::aesEncrypt(archiver::compress(archive), key);
+            this_->updateArchive(a);
+            auto encrypted = dht::crypto::aesEncrypt(archiver::compress(a.serialize()), key);
             if (not this_->dht_.isRunning())
                 throw std::runtime_error("DHT is not running..");
             this_->dht_.put(loc, encrypted, [this_,pin_str](bool ok) {
@@ -1141,7 +1004,7 @@ bool
 RingAccount::revokeDevice(const std::string& password, const std::string& device)
 {
     // shared_ptr of future
-    auto fa = ThreadPool::instance().getShared<ArchiveContent>(
+    auto fa = ThreadPool::instance().getShared<AccountArchive>(
         [this, password] { return readArchive(password); });
     auto sthis = shared();
     findCertificate(dht::InfoHash(device),
@@ -1153,7 +1016,7 @@ RingAccount::revokeDevice(const std::string& password, const std::string& device
             return;
         }
         this_.foundAccountDevice(crt);
-        ArchiveContent a;
+        AccountArchive a;
         try {
             a = fa->get();
         } catch (...) {
@@ -1213,7 +1076,7 @@ RingAccount::loadAccountFromDHT(const std::string& archive_password, const std::
     auto state_new = std::make_shared<std::pair<bool, bool>>(false, true);
     auto found = std::make_shared<bool>(false);
 
-    auto archiveFound = [w,found,archive_password](const ArchiveContent& a) {
+    auto archiveFound = [w,found,archive_password](AccountArchive&& a) {
         *found =  true;
         if (auto this_ = w.lock()) {
             this_->initRingDevice(a);
@@ -1257,7 +1120,7 @@ RingAccount::loadAccountFromDHT(const std::string& archive_password, const std::
                     RING_DBG("Found archive on the DHT");
                     runOnMainThread([=]() {
                         try {
-                            archiveFound(loadArchive(decrypted));
+                            archiveFound(AccountArchive(decrypted));
                         } catch (const std::exception& e) {
                             if (auto this_ = w.lock()) {
                                 RING_WARN("[Account %s] error reading archive: %s", this_->getAccountID().c_str(), e.what());
@@ -1294,7 +1157,7 @@ RingAccount::createAccount(const std::string& archive_password, dht::crypto::Ide
     setRegistrationState(RegistrationState::INITIALIZING);
     auto sthis = std::static_pointer_cast<RingAccount>(shared_from_this());
     ThreadPool::instance().run([sthis,archive_password,migrate]() mutable {
-        ArchiveContent a;
+        AccountArchive a;
         auto& this_ = *sthis;
 
         auto future_keypair = ThreadPool::instance().get<dev::KeyPair>(std::bind(&dev::KeyPair::create));
@@ -1363,7 +1226,7 @@ RingAccount::needsMigration(const dht::crypto::Identity& id)
 }
 
 bool
-RingAccount::updateCertificates(ArchiveContent& archive, dht::crypto::Identity& device)
+RingAccount::updateCertificates(AccountArchive& archive, dht::crypto::Identity& device)
 {
     using Certificate = dht::crypto::Certificate;
 
@@ -1406,7 +1269,7 @@ RingAccount::updateCertificates(ArchiveContent& archive, dht::crypto::Identity&
 void
 RingAccount::migrateAccount(const std::string& pwd, dht::crypto::Identity& device)
 {
-    ArchiveContent archive;
+    AccountArchive archive;
     try {
         archive = readArchive(pwd);
     } catch (...) {
diff --git a/src/ringdht/ringaccount.h b/src/ringdht/ringaccount.h
index ced83ee3c336d78f1d7fdeae33ef0d9816ddbf33..326bdbaba76ea8a9324c8cb720c54c8fb49e744b 100644
--- a/src/ringdht/ringaccount.h
+++ b/src/ringdht/ringaccount.h
@@ -69,6 +69,7 @@ namespace ring {
 
 class IceTransport;
 struct Contact;
+struct AccountArchive;
 
 class RingAccount : public SIPAccountBase {
     public:
@@ -317,7 +318,6 @@ class RingAccount : public SIPAccountBase {
         struct PendingMessage;
         struct TrustRequest;
         struct KnownDevice;
-        struct ArchiveContent;
         struct DeviceAnnouncement;
         struct DeviceSync;
         struct BuddyInfo;
@@ -488,15 +488,14 @@ class RingAccount : public SIPAccountBase {
 
         std::string makeReceipt(const dht::crypto::Identity& id);
         void createRingDevice(const dht::crypto::Identity& id);
-        void initRingDevice(const ArchiveContent& a);
+        void initRingDevice(const AccountArchive& a);
         void migrateAccount(const std::string& pwd, dht::crypto::Identity& device);
-        static bool updateCertificates(ArchiveContent& archive, dht::crypto::Identity& device);
+        static bool updateCertificates(AccountArchive& archive, dht::crypto::Identity& device);
 
         void createAccount(const std::string& archive_password, dht::crypto::Identity&& migrate);
-        std::string makeArchive(const ArchiveContent& content) const;
-        void saveArchive(const ArchiveContent& content, const std::string& pwd);
-        ArchiveContent readArchive(const std::string& pwd) const;
-        static ArchiveContent loadArchive(const std::vector<uint8_t>& data);
+        void updateArchive(AccountArchive& content) const;
+        void saveArchive(AccountArchive& content, const std::string& pwd);
+        AccountArchive readArchive(const std::string& pwd) const;
         std::vector<std::pair<sockaddr_storage, socklen_t>> loadBootstrap() const;
 
         static std::pair<std::string, std::string> saveIdentity(const dht::crypto::Identity id, const std::string& path, const std::string& name);