UNPKG

triam-base

Version:
863 lines (736 loc) 33.9 kB
"use strict"; var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; Object.defineProperty(exports, "__esModule", { value: true }); var xdr = _interopRequire(require("./generated/stellar-xdr_generated")); var Keypair = require("./keypair").Keypair; var _jsXdr = require("js-xdr"); var UnsignedHyper = _jsXdr.UnsignedHyper; var Hyper = _jsXdr.Hyper; var hash = require("./hashing").hash; var StrKey = require("./strkey").StrKey; var Asset = require("./asset").Asset; var BigNumber = _interopRequire(require("bignumber.js")); var best_r = require("./util/continued_fraction").best_r; var padEnd = _interopRequire(require("lodash/padEnd")); var trimEnd = _interopRequire(require("lodash/trimEnd")); var isEmpty = _interopRequire(require("lodash/isEmpty")); var isUndefined = _interopRequire(require("lodash/isUndefined")); var isString = _interopRequire(require("lodash/isString")); var isNumber = _interopRequire(require("lodash/isNumber")); var isFinite = _interopRequire(require("lodash/isFinite")); var ONE = 10000000; var MAX_INT64 = "9223372036854775807"; /** * When set using `{@link Operation.setOptions}` option, requires the issuing account to * give other accounts permission before they can hold the issuing account’s credit. * @constant * @see [Account flags](https://www.stellar.org/developers/guides/concepts/accounts.html#flags) */ var AuthRequiredFlag = 1 << 0; exports.AuthRequiredFlag = AuthRequiredFlag; /** * When set using `{@link Operation.setOptions}` option, allows the issuing account to * revoke its credit held by other accounts. * @constant * @see [Account flags](https://www.stellar.org/developers/guides/concepts/accounts.html#flags) */ var AuthRevocableFlag = 1 << 1; exports.AuthRevocableFlag = AuthRevocableFlag; /** * When set using `{@link Operation.setOptions}` option, then none of the authorization flags * can be set and the account can never be deleted. * @constant * @see [Account flags](https://www.stellar.org/developers/guides/concepts/accounts.html#flags) */ var AuthImmutableFlag = 1 << 2; exports.AuthImmutableFlag = AuthImmutableFlag; /** * `Operation` class represents [operations](https://www.stellar.org/developers/learn/concepts/operations.html) in Stellar network. * Use one of static methods to create operations: * * `{@link Operation.createAccount}` * * `{@link Operation.payment}` * * `{@link Operation.pathPayment}` * * `{@link Operation.manageOffer}` * * `{@link Operation.createPassiveOffer}` * * `{@link Operation.setOptions}` * * `{@link Operation.changeTrust}` * * `{@link Operation.allowTrust}` * * `{@link Operation.accountMerge}` * * `{@link Operation.inflation}` * * `{@link Operation.manageData}` * * @class Operation */ var Operation = exports.Operation = (function () { function Operation() { _classCallCheck(this, Operation); } _createClass(Operation, null, { createAccount: { /** * Create and fund a non existent account. * @param {object} opts * @param {string} opts.destination - Destination account ID to create an account for. * @param {string} opts.startingBalance - Amount in RIA the account should be funded for. Must be greater * than the [reserve balance amount](https://www.stellar.org/developers/learn/concepts/fees.html). * @param {string} [opts.source] - The source account for the payment. Defaults to the transaction's source account. * @returns {xdr.CreateAccountOp} */ value: function createAccount(opts) { if (!StrKey.isValidEd25519PublicKey(opts.destination)) { throw new Error("destination is invalid"); } if (!this.isValidAmount(opts.startingBalance)) { throw new TypeError(Operation.constructAmountRequirementsError("startingBalance")); } var attributes = {}; attributes.destination = Keypair.fromPublicKey(opts.destination).xdrAccountId(); attributes.startingBalance = this._toXDRAmount(opts.startingBalance); var createAccount = new xdr.CreateAccountOp(attributes); var opAttributes = {}; opAttributes.body = xdr.OperationBody.createAccount(createAccount); this.setSourceAccount(opAttributes, opts); return new xdr.Operation(opAttributes); } }, payment: { /** * Create a payment operation. * @param {object} opts * @param {string} opts.destination - The destination account ID. * @param {Asset} opts.asset - The asset to send. * @param {string} opts.amount - The amount to send. * @param {string} [opts.source] - The source account for the payment. Defaults to the transaction's source account. * @returns {xdr.PaymentOp} */ value: function payment(opts) { if (!StrKey.isValidEd25519PublicKey(opts.destination)) { throw new Error("destination is invalid"); } if (!opts.asset) { throw new Error("Must provide an asset for a payment operation"); } if (!this.isValidAmount(opts.amount)) { throw new TypeError(Operation.constructAmountRequirementsError("amount")); } var attributes = {}; attributes.destination = Keypair.fromPublicKey(opts.destination).xdrAccountId(); attributes.asset = opts.asset.toXDRObject(); attributes.amount = this._toXDRAmount(opts.amount); var payment = new xdr.PaymentOp(attributes); var opAttributes = {}; opAttributes.body = xdr.OperationBody.payment(payment); this.setSourceAccount(opAttributes, opts); return new xdr.Operation(opAttributes); } }, pathPayment: { /** * Returns a XDR PaymentOp. A "payment" operation send the specified amount to the * destination account, optionally through a path. RIA payments create the destination * account if it does not exist. * @param {object} opts * @param {Asset} opts.sendAsset - The asset to pay with. * @param {string} opts.sendMax - The maximum amount of sendAsset to send. * @param {string} opts.destination - The destination account to send to. * @param {Asset} opts.destAsset - The asset the destination will receive. * @param {string} opts.destAmount - The amount the destination receives. * @param {Asset[]} opts.path - An array of Asset objects to use as the path. * @param {string} [opts.source] - The source account for the payment. Defaults to the transaction's source account. * @returns {xdr.PathPaymentOp} */ value: function pathPayment(opts) { if (!opts.sendAsset) { throw new Error("Must specify a send asset"); } if (!this.isValidAmount(opts.sendMax)) { throw new TypeError(Operation.constructAmountRequirementsError("sendMax")); } if (!StrKey.isValidEd25519PublicKey(opts.destination)) { throw new Error("destination is invalid"); } if (!opts.destAsset) { throw new Error("Must provide a destAsset for a payment operation"); } if (!this.isValidAmount(opts.destAmount)) { throw new TypeError(Operation.constructAmountRequirementsError("destAmount")); } var attributes = {}; attributes.sendAsset = opts.sendAsset.toXDRObject(); attributes.sendMax = this._toXDRAmount(opts.sendMax); attributes.destination = Keypair.fromPublicKey(opts.destination).xdrAccountId(); attributes.destAsset = opts.destAsset.toXDRObject(); attributes.destAmount = this._toXDRAmount(opts.destAmount); var path = opts.path ? opts.path : []; attributes.path = []; for (var i in path) { attributes.path.push(path[i].toXDRObject()); } var payment = new xdr.PathPaymentOp(attributes); var opAttributes = {}; opAttributes.body = xdr.OperationBody.pathPayment(payment); this.setSourceAccount(opAttributes, opts); return new xdr.Operation(opAttributes); } }, changeTrust: { /** * Returns an XDR ChangeTrustOp. A "change trust" operation adds, removes, or updates a * trust line for a given asset from the source account to another. The issuer being * trusted and the asset code are in the given Asset object. * @param {object} opts * @param {Asset} opts.asset - The asset for the trust line. * @param {string} [opts.limit] - The limit for the asset, defaults to max int64. * If the limit is set to "0" it deletes the trustline. * @param {string} [opts.source] - The source account (defaults to transaction source). * @returns {xdr.ChangeTrustOp} */ value: function changeTrust(opts) { var attributes = {}; attributes.line = opts.asset.toXDRObject(); if (!isUndefined(opts.limit) && !this.isValidAmount(opts.limit, true)) { throw new TypeError(Operation.constructAmountRequirementsError("limit")); } if (opts.limit) { attributes.limit = this._toXDRAmount(opts.limit); } else { attributes.limit = Hyper.fromString(new BigNumber(MAX_INT64).toString()); } if (opts.source) { attributes.source = opts.source ? opts.source.masterKeypair : null; } var changeTrustOP = new xdr.ChangeTrustOp(attributes); var opAttributes = {}; opAttributes.body = xdr.OperationBody.changeTrust(changeTrustOP); this.setSourceAccount(opAttributes, opts); return new xdr.Operation(opAttributes); } }, allowTrust: { /** * Returns an XDR AllowTrustOp. An "allow trust" operation authorizes another * account to hold your account's credit for a given asset. * @param {object} opts * @param {string} opts.trustor - The trusting account (the one being authorized) * @param {string} opts.assetCode - The asset code being authorized. * @param {boolean} opts.authorize - True to authorize the line, false to deauthorize. * @param {string} [opts.source] - The source account (defaults to transaction source). * @returns {xdr.AllowTrustOp} */ value: function allowTrust(opts) { if (!StrKey.isValidEd25519PublicKey(opts.trustor)) { throw new Error("trustor is invalid"); } var attributes = {}; attributes.trustor = Keypair.fromPublicKey(opts.trustor).xdrAccountId(); if (opts.assetCode.length <= 4) { var code = padEnd(opts.assetCode, 4, "\u0000"); attributes.asset = xdr.AllowTrustOpAsset.assetTypeCreditAlphanum4(code); } else if (opts.assetCode.length <= 12) { var code = padEnd(opts.assetCode, 12, "\u0000"); attributes.asset = xdr.AllowTrustOpAsset.assetTypeCreditAlphanum12(code); } else { throw new Error("Asset code must be 12 characters at max."); } attributes.authorize = opts.authorize; var allowTrustOp = new xdr.AllowTrustOp(attributes); var opAttributes = {}; opAttributes.body = xdr.OperationBody.allowTrust(allowTrustOp); this.setSourceAccount(opAttributes, opts); return new xdr.Operation(opAttributes); } }, setOptions: { /** * Returns an XDR SetOptionsOp. A "set options" operations set or clear account flags, * set the account's inflation destination, and/or add new signers to the account. * The flags used in `opts.clearFlags` and `opts.setFlags` can be the following: * - `{@link AuthRequiredFlag}` * - `{@link AuthRevocableFlag}` * - `{@link AuthImmutableFlag}` * * It's possible to set/clear multiple flags at once using logical or. * @param {object} opts * @param {string} [opts.inflationDest] - Set this account ID as the account's inflation destination. * @param {(number|string)} [opts.clearFlags] - Bitmap integer for which account flags to clear. * @param {(number|string)} [opts.setFlags] - Bitmap integer for which account flags to set. * @param {number|string} [opts.masterWeight] - The master key weight. * @param {number|string} [opts.lowThreshold] - The sum weight for the low threshold. * @param {number|string} [opts.medThreshold] - The sum weight for the medium threshold. * @param {number|string} [opts.highThreshold] - The sum weight for the high threshold. * @param {object} [opts.signer] - Add or remove a signer from the account. The signer is * deleted if the weight is 0. Only one of `ed25519PublicKey`, `sha256Hash`, `preAuthTx` should be defined. * @param {string} [opts.signer.ed25519PublicKey] - The ed25519 public key of the signer. * @param {Buffer|string} [opts.signer.sha256Hash] - sha256 hash (Buffer or hex string) of preimage that will unlock funds. Preimage should be used as signature of future transaction. * @param {Buffer|string} [opts.signer.preAuthTx] - Hash (Buffer or hex string) of transaction that will unlock funds. * @param {number|string} [opts.signer.weight] - The weight of the new signer (0 to delete or 1-255) * @param {string} [opts.homeDomain] - sets the home domain used for reverse federation lookup. * @param {string} [opts.source] - The source account (defaults to transaction source). * @returns {xdr.SetOptionsOp} * @see [Account flags](https://www.stellar.org/developers/guides/concepts/accounts.html#flags) */ value: function setOptions(opts) { var attributes = {}; if (opts.inflationDest) { if (!StrKey.isValidEd25519PublicKey(opts.inflationDest)) { throw new Error("inflationDest is invalid"); } attributes.inflationDest = Keypair.fromPublicKey(opts.inflationDest).xdrAccountId(); } var weightCheckFunction = function (value, name) { if (value >= 0 && value <= 255) { return true; } else { throw new Error("" + name + " value must be between 0 and 255"); } }; attributes.clearFlags = this._checkUnsignedIntValue("clearFlags", opts.clearFlags); attributes.setFlags = this._checkUnsignedIntValue("setFlags", opts.setFlags); attributes.masterWeight = this._checkUnsignedIntValue("masterWeight", opts.masterWeight, weightCheckFunction); attributes.lowThreshold = this._checkUnsignedIntValue("lowThreshold", opts.lowThreshold, weightCheckFunction); attributes.medThreshold = this._checkUnsignedIntValue("medThreshold", opts.medThreshold, weightCheckFunction); attributes.highThreshold = this._checkUnsignedIntValue("highThreshold", opts.highThreshold, weightCheckFunction); if (!isUndefined(opts.homeDomain) && !isString(opts.homeDomain)) { throw new TypeError("homeDomain argument must be of type String"); } attributes.homeDomain = opts.homeDomain; if (opts.signer) { var weight = this._checkUnsignedIntValue("signer.weight", opts.signer.weight, weightCheckFunction); var key = undefined; var setValues = 0; if (opts.signer.ed25519PublicKey) { if (!StrKey.isValidEd25519PublicKey(opts.signer.ed25519PublicKey)) { throw new Error("signer.ed25519PublicKey is invalid."); } var rawKey = StrKey.decodeEd25519PublicKey(opts.signer.ed25519PublicKey); key = new xdr.SignerKey.signerKeyTypeEd25519(rawKey); setValues++; } if (opts.signer.preAuthTx) { if (isString(opts.signer.preAuthTx)) { opts.signer.preAuthTx = Buffer.from(opts.signer.preAuthTx, "hex"); } if (!(Buffer.isBuffer(opts.signer.preAuthTx) && opts.signer.preAuthTx.length == 32)) { throw new Error("signer.preAuthTx must be 32 bytes Buffer."); } key = new xdr.SignerKey.signerKeyTypePreAuthTx(opts.signer.preAuthTx); setValues++; } if (opts.signer.sha256Hash) { if (isString(opts.signer.sha256Hash)) { opts.signer.sha256Hash = Buffer.from(opts.signer.sha256Hash, "hex"); } if (!(Buffer.isBuffer(opts.signer.sha256Hash) && opts.signer.sha256Hash.length == 32)) { throw new Error("signer.sha256Hash must be 32 bytes Buffer."); } key = new xdr.SignerKey.signerKeyTypeHashX(opts.signer.sha256Hash); setValues++; } if (setValues != 1) { throw new Error("Signer object must contain exactly one of signer.ed25519PublicKey, signer.sha256Hash, signer.preAuthTx."); } attributes.signer = new xdr.Signer({ key: key, weight: weight }); } var setOptionsOp = new xdr.SetOptionsOp(attributes); var opAttributes = {}; opAttributes.body = xdr.OperationBody.setOption(setOptionsOp); this.setSourceAccount(opAttributes, opts); return new xdr.Operation(opAttributes); } }, manageOffer: { /** * Returns a XDR ManageOfferOp. A "manage offer" operation creates, updates, or * deletes an offer. * @param {object} opts * @param {Asset} opts.selling - What you're selling. * @param {Asset} opts.buying - What you're buying. * @param {string} opts.amount - The total amount you're selling. If 0, deletes the offer. * @param {number|string|BigNumber|Object} opts.price - Price of 1 unit of `selling` in terms of `buying`. * @param {number} opts.price.n - If `opts.price` is an object: the price numerator * @param {number} opts.price.d - If `opts.price` is an object: the price denominator * @param {number|string} [opts.offerId ]- If `0`, will create a new offer (default). Otherwise, edits an exisiting offer. * @param {string} [opts.source] - The source account (defaults to transaction source). * @throws {Error} Throws `Error` when the best rational approximation of `price` cannot be found. * @returns {xdr.ManageOfferOp} */ value: function manageOffer(opts) { var attributes = {}; attributes.selling = opts.selling.toXDRObject(); attributes.buying = opts.buying.toXDRObject(); if (!this.isValidAmount(opts.amount, true)) { throw new TypeError(Operation.constructAmountRequirementsError("amount")); } attributes.amount = this._toXDRAmount(opts.amount); if (isUndefined(opts.price)) { throw new TypeError("price argument is required"); } attributes.price = this._toXDRPrice(opts.price); if (!isUndefined(opts.offerId)) { opts.offerId = opts.offerId.toString(); } else { opts.offerId = "0"; } attributes.offerId = UnsignedHyper.fromString(opts.offerId); var manageOfferOp = new xdr.ManageOfferOp(attributes); var opAttributes = {}; opAttributes.body = xdr.OperationBody.manageOffer(manageOfferOp); this.setSourceAccount(opAttributes, opts); return new xdr.Operation(opAttributes); } }, createPassiveOffer: { /** * Returns a XDR CreatePasiveOfferOp. A "create passive offer" operation creates an * offer that won't consume a counter offer that exactly matches this offer. This is * useful for offers just used as 1:1 exchanges for path payments. Use manage offer * to manage this offer after using this operation to create it. * @param {object} opts * @param {Asset} opts.selling - What you're selling. * @param {Asset} opts.buying - What you're buying. * @param {string} opts.amount - The total amount you're selling. If 0, deletes the offer. * @param {number|string|BigNumber|Object} opts.price - Price of 1 unit of `selling` in terms of `buying`. * @param {number} opts.price.n - If `opts.price` is an object: the price numerator * @param {number} opts.price.d - If `opts.price` is an object: the price denominator * @param {string} [opts.source] - The source account (defaults to transaction source). * @throws {Error} Throws `Error` when the best rational approximation of `price` cannot be found. * @returns {xdr.CreatePassiveOfferOp} */ value: function createPassiveOffer(opts) { var attributes = {}; attributes.selling = opts.selling.toXDRObject(); attributes.buying = opts.buying.toXDRObject(); if (!this.isValidAmount(opts.amount)) { throw new TypeError(Operation.constructAmountRequirementsError("amount")); } attributes.amount = this._toXDRAmount(opts.amount); if (isUndefined(opts.price)) { throw new TypeError("price argument is required"); } attributes.price = this._toXDRPrice(opts.price); var createPassiveOfferOp = new xdr.CreatePassiveOfferOp(attributes); var opAttributes = {}; opAttributes.body = xdr.OperationBody.createPassiveOffer(createPassiveOfferOp); this.setSourceAccount(opAttributes, opts); return new xdr.Operation(opAttributes); } }, accountMerge: { /** * Transfers native balance to destination account. * @param {object} opts * @param {string} opts.destination - Destination to merge the source account into. * @param {string} [opts.source] - The source account (defaults to transaction source). * @returns {xdr.AccountMergeOp} */ value: function accountMerge(opts) { var opAttributes = {}; if (!StrKey.isValidEd25519PublicKey(opts.destination)) { throw new Error("destination is invalid"); } opAttributes.body = xdr.OperationBody.accountMerge(Keypair.fromPublicKey(opts.destination).xdrAccountId()); this.setSourceAccount(opAttributes, opts); return new xdr.Operation(opAttributes); } }, inflation: { /** * This operation generates the inflation. * @param {object} [opts] * @param {string} [opts.source] - The optional source account. * @returns {xdr.InflationOp} */ value: function inflation() { var opts = arguments[0] === undefined ? {} : arguments[0]; var opAttributes = {}; opAttributes.body = xdr.OperationBody.inflation(); this.setSourceAccount(opAttributes, opts); return new xdr.Operation(opAttributes); } }, manageData: { /** * This operation adds data entry to the ledger. * @param {object} opts * @param {string} opts.name - The name of the data entry. * @param {string|Buffer} opts.value - The value of the data entry. * @param {string} [opts.source] - The optional source account. * @returns {xdr.ManageDataOp} */ value: function manageData(opts) { var attributes = {}; if (!(isString(opts.name) && opts.name.length <= 64)) { throw new Error("name must be a string, up to 64 characters"); } attributes.dataName = opts.name; if (!isString(opts.value) && !Buffer.isBuffer(opts.value) && opts.value !== null) { throw new Error("value must be a string, Buffer or null"); } if (isString(opts.value)) { attributes.dataValue = new Buffer(opts.value); } else { attributes.dataValue = opts.value; } if (attributes.dataValue !== null && attributes.dataValue.length > 64) { throw new Error("value cannot be longer that 64 bytes"); } var manageDataOp = new xdr.ManageDataOp(attributes); var opAttributes = {}; opAttributes.body = xdr.OperationBody.manageDatum(manageDataOp); this.setSourceAccount(opAttributes, opts); return new xdr.Operation(opAttributes); } }, setSourceAccount: { value: function setSourceAccount(opAttributes, opts) { if (opts.source) { if (!StrKey.isValidEd25519PublicKey(opts.source)) { throw new Error("Source address is invalid"); } opAttributes.sourceAccount = Keypair.fromPublicKey(opts.source).xdrAccountId(); } } }, fromXDRObject: { /** * Converts the XDR Operation object to the opts object used to create the XDR * operation. * @param {xdr.Operation} operation - An XDR Operation. * @return {Operation} */ value: function fromXDRObject(operation) { function accountIdtoAddress(accountId) { return StrKey.encodeEd25519PublicKey(accountId.ed25519()); } var result = {}; if (operation.sourceAccount()) { result.source = accountIdtoAddress(operation.sourceAccount()); } var attrs = operation.body().value(); switch (operation.body()["switch"]().name) { case "createAccount": result.type = "createAccount"; result.destination = accountIdtoAddress(attrs.destination()); result.startingBalance = this._fromXDRAmount(attrs.startingBalance()); break; case "payment": result.type = "payment"; result.destination = accountIdtoAddress(attrs.destination()); result.asset = Asset.fromOperation(attrs.asset()); result.amount = this._fromXDRAmount(attrs.amount()); break; case "pathPayment": result.type = "pathPayment"; result.sendAsset = Asset.fromOperation(attrs.sendAsset()); result.sendMax = this._fromXDRAmount(attrs.sendMax()); result.destination = accountIdtoAddress(attrs.destination()); result.destAsset = Asset.fromOperation(attrs.destAsset()); result.destAmount = this._fromXDRAmount(attrs.destAmount()); var path = attrs.path(); result.path = []; for (var i in path) { result.path.push(Asset.fromOperation(path[i])); } break; case "changeTrust": result.type = "changeTrust"; result.line = Asset.fromOperation(attrs.line()); result.limit = this._fromXDRAmount(attrs.limit()); break; case "allowTrust": result.type = "allowTrust"; result.trustor = accountIdtoAddress(attrs.trustor()); result.assetCode = attrs.asset().value().toString(); result.assetCode = trimEnd(result.assetCode, "\u0000"); result.authorize = attrs.authorize(); break; case "setOption": result.type = "setOptions"; if (attrs.inflationDest()) { result.inflationDest = accountIdtoAddress(attrs.inflationDest()); } result.clearFlags = attrs.clearFlags(); result.setFlags = attrs.setFlags(); result.masterWeight = attrs.masterWeight(); result.lowThreshold = attrs.lowThreshold(); result.medThreshold = attrs.medThreshold(); result.highThreshold = attrs.highThreshold(); result.homeDomain = attrs.homeDomain(); if (attrs.signer()) { var signer = {}; var arm = attrs.signer().key().arm(); if (arm == "ed25519") { signer.ed25519PublicKey = accountIdtoAddress(attrs.signer().key()); } else if (arm == "preAuthTx") { signer.preAuthTx = attrs.signer().key().preAuthTx(); } else if (arm == "hashX") { signer.sha256Hash = attrs.signer().key().hashX(); } signer.weight = attrs.signer().weight(); result.signer = signer; } break; case "manageOffer": result.type = "manageOffer"; result.selling = Asset.fromOperation(attrs.selling()); result.buying = Asset.fromOperation(attrs.buying()); result.amount = this._fromXDRAmount(attrs.amount()); result.price = this._fromXDRPrice(attrs.price()); result.offerId = attrs.offerId().toString(); break; case "createPassiveOffer": result.type = "createPassiveOffer"; result.selling = Asset.fromOperation(attrs.selling()); result.buying = Asset.fromOperation(attrs.buying()); result.amount = this._fromXDRAmount(attrs.amount()); result.price = this._fromXDRPrice(attrs.price()); break; case "accountMerge": result.type = "accountMerge"; result.destination = accountIdtoAddress(attrs); break; case "manageDatum": result.type = "manageData"; result.name = attrs.dataName(); result.value = attrs.dataValue(); break; case "inflation": result.type = "inflation"; break; default: throw new Error("Unknown operation"); } return result; } }, isValidAmount: { value: function isValidAmount(value) { var allowZero = arguments[1] === undefined ? false : arguments[1]; if (!isString(value)) { return false; } var amount = undefined; try { amount = new BigNumber(value); } catch (e) { return false; } // == 0 if (!allowZero && amount.isZero()) { return false; } // < 0 if (amount.isNegative()) { return false; } // > Max value if (amount.times(ONE).greaterThan(new BigNumber(MAX_INT64).toString())) { return false; } // Decimal places (max 7) if (amount.decimalPlaces() > 7) { return false; } // Infinity if (!amount.isFinite()) { return false; } // NaN if (amount.isNaN()) { return false; } return true; } }, constructAmountRequirementsError: { value: function constructAmountRequirementsError(arg) { return "" + arg + " argument must be of type String, represent a positive number and have at most 7 digits after the decimal"; } }, _checkUnsignedIntValue: { /** * Returns value converted to uint32 value or undefined. * If `value` is not `Number`, `String` or `Undefined` then throws an error. * Used in {@link Operation.setOptions}. * @private * @param {string} name Name of the property (used in error message only) * @param {*} value Value to check * @param {function(value, name)} isValidFunction Function to check other constraints (the argument will be a `Number`) * @returns {undefined|Number} * @private */ value: function _checkUnsignedIntValue(name, value) { var isValidFunction = arguments[2] === undefined ? null : arguments[2]; if (isUndefined(value)) { return undefined; } if (isString(value)) { value = parseFloat(value); } if (!isNumber(value) || !isFinite(value) || value % 1 !== 0) { throw new Error("" + name + " value is invalid"); } if (value < 0) { throw new Error("" + name + " value must be unsigned"); } if (!isValidFunction || isValidFunction && isValidFunction(value, name)) { return value; } throw new Error("" + name + " value is invalid"); } }, _toXDRAmount: { /** * @private */ value: function _toXDRAmount(value) { var amount = new BigNumber(value).mul(ONE); return Hyper.fromString(amount.toString()); } }, _fromXDRAmount: { /** * @private */ value: function _fromXDRAmount(value) { return new BigNumber(value).div(ONE).toString(); } }, _fromXDRPrice: { /** * @private */ value: function _fromXDRPrice(price) { var n = new BigNumber(price.n()); return n.div(new BigNumber(price.d())).toString(); } }, _toXDRPrice: { /** * @private */ value: function _toXDRPrice(price) { var xdrObject = undefined; if (price.n && price.d) { xdrObject = new xdr.Price(price); } else { price = new BigNumber(price); var approx = best_r(price); xdrObject = new xdr.Price({ n: parseInt(approx[0]), d: parseInt(approx[1]) }); } if (xdrObject.n() < 0 || xdrObject.d() < 0) { throw new Error("price must be positive"); } return xdrObject; } } }); return Operation; })();