---
arc: 35
title: Algorand Offline Wallet Backup Protocol
description: Wallet-agnostic backup protocol for multiple accounts
author: Yigit Guler (@yigitguler)
discussions-to: https://github.com/algorandfoundation/ARCs/issues/156
status: Final
type: Standards Track
category: Interface
sub-category: Wallet
created: 2023-01-03
---
# Algorand Secure Offline Wallet Backup Protocol


## Abstract
This document outlines the high-level requirements for a wallet-agnostic backup protocol that can be used across all wallets on the Algorand ecosystem.

## Specification
The key words "**MUST**", "**MUST NOT**", "**REQUIRED**", "**SHALL**", "**SHALL NOT**", "**SHOULD**", "**SHOULD NOT**", "**RECOMMENDED**", "**MAY**", and "**OPTIONAL**" in this document are to be interpreted as described in <a href="https://www.ietf.org/rfc/rfc2119.txt">RFC-2119</a>.

### Requirements
At a high-level, offline wallet backup protocol has the following requirements:

 * Wallet applications should allow backing up and storing multiple accounts at the same time.
Account information should be encrypted with a user-defined secret key, utilizing NaCl SecretBox method (audited and endorsed by Algorand).

 * Encrypted final string should be easily copyable to be stored digitally.
When importing, wallet applications should be able to detect already imported accounts and gracefully ignore them.

### Format

Before encryption, account information should be converted to the following JSON format:

```
{
  "device_id": "UNIQUE IDENTIFIER FOR DEVICE (OPTIONAL)",
  "provider_name": "PROVIDER NAME (OPTIONAL, i.e. Pera Wallet)",
  "accounts": [
    {
      "address": "ACCOUNT PUBLIC ADDRESS (REQUIRED)",
      "name": "USER DEFINED ACCOUNT NAME (OPTIONAL)",
      "account_type": "TYPE OF ACCOUNT: single, multisig, watch, contact, ledger (REQUIRED)",
    "private_key": "PRIVATE KEY AS BASE64 ENCODING OF 64 BYTE ALGORAND PRIVATE KEY as encoded by algosdk (NOT PASSPHRASE, REQUIRED for user-owned accounts, can be omitted in case of watch, contact, multisig, ledger accounts)",
      "metadata": "ANY ADDITIONAL CONTENT (OPTIONAL)",
      "multisig": "Multisig information (only required if the account_type is multisig)",
      "ledger": {
        "device_id": "device id",
        "index": <index of the account on device, integer>,
        "connection_type": "bluetooth|usb"
      },
    },
    ...
  ]
}
```

*Clients must accept additional fields in the JSON document.*

Here is an example with a single account:

```
{
  "device_id": "2498232091970170817",
  "provider_name": "Pera Wallet",
  "accounts": [
    {
      "address": "ELWRE6HZ7KIUT46EQ6PBISGD3ND6QSCBVWICYR2QR2Y7LOBRZRCAIKLWDE",
      "name": "My NFT Account",
      "account_type": "single",
      "private_key": "w0HG2VH7tAYz9PD4SYX0flC4CKh1OONCB6U5bP7cXGci7RJ4+fqRSfPEh54USMPbR+hIQa2QLEdQjrH1uDHMRA=="
    }
  ],
}
```

Here is an example with a single multi-sig account:

```
{
  "device_id": "2498232091970170817",
  "provider_name": "Pera Wallet",
  "accounts": [
    {
      "address": "ELWRE6HZ7KIUT46EQ6PBISGD3ND6QSCBVWICYR2QR2Y7LOBRZRCAIKLWDE",
      "name": "Our Multisig Account",
      "account_type": "multisig",
      "multisig": {
        version: 1,
        threshold: 2,
        addrs: [
            account1.addr,
            account2.addr,
            account3.addr,
            ],
     },
    }
  ],
}
```

### Encryption

Once the input JSON is ready, as specified above, it needs to be encrypted. Even if it is assumed that the user is going to store this information in a secure location, copy-pasting it without encryption is not secure since multiple applications can access the clipboard.

The information needs to be encrypted using a very long passphrase. 12 words mnemonic will be used as the key. 12-word mnemonic is secure and it will not create confusion with the 25-word mnemonics that are used to encrypt accounts.

The wallet applications should not allow users to copy the 12-word mnemonic nor allow taking screenshots. The users should note it visually.

The encryption should be made as follows:

1. The wallet generates a random 16-byte string S (using a cryptographically secure random number generator)
2. The wallet derives a 32-byte key: `key = HMAC-SHA256(key="Algorand export 1.0", input=S)`
    On libsodium, use https://libsodium.gitbook.io/doc/advanced/hmac-sha2#hmac-sha-256,
    `crypto_auth_hmacsha256_init` / `crypto_auth_hmacsha256_update` / `crypto_auth_hmacsha256_final`
3. The wallet encrypts the input JSON using `crypto_secretbox_easy` from libsodium (https://libsodium.gitbook.io/doc/secret-key_cryptography/secretbox)
4. The wallet outputs the following output JSON:

```
{
  "version": "1.0",
  "suite": "HMAC-SHA256:sodium_secretbox_easy",
  "ciphertext": <base64 of the ciphertext>
}
```

This JSON document (will be referred as ciphertext envelope JSON) needs to be encoded with base64 again in order to make it easier to copy-paste & store.

5. S is encoded as a 12-word mnemonic (according to BIP-39) and displayed to the user.

The user will be responsible for keeping the 12-word mnemonic and the base64 output of the ciphertext envelope JSON in safe locations. Note that step 5 is the default approach, however, the wallets can support other methods other than mnemonics as well, as long as they are secure.


### Importing
When importing, wallet applications should ask the user for the base64 output of the envelope JSON and the 12-word mnemonic. After getting these values, it should attempt to decrypt the encrypted string using the 12-word mnemonic. On successful decryption, accounts that can be imported can be processed.

## Rationale
There are many benefits to having an openly documented format:

 * Better interoperability across wallets, allowing users to use multiple wallets easily by importing all of their accounts using a single format.

 * Easy and secure backup of all wallet data at a user-defined location, including secure storage in digital environments.

 * Ability to transfer data from device to device securely, such as when moving data from one mobile device to another.


## Security Considerations
Tbd

## Copyright
Copyright and related rights waived via <a href="https://creativecommons.org/publicdomain/zero/1.0/">CCO</a>.
