UNPKG

nem-voting

Version:
380 lines 15.9 kB
"use strict"; 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 nem_library_1 = require("nem-library"); const CryptoJS = require("crypto-js"); const rxjs_1 = require("rxjs"); let accountHttp; let chainHttp; let blockHttp; let transactionHttp; const testNodeAddress = "hugetestalice.nem.ninja"; exports.testNodeAddress = testNodeAddress; const mainNodeAddress = "hugealice.nem.ninja"; exports.mainNodeAddress = mainNodeAddress; const initializeHttp = () => { let nodes = []; if (nem_library_1.NEMLibrary.getNetworkType() === nem_library_1.NetworkTypes.TEST_NET) { nodes = [ { protocol: "http", domain: testNodeAddress, port: 7890 }, ]; } else if (nem_library_1.NEMLibrary.getNetworkType() === nem_library_1.NetworkTypes.MAIN_NET) { nodes = [ { protocol: "http", domain: mainNodeAddress, port: 7890 }, ]; } else { throw new Error("Not bootstrapped"); } accountHttp = new nem_library_1.AccountHttp(nodes); if (nem_library_1.NEMLibrary.getNetworkType() === nem_library_1.NetworkTypes.TEST_NET) { accountHttp.historicalNodes = [ { protocol: "http", domain: testNodeAddress, port: 7890 }, ]; } if (nem_library_1.NEMLibrary.getNetworkType() === nem_library_1.NetworkTypes.MAIN_NET) { accountHttp.historicalNodes = [ { protocol: "http", domain: mainNodeAddress, port: 7890 }, ]; } chainHttp = new nem_library_1.ChainHttp(nodes); blockHttp = new nem_library_1.BlockHttp(nodes); transactionHttp = new nem_library_1.TransactionHttp(nodes); }; const getTransferTransaction = (transaction) => { if (transaction.type === nem_library_1.TransactionTypes.MULTISIG) { return transaction.otherTransaction; } else if (transaction.type === nem_library_1.TransactionTypes.TRANSFER) { return transaction; } return null; }; exports.getTransferTransaction = getTransferTransaction; const getTransactionPageable = (receiver, pageSize) => { initializeHttp(); return accountHttp.incomingTransactionsPaginated(receiver, { pageSize }); }; exports.getTransactionPageable = getTransactionPageable; const getAllTransactions = (receiver) => { initializeHttp(); const pageable = accountHttp.incomingTransactionsPaginated(receiver, { pageSize: 100 }); return pageable .map((allTransactions) => { pageable.nextPage(); return allTransactions.filter((t) => (t.type === nem_library_1.TransactionTypes.MULTISIG || t.type === nem_library_1.TransactionTypes.TRANSFER)); }).reduce((acc, page) => { return acc.concat(page); }, []); }; exports.getAllTransactions = getAllTransactions; const getAllOutgoingTransactions = (sender) => { initializeHttp(); const pageable = accountHttp.outgoingTransactionsPaginated(sender, { pageSize: 100 }); return pageable .map((allTransactions) => { pageable.nextPage(); return allTransactions.filter((t) => (t.type === nem_library_1.TransactionTypes.MULTISIG || t.type === nem_library_1.TransactionTypes.TRANSFER)); }).reduce((acc, page) => { return acc.concat(page); }, []); }; const getOutgoingTransactionsWithString = (queryString, sender, position = 0) => { initializeHttp(); return getAllOutgoingTransactions(sender) .map((allTransactions) => { // We only want transfer and multisig transactions, and we are only interested in // the inner transaction for multisig transactions const transactions = allTransactions .map((transaction) => { if (transaction.type === nem_library_1.TransactionTypes.MULTISIG) { transaction = transaction.otherTransaction; } return transaction; }); // Then we get the messages, we only want the plain messages, not encrypted return transactions .filter((t) => t.message.isPlain()) .filter((t) => t.message.plain().includes(queryString, position)); }); }; exports.getOutgoingTransactionsWithString = getOutgoingTransactionsWithString; const getPageOfTransactions = (address, pageSize, lastId) => { initializeHttp(); return accountHttp.incomingTransactions(address, { pageSize, id: lastId, }) .map((allTransactions) => { return allTransactions.filter((t) => (t.type === nem_library_1.TransactionTypes.MULTISIG || t.type === nem_library_1.TransactionTypes.TRANSFER)); }).reduce((acc, page) => { return acc.concat(page); }, []); }; const getPageOfTransactionsWithString = (address, pageSize, queryString, lastId, sender, position = 0) => { return getPageOfTransactions(address, pageSize, lastId) .map((allTransactions) => { // We only want transfer and multisig transactions, and we are only interested in // the inner transaction for multisig transactions let transactions = allTransactions .filter((t) => (t.type === nem_library_1.TransactionTypes.MULTISIG || t.type === nem_library_1.TransactionTypes.TRANSFER)) .map((transaction) => { if (transaction.type === nem_library_1.TransactionTypes.MULTISIG) { transaction = transaction.otherTransaction; } return transaction; }); // filter by sender if (sender !== undefined) { transactions = transactions.filter((t) => (t.signer !== undefined && t.signer.address.plain() === sender.plain())); } // Then we get the messages, we only want the plain messages, not encrypted return transactions .filter((t) => t.message.isPlain()) .filter((t) => t.message.plain().includes(queryString, position)); }); }; exports.getPageOfTransactionsWithString = getPageOfTransactionsWithString; const findTransaction = (sender, receiver) => { return getAllTransactions(receiver) .map((transactions) => { const filtered = transactions.filter((transaction) => { const tt = getTransferTransaction(transaction); if (!tt) { return false; } return (tt.signer.address.plain() === sender.plain()); }); if (filtered.length === 0) { return null; } else { return filtered[0]; } }); }; exports.findTransaction = findTransaction; const getTransactionsWithString = (queryString, receiver, sender, position = 0) => { initializeHttp(); return getAllTransactions(receiver) .map((allTransactions) => { // We only want transfer and multisig transactions, and we are only interested in // the inner transaction for multisig transactions let transactions = allTransactions .filter((t) => (t.type === nem_library_1.TransactionTypes.MULTISIG || t.type === nem_library_1.TransactionTypes.TRANSFER)) .map((transaction) => { if (transaction.type === nem_library_1.TransactionTypes.MULTISIG) { transaction = transaction.otherTransaction; } return transaction; }); // filter by sender if (sender !== undefined) { transactions = transactions.filter((t) => (t.signer !== undefined && t.signer.address.plain() === sender.plain())); } // Then we get the messages, we only want the plain messages, not encrypted return transactions .filter((t) => t.message.isPlain()) .filter((t) => t.message.plain().includes(queryString, position)); }); }; exports.getTransactionsWithString = getTransactionsWithString; const getFirstMessageWithString = (queryString, receiver, sender, position = 0) => { return getTransactionsWithString(queryString, receiver, sender = sender, position = position) .map((transactions) => { if (transactions.length === 0) { return null; } return transactions[transactions.length - 1].message.plain(); }); }; exports.getFirstMessageWithString = getFirstMessageWithString; // Gets the address of the first person that sent a transaction to this address const getFirstSender = (receiver) => { return getTransactionsWithString("", receiver) .map((transactions) => { transactions = transactions.sort((a, b) => { return a.getTransactionInfo().height - b.getTransactionInfo().height; }); if (!transactions || transactions.length === 0 || !transactions[0].signer) { return null; } else { return transactions[0].signer.address; } }); }; exports.getFirstSender = getFirstSender; const getAllMessagesWithString = (queryString, receiver, sender, block) => { return getTransactionsWithString(queryString, receiver, sender = sender) .map((transactions) => { if (transactions.length === 0) { return null; } // filter only transactions sent before block if (block !== undefined) { const validTransactions = transactions.filter((t) => t.getTransactionInfo().height < block); return validTransactions.map((transaction) => transaction.message.plain()); } else { return transactions.map((transaction) => transaction.message.plain()); } }); }; exports.getAllMessagesWithString = getAllMessagesWithString; const NEM_EPOCH = Date.UTC(2015, 2, 29, 0, 6, 25, 0); /** * Create a time stamp for a NEM transaction from a given timestamp * * @param {number} - javascript timestamp in ms * * @return {number} - The NEM transaction time stamp in milliseconds */ const toNEMTimeStamp = (date) => { const ts = Math.floor((date / 1000) - (NEM_EPOCH.valueOf() / 1000)); return ts; }; const getBlockchainHeight = () => { initializeHttp(); return chainHttp.getBlockchainHeight().first().toPromise(); }; const getBlockByHeight = (height) => { initializeHttp(); return blockHttp.getBlockByHeight(height).first().toPromise(); }; const getLastBlock = () => { initializeHttp(); return chainHttp.getBlockchainLastBlock().first().toPromise(); }; /** * getHeightByTimestamp(timestamp) returns the last harvested block at the time of the timestamp. * * @param {integer} timestamp - javascript timestamp in ms * * @return {promise} - a promise that returns the block height */ const getHeightByTimestampPromise = (timestamp) => __awaiter(this, void 0, void 0, function* () { try { // Approximate (60s average block time) const nemTimestamp = toNEMTimeStamp(timestamp); const now = toNEMTimeStamp(Date.now()); // const curHeight = await getBlockchainHeight(); const curHeight = yield getBlockchainHeight(); // memoization const memo = []; let foundHeight = null; let lastTimestamp = now; let lastHeight = curHeight; let lb = 1; // lower bound let ub = curHeight; // upper bound // estimation while (foundHeight === null) { if (lb === ub) { return lb; } let height = lastHeight + Math.ceil((nemTimestamp - lastTimestamp) / 60); if (height < lb) { height = lb; } else if (height > ub) { height = ub; } const block = (memo[height]) ? memo[height] : yield getBlockByHeight(height); memo[height] = block; if (block.timeStamp <= nemTimestamp) { const nextBlock = (memo[height + 1]) ? memo[height + 1] : yield getBlockByHeight(height + 1); memo[height + 1] = nextBlock; // check if target if (nextBlock.timeStamp > nemTimestamp) { foundHeight = height; } else { lb = height + 1; } } else { ub = height - 1; } lastHeight = height; lastTimestamp = block.timeStamp; } return foundHeight; } catch (err) { throw err; } }); exports.getHeightByTimestampPromise = getHeightByTimestampPromise; const getHeightByTimestamp = (timestamp) => { return rxjs_1.Observable.fromPromise(getHeightByTimestampPromise(timestamp)); }; exports.getHeightByTimestamp = getHeightByTimestamp; const getImportances = (addresses, block) => { initializeHttp(); if (block === undefined || block < 0) { return accountHttp.getBatchAccountData(addresses) .map((accountsData) => { return accountsData.map((account) => { return account.importance; }); }); } else { return accountHttp.getBatchHistoricalAccountData(addresses, block, block, 1) .map((accountsHistoricalInfo) => { return accountsHistoricalInfo.map((accountInfo) => { return accountInfo[0].importance; }); }); } }; exports.getImportances = getImportances; const getMessageTransaction = (message, address) => { const transferTransaction = nem_library_1.TransferTransaction.create(nem_library_1.TimeWindow.createWithDeadline(), address, new nem_library_1.XEM(0), nem_library_1.PlainMessage.create(message)); return transferTransaction; }; exports.getMessageTransaction = getMessageTransaction; const getMultisigMessage = (multisigAccount, message, address) => { const transferTransaction = nem_library_1.TransferTransaction.create(nem_library_1.TimeWindow.createWithDeadline(1), address, new nem_library_1.XEM(0), nem_library_1.PlainMessage.create(message)); const multisigTransaction = nem_library_1.MultisigTransaction.create(nem_library_1.TimeWindow.createWithDeadline(), transferTransaction, multisigAccount); return multisigTransaction; }; exports.getMultisigMessage = getMultisigMessage; const publicKeyToAddress = (pubKey) => { if (pubKey[0] >= "8") { pubKey = "00" + pubKey; } const pa = nem_library_1.PublicAccount.createWithPublicKey(pubKey); return pa.address; }; // Poll Address from index information and creator const generatePollAddress = (title, publicKey) => { const pk = CryptoJS.SHA3(publicKey + title, { outputLength: 256 }).toString(); const pa = nem_library_1.PublicAccount.createWithPublicKey(pk); return pa.address; }; exports.generatePollAddress = generatePollAddress; const deriveOptionAddress = (pollAddress, option) => { const plainAddress = pollAddress.plain(); const pubKey = CryptoJS.SHA3(plainAddress + option, { outputLength: 256 }).toString(); return publicKeyToAddress(pubKey); }; exports.deriveOptionAddress = deriveOptionAddress; const generateRandomAddress = () => { const pk = CryptoJS.lib.WordArray.random(32).toString(); return publicKeyToAddress(pk); }; exports.generateRandomAddress = generateRandomAddress; const generateRandomPubKey = () => { return CryptoJS.lib.WordArray.random(32).toString(); }; exports.generateRandomPubKey = generateRandomPubKey; //# sourceMappingURL=utils.js.map