Skip to content

Infrastructure

Milen Radkov edited this page Aug 3, 2019 · 36 revisions

Used APIs and infrastructure

Aeternity SDK

Waellet is using the aeternity javascript SDK for blockchain operations related to transaction building, broadcasting, and smart contract calls.

Aeternity Middleware

Wallet is using Aeternity Middleware for fetching account transactions and account registered names

Malicious websites tracker

The EtherscamDB API is used to detect phishing and scammy websites. When visiting webpage request to API is made with the host of the visited page. If the API returns a response that this host is marked as scammy, the extension redirect to a page which explains the possible security risks of visiting this page and allowing the user to continue at own risk.

Market price

The CoinGecko API is used for getting the current market price of a certain token. It provides data such as live pricing, trading volume, tickers, exchanges, historical data, coin info & images, developer & community stats, events, global markets, and more.

Generating waellet flow

After installing the extension for the first time or after extension data deletion, there is an option to generate a new wallet.

The workflow of generating wallet is as follows:

  1. Enter a password with which you can access your wallet after logout, encrypt and decrypt your private key.
  2. After entering a password, 12-word mnemonic phrase is generated using bip39 library
  3. The mnemonic phrase is showed and the user has to write down the phrase.
  4. The user is asked to confirm the phrase by entering it in the same order as received.
  5. After entering the correct order of the phrase, seed (private key) is generated from the mnemonic.
  6. The private key is encrypted with the entered password from step 1.
  7. The encrypted private key is stored in the storage of the extension.
  8. A flag in the storage is raised, indicating that the user is logged in.
  +----------+
  | password |
  | prompt   |
  +----+-----+
       |
       |
       v               +---------------------+
  +----+-----+         |  storage            |
  | generate |         |                     |
  | mnemonic |         |    +-----------+    |
  +----+-----+      +-------+ encrypted |    |
       |            |  |    | keypair   |    |
+----->+            |  |    +-----+-----+    |
|      v            |  |          |          |
| +----+-----+      |  |          |          |
| | confirm  |      |  |          v          |
| | mnemonic +--Y---+  |    +-----+-----+    |
| +----+-----+         |    | logged in |    |
|      |            +-------+ flag      |    |
|      N            |  |    +-----------+    |
|      |            |  +---------------------+
+------+            v  
               +----+----+
               | account |
               | page    |
               +---------+

Library used for deriving public keys from the created private key: Aeternity HD wallet library

Authentication flow

If there is an encrypted private key present in the browser storage:

  1. User is already logged in:
  • A flag is raised in the browser storage, indicating that the user is logged in.
  • When opening the extension the user is redirected directly to account page.
  1. User is not logged in, or the flag equals false or is there is no flag in the storage.
  • The user is prompted to enter the password used to encrypt the private key.

On user password entry, an attempt to decrypt the encrypted keystore object (containing the public/private keypair) stored in the browser is made.

  • If it's decrypted successfully, it means that the user entered the correct password, and extension redirects the user to account page.
  • If the keystore is not decrypted successfully with the entered password, authentication is not possible and the user cannot unlock this wallet.
        +---------------------+
        |  storage            |
        |                     |
        |    +-----------+    |
        |    | encrypted |    |
        |    | keypair   |    |
        |    +-----------+    |
        |          |          |
        |          |          |
        |          v          |
        |    +-----+-----+    |
        |    | logged in |    |
     +-----Y-+ flag      +-N-----+
     |  |    +-----------+    |  |
     |  +---------------------+  + <------+
     |                           |        |
     v                           |        |
+---------+   correct      +-----v----+   |
| account |   password     | password |   |
| page    | <------------Y-+ prompt   +-N-+
+---------+                +----------+

Import flow

Import from private key

User can restore his wallet by importing private key. After entering the private key, password is required. This password will be used to encrypt the private key and allow the user to unlock the wallet. After ecnrypting, the encrypted private key is stored in the storage and the user is redirected to account page.

Import from keystore.json

Keystore.json file is file containing encrypted private key. If user have export of the private key it can be imported from this module. After uploading keystore.json file, user must enter password with which the keystore is ecrypted. After entering the file keystore is decrypted with the password.

  • If it's decrypted successfully, it means that the user entered the correct password, and extension redirects the user to account page.
  • If the keystore is not decrypted successfully with the entered password, authentication is not possible and the user cannot unlock this keystore.json file.

Import from seed phrase

If user want to restore account from seed phrase it can be done from this section.

  1. User enter seed phrase
  2. Prompt for entering password
  3. From the entered seed phrase, private key is generated
  4. Private key is encrypted with the entered password
  5. Encrypted private key is stored in the storage
  6. Redirect to account page

For encrypt and decrypt the private key argon browser library and Aeternity SDK keystore are used

Real Time Updating Data

All data in Waellet is fetch constantly via setInterval.

This is the data fetch:

  • If active token is not AE, token balance of the active account is fetched
  • AE token balance of the active account
  • If menu dropdown is opened - balance of tokens of the active account
  • If account dropdown is opened - balances of all subaccounts
  • All mined claim transactions which need to send update name transaction
pollData() {
  let triggerOnce = false
  let running = false
  this.polling = setInterval(async () => {
    if(this.sdk != null && this.isLoggedIn) {
        if(this.current.token != 0) {
          this.$store.dispatch('updateBalanceToken')
        }
        this.$store.dispatch('updateBalance');
        if(this.dropdown.account) {
          this.$store.dispatch('updateBalanceSubaccounts');
        }
        if(this.dropdown.settings) {
          this.$store.dispatch('updateBalanceTokens');
        }
        if(!this.$router.currentRoute.path.includes("/sign-transaction")) {
          if(!running) {
            running = true
            this.$store.dispatch('updateRegisteredName').then(res => {
              running = false
            })
          }
        }
        if(!triggerOnce) {
          this.$store.dispatch('getRegisteredNames')
          this.$store.dispatch('updateBalanceSubaccounts');
          triggerOnce = true
        }
    }
  }, 2500);
}