tokensStore.js 2.27 KiB
Newer Older
Amaury Martiny's avatar
Amaury Martiny committed
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
//
Amaury Martiny's avatar
Amaury Martiny committed
// SPDX-License-Identifier: BSD-3-Clause
Amaury Martiny's avatar
Amaury Martiny committed

Amaury Martiny's avatar
Amaury Martiny committed
import { action, computed, observable } from 'mobx';
import { chainName$, defaultAccount$ } from '@parity/light.js';
import { combineLatest } from 'rxjs';
Amaury Martiny's avatar
Amaury Martiny committed
import store from 'store';

import ethereumIcon from '../assets/img/tokens/ethereum.png';
Amaury Martiny's avatar
Amaury Martiny committed
import LS_PREFIX from './utils/lsPrefix';
Amaury Martiny's avatar
Amaury Martiny committed

Amaury Martiny's avatar
Amaury Martiny committed
const LS_KEY = `${LS_PREFIX}::tokens`;
Amaury Martiny's avatar
Amaury Martiny committed

Amaury Martiny's avatar
Amaury Martiny committed
export class TokensStore {
  @observable tokens = {};
Amaury Martiny's avatar
Amaury Martiny committed

Amaury Martiny's avatar
Amaury Martiny committed
  constructor () {
Amaury Martiny's avatar
Amaury Martiny committed
    combineLatest(chainName$(), defaultAccount$()).subscribe(
      ([chainName, defaultAccount]) =>
        // Refetch token from localStorage everytime we have a new chainName
        // (shouldn't happen) or the user selects a new account
        this.fetchTokensFromDb(chainName, defaultAccount)
Amaury Martiny's avatar
Amaury Martiny committed
  }

  @action
Amaury Martiny's avatar
Amaury Martiny committed
  addToken = (address, token) => {
    this.tokens[address] = token;
Amaury Martiny's avatar
Amaury Martiny committed
    this.updateLS();
  };

  @action
  fetchTokensFromDb = async (chainName, defaultAccount) => {
    if (!defaultAccount || !chainName) {
      this.tokens = {};
      return;
    }

    // Set the localStorage key, we have one key per chain per account, in this
    // format: __paritylight::tokens::0x123::kovan
Amaury Martiny's avatar
Amaury Martiny committed
    this.lsKey = `${LS_KEY}::${defaultAccount}::${chainName}`;

    // Now we fetch the tokens from the localStorage
    const tokens = store.get(this.lsKey);
    if (!tokens) {
      // If there's nothing in the localStorage, we add be default only
      // Ethereum. We consider Ethereum as a token, with address 'ETH'

      this.tokens = {
Amaury Martiny's avatar
Amaury Martiny committed
        ETH: {
          address: 'ETH',
          decimals: 18,
Amaury Martiny's avatar
Amaury Martiny committed
          logo: ethereumIcon,
          name: 'Ethereum',
          symbol: 'ETH'
        }
    } else {
      this.tokens = tokens;
Amaury Martiny's avatar
Amaury Martiny committed
  @action
Amaury Martiny's avatar
Amaury Martiny committed
  removeToken = address => {
    delete this.tokens[address];
Amaury Martiny's avatar
Amaury Martiny committed
    this.updateLS();
  };

Amaury Martiny's avatar
Amaury Martiny committed
  @computed
  get tokensArray () {
    return Object.values(this.tokens);
Amaury Martiny's avatar
Amaury Martiny committed
  }

  @computed
  get tokensArrayWithoutEth () {
    return this.tokensArray.filter(
Amaury Martiny's avatar
Amaury Martiny committed
      ({ address }) => address !== 'ETH' // Ethereum is the only token without address, has 'ETH' instead
    );
  }

  updateLS = () => {
    if (!this.lsKey) {
      return;
    }
    store.set(this.lsKey, this.tokens);
  };
Amaury Martiny's avatar
Amaury Martiny committed
}

export default new TokensStore();