UNPKG

@aeternity/aepp-sdk

Version:
132 lines (119 loc) 4.95 kB
/* * ISC License (ISC) * Copyright (c) 2018 aeternity developers * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /** * Ae module * @module @aeternity/aepp-sdk/es/ae * @export Ae * @example import Ae from '@aeternity/aepp-sdk/es/ae' */ import stampit from '@stamp/it' import Tx from '../tx' import Chain from '../chain' import Account from '../account' import TxBuilder from '../tx/builder' import * as R from 'ramda' import { BigNumber } from 'bignumber.js' /** * Sign and post a transaction to the chain * @instance * @category async * @rtype (tx: String, options: Object) => Promise[String] * @param {String} tx - Transaction * @param {Object} [options={}] options - Options * @param {Object} [options.verify] verify - Verify transaction before broadcast, throw error if not valid * @return {String|String} Transaction or transaction hash */ async function send (tx, options) { const opt = R.merge(this.Ae.defaults, options) const signed = await this.signTransaction(tx, opt) return this.sendTransaction(signed, opt) } /** * Send tokens to another account * @instance * @category async * @rtype (amount: Number|String, recipientId: String, options?: Object) => Promise[String] * @param {Number|String} amount - Amount to spend * @param {String} recipientId - Address of recipient account * @param {Object} options - Options * @return {String|String} Transaction or transaction hash */ async function spend (amount, recipientId, options = {}) { const opt = R.merge(this.Ae.defaults, options) const spendTx = await this.spendTx(R.merge(opt, { senderId: await this.address(), recipientId, amount: amount })) return this.send(spendTx, opt) } /** * Send a percentage of funds to another account * @instance * @category async * @rtype (percentage: Number|String, recipientId: String, options?: Object) => Promise[String] * @param {Number|String} percentage - Percentage of amount to spend * @param {String} recipientId - Address of recipient account * @param {Object} options - Options * @return {String|String} Transaction or transaction hash */ async function transferFunds (percentage, recipientId, options = { excludeFee: false }) { if (percentage < 0 || percentage > 1) throw new Error(`Percentage should be a number between 0 and 1, got ${percentage}`) const opt = R.merge(this.Ae.defaults, options) const requestTransferAmount = BigNumber(await this.balance(await this.address())).times(percentage) let spendTx = await this.spendTx(R.merge(opt, { senderId: await this.address(), recipientId, amount: requestTransferAmount })) const { tx: txObject } = TxBuilder.unpackTx(spendTx) // If the requestTransferAmount should include the fee keep calculating the fee let amount = requestTransferAmount if (!options.excludeFee) { while (amount.plus(txObject.fee).gt(requestTransferAmount)) { amount = requestTransferAmount.minus(txObject.fee) } } // Rebuild tx spendTx = await this.spendTx(R.merge(opt, { senderId: await this.address(), recipientId, amount })) return this.send(spendTx, opt) } /** * Remove all listeners for RPC * @instance * @return {void} */ function destroyInstance () { const destroyMethods = ['destroyClient', 'destroyServer'] // Array with destroy function's destroyMethods.forEach(m => this[m] && typeof this[m] === 'function' && this[m]()) } /** * Basic Ae Stamp * * Attempting to create instances from the Stamp without overwriting all * abstract methods using composition will result in an exception. * * Ae objects are the composition of three basic building blocks: * * {@link module:@aeternity/aepp-sdk/es/tx--Tx} * * {@link module:@aeternity/aepp-sdk/es/account--Account} * * {@link module:@aeternity/aepp-sdk/es/chain--Chain} * Only by providing the joint functionality of those three, most more advanced * operations, i.e. the ones with actual use value on the chain, become * available. * @function * @alias module:@aeternity/aepp-sdk/es/ae * @rtype Stamp * @param {Object} [options={}] - Initializer object * @return {Object} Ae instance */ const Ae = stampit(Tx, Account, Chain, { methods: { send, spend, transferFunds, destroyInstance }, deepProps: { Ae: { defaults: {} } } }) export default Ae