diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp
--- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp
+++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp
@@ -3,6 +3,7 @@
 #include "BaseDataStore.h"
 #include "DatabaseManager.h"
 #include "InternalModules/GlobalDBSingleton.h"
+#include "InternalModules/RustPromiseManager.h"
 #include "NativeModuleUtils.h"
 #include "TerminateApp.h"
 
@@ -1063,9 +1064,44 @@
   std::string userDataStr = userData.utf8(rt);
   return createPromiseAsJSIValue(
       rt, [=](jsi::Runtime &innerRt, std::shared_ptr<Promise> promise) {
-        this->jsInvoker_->invokeAsync([=, &innerRt]() {
-          promise->resolve(
-              jsi::String::createFromUtf8(innerRt, std::string("")));
+        this->cryptoThread->scheduleTask([=, &innerRt]() {
+          std::string error;
+
+          std::string backupID;
+          try {
+            backupID = crypto::Tools::generateRandomString(32);
+          } catch (const std::exception &e) {
+            error = "Failed to generate backupID";
+          }
+
+          std::string pickleKey;
+          std::string pickledAccount;
+          if (!error.size()) {
+            try {
+              pickleKey = crypto::Tools::generateRandomString(64);
+              crypto::Persist persist =
+                  this->cryptoModule->storeAsB64(pickleKey);
+              pickledAccount =
+                  std::string(persist.account.begin(), persist.account.end());
+            } catch (const std::exception &e) {
+              error = "Failed to pickle crypto account";
+            }
+          }
+
+          if (!error.size()) {
+            auto currentID = RustPromiseManager::instance.addPromise(
+                promise, this->jsInvoker_, innerRt);
+            ::createBackup(
+                rust::string(backupID),
+                rust::string(backupSecretStr),
+                rust::string(pickleKey),
+                rust::string(pickledAccount),
+                rust::string(userDataStr),
+                currentID);
+          } else {
+            this->jsInvoker_->invokeAsync(
+                [=, &innerRt]() { promise->reject(error); });
+          }
         });
       });
 }
@@ -1082,10 +1118,14 @@
   std::string encryptedUserDataStr = encryptedUserData.utf8(rt);
   return createPromiseAsJSIValue(
       rt, [=](jsi::Runtime &innerRt, std::shared_ptr<Promise> promise) {
-        this->jsInvoker_->invokeAsync([=, &innerRt]() {
-          promise->resolve(
-              jsi::String::createFromUtf8(innerRt, std::string("")));
-        });
+        auto currentID = RustPromiseManager::instance.addPromise(
+            promise, this->jsInvoker_, innerRt);
+        ::restoreBackup(
+            rust::string(backupIDStr),
+            rust::string(backupSecretStr),
+            rust::string(encryptedUserKeysStr),
+            rust::string(encryptedUserDataStr),
+            currentID);
       });
 }
 
