all files / src/ asset.js

98.75% Statements 79/80
95.65% Branches 44/46
100% Functions 15/15
97.78% Lines 44/45
1 statement, 5 branches Ignored     
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154                                      1× 138× 3×   135× 1×   134× 1×     133× 133×               53×                 52× 52×   26×   25× 25× 25× 25×   1× 1× 1× 1×                     72× 25×   47× 47× 44× 44×   3× 3×       47× 47×   47×         47×                 19×               19×                           3× 1×   2× 1× 1× 1×                     75×                 15×      
import {default as xdr} from "./generated/digitalbits-xdr_generated";
import {Keypair} from "./keypair";
import {StrKey} from "./strkey";
import clone from 'lodash/clone';
import padEnd from 'lodash/padEnd';
import trimEnd from 'lodash/trimEnd';
 
/**
 * Asset class represents an asset, either the native asset (`XLM`)
 * or an asset code / issuer account ID pair.
 *
 * An asset code describes an asset code and issuer pair. In the case of the native
 * asset XLM, the issuer will be null.
 *
 * @constructor
 * @param {string} code - The asset code.
 * @param {string} issuer - The account ID of the issuer.
 */
export class Asset {
  constructor(code, issuer) {
    if (!/^[a-zA-Z0-9]{1,12}$/.test(code)) {
      throw new Error("Asset code is invalid (maximum alphanumeric, 12 characters at max)");
    }
    if (String(code).toLowerCase() !== "xlm" && !issuer) {
      throw new Error("Issuer cannot be null");
    }
    if (issuer && !StrKey.isValidEd25519PublicKey(issuer)) {
      throw new Error("Issuer is invalid");
    }
 
    this.code = code;
    this.issuer = issuer;
  }
 
  /**
   * Returns an asset object for the native asset.
   * @Return {Asset}
   */
  static native() {
    return new Asset("XLM");
  }
 
  /**
   * Returns an asset object from its XDR object representation.
   * @param {xdr.Asset} assetXdr - The asset xdr object.
   * @returns {Asset}
   */
  static fromOperation(assetXdr) {
    let anum, code, issuer;
    switch(assetXdr.switch()) {
      case xdr.AssetType.assetTypeNative():
      return this.native();
      case xdr.AssetType.assetTypeCreditAlphanum4():
      anum = assetXdr.alphaNum4();
      issuer = StrKey.encodeEd25519PublicKey(anum.issuer().ed25519());
      code = trimEnd(anum.assetCode(), '\0');
      return new this(code, issuer);
      case xdr.AssetType.assetTypeCreditAlphanum12():
      anum = assetXdr.alphaNum12();
      issuer = StrKey.encodeEd25519PublicKey(anum.issuer().ed25519());
      code = trimEnd(anum.assetCode(), '\0');
      return new this(code, issuer);
      default:
      throw new Error(`Invalid asset type: ${assetXdr.switch().name}`);
    }
  }
 
  /**
   * Returns the xdr object for this asset.
   * @returns {xdr.Asset}
   */
  toXDRObject() {
    if (this.isNative()) {
      return xdr.Asset.assetTypeNative();
    } else {
      let xdrType, xdrTypeString;
      if (this.code.length <= 4) {
        xdrType = xdr.AssetAlphaNum4;
        xdrTypeString = 'assetTypeCreditAlphanum4';
      } else {
        xdrType = xdr.AssetAlphaNum12;
        xdrTypeString = 'assetTypeCreditAlphanum12';
      }
 
          // pad code with null bytes if necessary
          let padLength = this.code.length <= 4 ? 4 : 12;
          let paddedCode = padEnd(this.code, padLength, '\0');
 
          var assetType = new xdrType({
            assetCode: paddedCode,
            issuer: Keypair.fromPublicKey(this.issuer).xdrAccountId()
          });
 
          return new xdr.Asset(xdrTypeString, assetType);
        }
      }
 
  /**
   * Return the asset code
   * @returns {string}
   */
  getCode() {
    return clone(this.code);
  }
 
  /**
   * Return the asset issuer
   * @returns {string}
   */
  getIssuer() {
    return clone(this.issuer);
  }
 
  /**
   * Return the asset type. Can be one of following types:
   *
   * * `native`
   * * `credit_alphanum4`
   * * `credit_alphanum12`
   *
   * @see [Assets concept](https://developer.digitalbits.io/learn/concepts/assets.html)
   * @returns {string}
   */
  getAssetType() {
    if (this.isNative()) {
      return 'native';
    } else {
      if (this.code.length >= 1 && this.code.length <= 4) {
        return "credit_alphanum4";
      } else Eif (this.code.length >= 5 && this.code.length <= 12) {
        return "credit_alphanum12";
      }
    }
  }
 
 
  /**
   * Returns true if this asset object is the native asset.
   * @returns {boolean}
   */
  isNative() {
    return !this.issuer;
  }
 
  /**
   * Returns true if this asset equals the given asset.
   * @param {Asset} asset Asset to compare
   * @returns {boolean}
   */
  equals(asset) {
    return this.code == asset.getCode() && this.issuer == asset.getIssuer();
  }
}