DeFiCh/wallet

View on GitHub
mobile-app/app/api/secured/index.ts

Summary

Maintainability
A
0 mins
Test Coverage
import { EnvironmentNetwork, getEnvironment } from "@waveshq/walletkit-core";
import { getReleaseChannel } from "@api/releaseChannel";
import { StorageProvider } from "./provider";

/**
 * @return EnvironmentNetwork if invalid, will be set to `networks[0]`
 */
async function getNetwork(): Promise<EnvironmentNetwork> {
  const env = getEnvironment(getReleaseChannel());
  const network = await StorageProvider.getItem(`${env.name}.NETWORK`);

  if ((env.networks as any[]).includes(network)) {
    return network as EnvironmentNetwork;
  }

  await setNetwork(env.networks[0]);
  return env.networks[0];
}

/**
 * @param network {EnvironmentNetwork} with set with 'environment' prefixed
 */
async function setNetwork(network: EnvironmentNetwork): Promise<void> {
  const env = getEnvironment(getReleaseChannel());

  if (!env.networks.includes(network)) {
    throw new Error("network is not part of environment");
  }

  await StorageProvider.setItem(`${env.name}.NETWORK`, network);
}

async function getKey(key: string): Promise<string> {
  const env = getEnvironment(getReleaseChannel());
  const network = await getNetwork();
  return `${env.name}.${network}.${key}`;
}

/**
 * @param key {string} of item with 'environment' and 'network' prefixed
 * @return {string | null}
 */
async function getItem(key: string): Promise<string | null> {
  return await StorageProvider.getItem(await getKey(key));
}

/**
 * @param key {string} of item with 'environment' and 'network' prefixed
 * @param value {string} to set
 * @throws Error when byte length exceed 2048 bytes
 */
async function setItem(key: string, value: string): Promise<void> {
  if (Buffer.byteLength(value, "utf-8") >= 2048) {
    throw new Error("value exceed 2048 bytes, unable to setItem");
  }
  return await StorageProvider.setItem(await getKey(key), value);
}

/**
 * @param key {string} of item with 'environment' and 'network' prefixed
 */
async function removeItem(key: string): Promise<void> {
  await StorageProvider.removeItem(await getKey(key));
}

/**
 * Secured Store provides a way to encrypt and securely store key–value pairs locally on the native device.
 * On web for non production workload, it uses AsyncStorage.
 *
 * SecuredStoreAPI is also used to keep track of current set network. All key/value stored in SecuredStore
 * is network prefix. By design isolated each key/value to their network specific store allowing separation
 * of sensitive value between networks. Thus SecuredStoreAPI should only be used for sensitive values e.g. wallet.
 */
export const SecuredStoreAPI = {
  getNetwork,
  setNetwork,
  getItem,
  setItem,
  removeItem,
};