diff --git a/native/native_rust_library/Cargo.lock b/native/native_rust_library/Cargo.lock
--- a/native/native_rust_library/Cargo.lock
+++ b/native/native_rust_library/Cargo.lock
@@ -773,6 +773,7 @@
 version = "0.1.0"
 dependencies = [
  "argon2 0.5.1",
+ "base64",
  "comm-opaque2",
  "cxx",
  "cxx-build",
diff --git a/native/native_rust_library/Cargo.toml b/native/native_rust_library/Cargo.toml
--- a/native/native_rust_library/Cargo.toml
+++ b/native/native_rust_library/Cargo.toml
@@ -18,6 +18,7 @@
 serde_json = "1.0"
 argon2 = { version = "0.5.1", features = ["std"] }
 grpc_clients = { path = "../../shared/grpc_clients" }
+base64 = "0.21"
 
 [build-dependencies]
 cxx-build = "1.0"
diff --git a/native/native_rust_library/src/backup.rs b/native/native_rust_library/src/backup.rs
new file mode 100644
--- /dev/null
+++ b/native/native_rust_library/src/backup.rs
@@ -0,0 +1,154 @@
+use crate::argon2_tools::compute_backup_key;
+use crate::constants::aes;
+use crate::handle_string_result_as_callback;
+use crate::RUNTIME;
+use base64::{prelude::BASE64_STANDARD, Engine};
+use serde::{Deserialize, Serialize};
+use serde_json::json;
+use std::error::Error;
+pub mod ffi {
+  use super::*;
+
+  pub fn create_backup_sync(
+    backup_id: String,
+    backup_secret: String,
+    pickle_key: String,
+    pickled_account: String,
+    user_data: String,
+    promise_id: u32,
+  ) {
+    RUNTIME.spawn(async move {
+      let result = create_backup(
+        backup_id,
+        backup_secret,
+        pickle_key,
+        pickled_account,
+        user_data,
+      );
+      handle_string_result_as_callback(result, promise_id);
+    });
+  }
+
+  pub fn restore_backup_sync(
+    backup_id: String,
+    backup_secret: String,
+    encrypted_user_keys: String,
+    encrypted_user_data: String,
+    promise_id: u32,
+  ) {
+    RUNTIME.spawn(async move {
+      let result = restore_backup(
+        backup_id,
+        backup_secret,
+        encrypted_user_keys,
+        encrypted_user_data,
+      );
+      handle_string_result_as_callback(result, promise_id);
+    });
+  }
+}
+
+pub fn create_backup(
+  backup_id: String,
+  backup_secret: String,
+  pickle_key: String,
+  pickled_account: String,
+  user_data: String,
+) -> Result<String, Box<dyn Error>> {
+  let mut backup_key =
+    compute_backup_key(backup_secret.as_bytes(), backup_id.as_bytes())?;
+
+  let mut user_data = user_data.into_bytes();
+
+  let mut backup_data_key = [0; aes::KEY_SIZE];
+  crate::ffi::generate_key(&mut backup_data_key)?;
+  let encrypted_user_data = encrypt(&mut backup_data_key, &mut user_data)?;
+
+  let user_keys = UserKeys {
+    backup_data_key,
+    pickle_key,
+    pickled_account,
+  };
+  let encrypted_user_keys = user_keys.encrypt(&mut backup_key)?;
+
+  Ok(
+    json!({
+      "backupID": backup_id,
+      "userKeys": BASE64_STANDARD.encode(encrypted_user_keys),
+      "userData": BASE64_STANDARD.encode(encrypted_user_data),
+    })
+    .to_string(),
+  )
+}
+
+pub fn restore_backup(
+  backup_id: String,
+  backup_secret: String,
+  encrypted_user_keys: String,
+  encrypted_user_data: String,
+) -> Result<String, Box<dyn Error>> {
+  let mut encrypted_user_keys: Vec<u8> =
+    BASE64_STANDARD.decode(&encrypted_user_keys)?;
+  let mut encrypted_user_data: Vec<u8> =
+    BASE64_STANDARD.decode(&encrypted_user_data)?;
+
+  let mut backup_id = backup_id.into_bytes();
+
+  let mut backup_key =
+    compute_backup_key(backup_secret.as_bytes(), &mut backup_id)?;
+
+  let mut user_keys =
+    UserKeys::from_encrypted(&mut encrypted_user_keys, &mut backup_key)?;
+
+  let user_data =
+    decrypt(&mut user_keys.backup_data_key, &mut encrypted_user_data)?;
+
+  Ok(
+    json!({
+        "userData": String::from_utf8(user_data)?,
+        "pickleKey": user_keys.pickle_key,
+        "pickledAccount": user_keys.pickled_account,
+    })
+    .to_string(),
+  )
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+struct UserKeys {
+  backup_data_key: [u8; 32],
+  pickle_key: String,
+  pickled_account: String,
+}
+
+impl UserKeys {
+  fn encrypt(&self, backup_key: &mut [u8]) -> Result<Vec<u8>, Box<dyn Error>> {
+    let mut json = serde_json::to_vec(self)?;
+    encrypt(backup_key, &mut json)
+  }
+
+  fn from_encrypted(
+    data: &mut [u8],
+    backup_key: &mut [u8],
+  ) -> Result<Self, Box<dyn Error>> {
+    let decrypted = decrypt(backup_key, data)?;
+    Ok(serde_json::from_slice(&decrypted)?)
+  }
+}
+
+fn encrypt(key: &mut [u8], data: &mut [u8]) -> Result<Vec<u8>, Box<dyn Error>> {
+  let encrypted_len = data.len() + aes::IV_LENGTH + aes::TAG_LENGTH;
+  let mut encrypted = vec![0; encrypted_len];
+
+  crate::ffi::encrypt(key, data, &mut encrypted)?;
+
+  Ok(encrypted)
+}
+
+fn decrypt(key: &mut [u8], data: &mut [u8]) -> Result<Vec<u8>, Box<dyn Error>> {
+  let decrypted_len = data.len() - aes::IV_LENGTH - aes::TAG_LENGTH;
+  let mut decrypted = vec![0; decrypted_len];
+
+  crate::ffi::decrypt(key, data, &mut decrypted)?;
+
+  Ok(decrypted)
+}
diff --git a/native/native_rust_library/src/lib.rs b/native/native_rust_library/src/lib.rs
--- a/native/native_rust_library/src/lib.rs
+++ b/native/native_rust_library/src/lib.rs
@@ -18,6 +18,7 @@
 use tracing::instrument;
 
 mod argon2_tools;
+mod backup;
 mod constants;
 
 use argon2_tools::compute_backup_key_str;
@@ -45,6 +46,7 @@
   );
 }
 
+use backup::ffi::*;
 #[cxx::bridge]
 mod ffi {
 
@@ -178,6 +180,28 @@
       plaintext: &mut [u8],
     ) -> Result<()>;
   }
+
+  // Backup
+  extern "Rust" {
+    #[cxx_name = "createBackup"]
+    fn create_backup_sync(
+      backup_id: String,
+      backup_secret: String,
+      pickle_key: String,
+      pickled_account: String,
+      user_data: String,
+      promise_id: u32,
+    );
+
+    #[cxx_name = "restoreBackup"]
+    fn restore_backup_sync(
+      backup_id: String,
+      backup_secret: String,
+      encrypted_user_keys: String,
+      encrypted_user_data: String,
+      promise_id: u32,
+    );
+  }
 }
 
 fn handle_string_result_as_callback<E>(