UNPKG

hive-keychain-commons

Version:

Platform-agnostic functions used in Hive Keychain mobile and extensions

185 lines (184 loc) 6.32 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Price = exports.Asset = void 0; class Asset { constructor(amount, symbol) { /** * Return asset precision. */ this.getPrecision = () => { switch (this.symbol) { case 'TESTS': case 'TBD': case 'HIVE': case 'HBD': case 'SBD': case 'STEEM': return 3; case 'VESTS': return 6; } }; /** * Return a string representation of this asset, e.g. `42.000 HIVE`. */ this.toString = () => { return this.amount.toFixed(this.getPrecision()) + ' ' + this.symbol; }; /** * Return a new Asset instance with amount added. */ this.add = (amount) => { const other = Asset.from(amount, this.symbol); if (this.symbol !== other.symbol) throw new Error(`can not add with different symbols`); return new Asset(this.amount + other.amount, this.symbol); }; /** * Return a new Asset instance with amount subtracted. */ this.subtract = (amount) => { const other = Asset.from(amount, this.symbol); if (this.symbol !== other.symbol) throw new Error(`can not subtract with different symbols`); return new Asset(this.amount - other.amount, this.symbol); }; /** * Return a new Asset with the amount multiplied by factor. */ this.multiply = (factor) => { const other = Asset.from(factor, this.symbol); if (this.symbol !== other.symbol) { throw new Error(`can not multiply with different symbols`); } return new Asset(this.amount * other.amount, this.symbol); }; /** * Return a new Asset with the amount divided. */ this.divide = (divisor) => { const other = Asset.from(divisor, this.symbol); if (this.symbol !== other.symbol) { throw new Error(`can not divide with different symbols`); } return new Asset(this.amount / other.amount, this.symbol); }; /** * For JSON serialization, same as toString(). */ this.toJSON = () => { return this.toString(); }; this.amount = amount; this.symbol = symbol; } } exports.Asset = Asset; /** * Create a new Asset instance from a string, e.g. `42.000 HIVE`. */ Asset.fromString = (str, expectedSymbol) => { const _a = str.split(' '); const amountString = _a[0]; const symbol = _a[1]; if (!['HIVE', 'VESTS', 'HBD', 'TESTS', 'TBD', 'SBD', 'STEEM'].includes(symbol)) { throw new Error(`Invalid asset symbol: ${symbol}`); } if (expectedSymbol && symbol !== expectedSymbol) { throw new Error(`Invalid asset, expected symbol: ${expectedSymbol} got: ${symbol}`); } const amount = Number.parseFloat(amountString); if (!Number.isFinite(amount)) { throw new Error(`Invalid asset amount: ${amountString}`); } return new Asset(amount, symbol); }; /** * Convenience to create new Asset. * @param symbol Symbol to use when created from number. Will also be used to validate * the asset, throws if the passed value has a different symbol than this. */ Asset.from = (value, symbol) => { if (value instanceof Asset) { if (symbol && value.symbol !== symbol) { throw new Error(`Invalid asset, expected symbol: ${symbol} got: ${value.symbol}`); } return value; } else if (typeof value === 'number' && Number.isFinite(value)) { return new Asset(value, symbol || 'STEEM'); } else if (typeof value === 'string') { return Asset.fromString(value, symbol); } else { throw new Error(`Invalid asset '${String(value)}'`); } }; /** * Return the smaller of the two assets. */ Asset.min = (a, b) => { if (a.symbol !== b.symbol) throw new Error(`can not compare assets with different symbols`); return a.amount < b.amount ? a : b; }; /** * Return the larger of the two assets. */ Asset.max = (a, b) => { if (a.symbol !== b.symbol) throw new Error(`can not compare assets with different symbols`); return a.amount > b.amount ? a : b; }; class Price { constructor(base, quote) { /** * Return a string representation of this price pair. */ this.toString = () => { return this.base + ':' + this.quote; }; /** * Return a new Asset with the price converted between the symbols in the pair. * Throws if passed asset symbol is not base or quote. */ this.convert = (asset) => { if (asset.symbol === this.base.symbol) { if (this.base.amount <= 0) { throw new Error('Base amount must be greater than zero'); } return new Asset((asset.amount * this.quote.amount) / this.base.amount, this.quote.symbol); } else if (asset.symbol === this.quote.symbol) { if (this.quote.amount <= 0) { throw new Error('Quote amount must be greater than zero'); } return new Asset((asset.amount * this.base.amount) / this.quote.amount, this.base.symbol); } else { throw new Error(`Can not convert ${asset} with ${this}`); } }; this.base = base; this.quote = quote; if (base.amount === 0 || quote.amount === 0) { throw new Error('base and quote assets must be non-zero'); } if (base.symbol === quote.symbol) { throw new Error('base and quote can not have the same symbol'); } } } exports.Price = Price; /** * Convenience to create new Price. */ Price.from = (value) => { if (value instanceof Price) { return value; } else { return new Price(Asset.from(value.base), Asset.from(value.quote)); } };