@steemit/steem-js
Version:
JavaScript library for the Steem blockchain
106 lines (100 loc) • 4.84 kB
JavaScript
;
var _bluebird = _interopRequireDefault(require("bluebird"));
var _debug = _interopRequireDefault(require("debug"));
var _helpers = _interopRequireDefault(require("./helpers"));
var _formatter = _interopRequireDefault(require("../formatter"));
var _operations = _interopRequireDefault(require("./operations"));
var _api = _interopRequireDefault(require("../api"));
var _auth = _interopRequireDefault(require("../auth"));
var _utils = require("../utils");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const debug = (0, _debug.default)('steem:broadcast');
const noop = function () {};
const formatter = (0, _formatter.default)(_api.default);
const steemBroadcast = {};
// Base transaction logic -----------------------------------------------------
/**
* Sign and broadcast transactions on the steem network
* @param {Object} tx - Transaction object
* @param {Object|String} privKeys - Private keys or key string
* @param {Function} [callback] - Optional callback function
* @return {Promise} - Returns a promise if no callback is provided
*/
steemBroadcast.send = function steemBroadcast$send(tx, privKeys, callback) {
const resultP = steemBroadcast._prepareTransaction(tx).then(transaction => {
debug('Signing transaction (transaction, transaction.operations)', transaction, transaction.operations);
return _bluebird.default.join(transaction, _auth.default.signTransaction(transaction, privKeys));
}).spread((transaction, signedTransaction) => {
debug('Broadcasting transaction (transaction, transaction.operations)', transaction, transaction.operations);
return _api.default.broadcastTransactionSynchronousAsync(signedTransaction).then(result => {
return Object.assign({}, result, signedTransaction);
});
});
if (callback) {
resultP.nodeify(callback);
return undefined;
} else {
return resultP;
}
};
steemBroadcast._prepareTransaction = function steemBroadcast$_prepareTransaction(tx) {
const propertiesP = _api.default.getDynamicGlobalPropertiesAsync();
return propertiesP.then(properties => {
// Set defaults on the transaction
const chainDate = new Date(properties.time + 'Z');
const refBlockNum = properties.last_irreversible_block_num - 1 & 0xFFFF;
return _api.default.getBlockHeaderAsync(properties.last_irreversible_block_num).then(block => {
const headBlockId = block ? block.previous : '0000000000000000000000000000000000000000';
return Object.assign({
ref_block_num: refBlockNum,
ref_block_prefix: new Buffer.from(headBlockId, 'hex').readUInt32LE(4),
expiration: new Date(chainDate.getTime() + 600 * 1000)
}, tx);
});
});
};
// Generated wrapper ----------------------------------------------------------
// Generate operations from operations.json
_operations.default.forEach(operation => {
const operationName = (0, _utils.camelCase)(operation.operation);
const operationParams = operation.params || [];
const useCommentPermlink = operationParams.indexOf('parent_author') !== -1 && operationParams.indexOf('parent_permlink') !== -1;
steemBroadcast[`${operationName}With`] = function steemBroadcast$specializedSendWith(wif, options, callback) {
debug(`Sending operation "${operationName}" with`, {
options,
callback
});
const keys = {};
if (operation.roles && operation.roles.length) {
keys[operation.roles[0]] = wif; // TODO - Automatically pick a role? Send all?
}
return steemBroadcast.send({
extensions: [],
operations: [[operation.operation, Object.assign({}, options, options.json_metadata != null ? {
json_metadata: toString(options.json_metadata)
} : {}, useCommentPermlink && options.permlink == null ? {
permlink: formatter.commentPermlink(options.parent_author, options.parent_permlink)
} : {})]]
}, keys, callback);
};
steemBroadcast[operationName] = function steemBroadcast$specializedSend(wif, ...args) {
debug(`Parsing operation "${operationName}" with`, {
args
});
const options = operationParams.reduce((memo, param, i) => {
memo[param] = args[i]; // eslint-disable-line no-param-reassign
return memo;
}, {});
// Check if the last argument is a function (callback)
let callback = null;
if (args.length > operationParams.length && typeof args[operationParams.length] === 'function') {
callback = args[operationParams.length];
}
return steemBroadcast[`${operationName}With`](wif, options, callback);
};
});
const toString = obj => typeof obj === 'object' ? JSON.stringify(obj) : obj;
(0, _helpers.default)(steemBroadcast);
// For backwards compatibility, maintain the Async versions
_bluebird.default.promisifyAll(steemBroadcast);
exports = module.exports = steemBroadcast;