cache-typescript-sdk
Version:
Blockstart NIS1 SDK
228 lines • 9.51 kB
JavaScript
;
/*
* The MIT License (MIT)
*
* Copyright (c) 2017 NEM
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const Mosaic_1 = require("../mosaic/Mosaic");
const XEM_1 = require("../mosaic/XEM");
const EncryptedMessage_1 = require("./EncryptedMessage");
const TimeWindow_1 = require("./TimeWindow");
const Transaction_1 = require("./Transaction");
const TransactionTypes_1 = require("./TransactionTypes");
var ExpirationType;
(function (ExpirationType) {
ExpirationType[ExpirationType["oneHour"] = 1] = "oneHour";
ExpirationType[ExpirationType["twoHour"] = 2] = "twoHour";
ExpirationType[ExpirationType["sixHour"] = 6] = "sixHour";
ExpirationType[ExpirationType["twelveHour"] = 12] = "twelveHour";
})(ExpirationType = exports.ExpirationType || (exports.ExpirationType = {}));
/**
* Transfer transactions contain data about transfers of XEM or mosaics to another account.
*/
class TransferTransaction extends Transaction_1.Transaction {
/**
* @internal
* @param recipient
* @param amount
* @param timeWindow
* @param version
* @param fee
* @param message
* @param signature
* @param mosaic
* @param sender
* @param transactionInfo
*/
constructor(recipient, amount, timeWindow, version, fee, message, signature, mosaic, sender, transactionInfo) {
super(TransactionTypes_1.TransactionTypes.TRANSFER, version, timeWindow, signature, sender, transactionInfo);
/**
* returns mosaic array of received mosaics
* @returns {MosaicTransferable[]}
*/
this.mosaicDetails = () => {
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
try {
if (this.containsMosaics()) {
resolve(yield Promise.all(this.mosaics().map((mosaic) => __awaiter(this, void 0, void 0, function* () {
return yield mosaic.getMosaicDetails();
}))));
}
else {
resolve([this.xem()]);
}
}
catch (err) {
reject(err);
}
}));
};
this.fee = fee;
this.recipient = recipient;
this._xem = amount;
this.message = message;
this._mosaics = mosaic;
}
/**
* in case that the transfer transaction contains mosaics, it throws an error
* @returns {XEM}
*/
xem() {
if (this.containsMosaics()) {
throw new Error("contain mosaics");
}
return this._xem;
}
/**
* in case that the transfer transaction does not contain mosaics, it throws an error
* @returns {Mosaic[]}
*/
mosaics() {
if (this.containsMosaics()) {
return this._mosaics
.map(x => new Mosaic_1.Mosaic(x.mosaicId, (x.quantity * (this._xem.quantity() / 1e6))));
}
throw new Error("Does not contain mosaics");
}
/**
*
* @returns {boolean}
*/
containsMosaics() {
return this._mosaics !== undefined && this._mosaics.length > 0;
}
/**
* all the Mosaic Identifiers of the attached mosaics
* @returns {MosaicId[]}
*/
mosaicIds() {
if (!this.containsMosaics()) {
throw new Error("does not contain mosaics");
}
return this._mosaics.map((_) => _.mosaicId);
}
/**
* Create DTO of TransferTransaction
* @returns {TransferTransactionDTO}
*/
toDTO() {
const version = this.networkVersion ? this.networkVersion : this.version;
return this.serializeDTO({
signer: this.signer ? this.signer.publicKey : undefined,
deadline: this.timeWindow.deadlineToDTO(),
timeStamp: this.timeWindow.timeStampToDTO(),
signature: this.signature,
type: this.type,
version,
mosaics: this._mosaics === undefined ? undefined : this._mosaics.map((mosaic) => new Mosaic_1.Mosaic(mosaic.mosaicId, mosaic.quantity)),
fee: this.fee,
recipient: this.recipient.plain(),
amount: this._xem.quantity(),
message: this.message.toDTO(),
});
}
/**
* Create a TransferTransaction object
* @param recipient
* @param xem
* @param message
* @param expiration?
* @returns {TransferTransaction}
*/
static createWithXem(recipient, xem, message, expiration) {
if (message instanceof EncryptedMessage_1.EncryptedMessage && recipient.plain() !== message.recipientPublicAccount.address.plain()) {
throw new Error("Recipient address and recipientPublicAccount don't match");
}
let fee = Math.floor(0.05 * this.calculateMinimum(xem.quantity() / 1000000) * 1000000);
if (message.payload.length !== 0) {
fee += 0.05 * (Math.floor((message.payload.length / 2) / 32) + 1) * 1000000;
}
return new TransferTransaction(recipient, xem, TimeWindow_1.TimeWindow.createWithDeadline(expiration), 1, fee, message, undefined, undefined);
}
/**
* @internal
* @param amount
* @returns {number}
*/
static calculateMinimum(amount) {
const fee = Math.floor(Math.max(1, amount / 10000));
return fee > 25 ? 25 : fee;
}
/**
* Create a TransferTransaction object
* @param recipient
* @param mosaics
* @param message
* @param expiration?
* @returns {TransferTransaction}
*/
static createWithMosaics(recipient, mosaics, message, expiration) {
if (message instanceof EncryptedMessage_1.EncryptedMessage && recipient.plain() !== message.recipientPublicAccount.address.plain()) {
throw new Error("Recipient address and recipientPublicAccount don't match");
}
const multiplier = new XEM_1.XEM(1);
let fee = 0;
mosaics.map((mosaic) => {
if (mosaic.properties.divisibility === 0 && mosaic.properties.initialSupply <= 10000) {
fee += 0.05 * 1000000;
}
else {
const quantity = mosaic.amount;
const maxMosaicQuantity = 9000000000000000;
const totalMosaicQuantity = mosaic.properties.initialSupply * Math.pow(10, mosaic.properties.divisibility);
const supplyRelatedAdjustment = Math.floor(0.8 * Math.log(maxMosaicQuantity / totalMosaicQuantity));
const xemFee = Math.min(25, quantity * 900000 / mosaic.properties.initialSupply);
fee += 0.05 * Math.max(1, xemFee - supplyRelatedAdjustment) * 1000000;
}
});
if (message.payload.length !== 0) {
fee += 0.05 * (Math.floor((message.payload.length / 2) / 32) + 1) * 1000000;
}
return new TransferTransaction(recipient, multiplier, TimeWindow_1.TimeWindow.createWithDeadline(expiration), 2, fee, message, undefined, mosaics.map((_) => new Mosaic_1.Mosaic(_.mosaicId, _.quantity())));
}
}
/**
* Create a CacheTransferTransaction object
* @param recipient
* @param mosaic
* @param message
* @param expiration? - 2 hours default, can't exceed 23 hours
* @returns {TransferTransaction}
*/
TransferTransaction.create = (recipient, mosaic, message, expiration) => {
if (mosaic.mosaicId.namespaceId === 'nem' && mosaic.mosaicId.name === 'xem') {
return TransferTransaction.createWithXem(recipient, mosaic, message, expiration);
}
else {
return TransferTransaction.createWithMosaics(recipient, [mosaic], message, expiration);
}
};
exports.TransferTransaction = TransferTransaction;
//# sourceMappingURL=TransferTransaction.js.map