cosmic-lib
Version:
A JavaScript implementation of the CosmicLink protocol for Stellar
529 lines (430 loc) • 14.7 kB
JavaScript
"use strict";
/**
* Contains the methods to convert field values from CosmicLink's
* `transaction descriptor` format to Stellar transaction object format.
*
* @private
* @exports construct
*/
var _regeneratorRuntime = require("@babel/runtime/regenerator");
var _asyncToGenerator = require("@babel/runtime/helpers/asyncToGenerator");
var construct = exports;
var Buffer = require("@cosmic-plus/base/es5/buffer");
var misc = require("@cosmic-plus/jsutils/es5/misc");
var StellarSdk = require("@cosmic-plus/base/es5/stellar-sdk");
var resolve = require("./resolve");
var specs = require("./specs");
var status = require("./status");
/**
* Returns the StellarSdk Transaction built from tdesc.
*
* @param {Object} tdesc
* @return {Transaction}
*/
construct.transaction = /*#__PURE__*/function () {
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(conf, tdesc) {
var txBuilder, index, odesc, operation, tx;
return _regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
if (!conf.status) {
_context.next = 2;
break;
}
throw new Error(conf.status);
case 2:
_context.prev = 2;
_context.next = 5;
return makeTransactionBuilder(conf, tdesc);
case 5:
txBuilder = _context.sent;
_context.t0 = _regeneratorRuntime.keys(tdesc.operations);
case 7:
if ((_context.t1 = _context.t0()).done) {
_context.next = 16;
break;
}
index = _context.t1.value;
odesc = tdesc.operations[index];
_context.next = 12;
return construct.operation(conf, odesc);
case 12:
operation = _context.sent;
txBuilder.addOperation(operation);
_context.next = 7;
break;
case 16:
tx = txBuilder.build(); // Fix timebounds related issues. (Trezor can't sign minTime:0+maxTime:0)
if (tx._timeBounds.minTime === "0" && tx._timeBounds.maxTime === "0") {
delete tx._timeBounds;
delete tx._tx._attributes.timeBounds;
}
return _context.abrupt("return", tx);
case 21:
_context.prev = 21;
_context.t2 = _context["catch"](2);
if (!conf.errors) {
console.error(_context.t2);
status.error(conf, _context.t2.message);
}
if (conf.status) {
_context.next = 28;
break;
}
status.fail(conf, "Transaction build failed", "throw");
_context.next = 29;
break;
case 28:
throw _context.t2;
case 29:
case "end":
return _context.stop();
}
}
}, _callee, null, [[2, 21]]);
}));
return function (_x, _x2) {
return _ref.apply(this, arguments);
};
}();
/**
* Returns the StellarSdk Operation built from `odesc`.
*
* @param {Object} odesc
* @return {Operation}
*/
construct.operation = /*#__PURE__*/function () {
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(conf, odesc) {
var operation, field;
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
operation = odesc.type;
delete odesc.type;
_context2.t0 = _regeneratorRuntime.keys(odesc);
case 3:
if ((_context2.t1 = _context2.t0()).done) {
_context2.next = 10;
break;
}
field = _context2.t1.value;
_context2.next = 7;
return construct.field(conf, field, odesc[field]);
case 7:
odesc[field] = _context2.sent;
_context2.next = 3;
break;
case 10:
return _context2.abrupt("return", StellarSdk.Operation[operation](odesc));
case 11:
case "end":
return _context2.stop();
}
}
}, _callee2);
}));
return function (_x3, _x4) {
return _ref2.apply(this, arguments);
};
}();
/**
* Returns the TransactionBuilder for `tdesc`.
*/
function makeTransactionBuilder(_x5, _x6) {
return _makeTransactionBuilder.apply(this, arguments);
}
/******************************************************************************/
/**
* Prepare `value` accordingly to `field` type.
*
* @param {string} field
* @param {any} value
*/
function _makeTransactionBuilder() {
_makeTransactionBuilder = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee9(conf, tdesc) {
var server, baseFee, txOpts, sourceAccount, builder, index, operation, destination, memoType, memoValue, _short;
return _regeneratorRuntime.wrap(function _callee9$(_context9) {
while (1) {
switch (_context9.prev = _context9.next) {
case 0:
server = resolve.server(conf);
_context9.next = 3;
return server.fetchBaseFee();
case 3:
baseFee = _context9.sent;
txOpts = {};
txOpts.networkPassphrase = resolve.networkPassphrase(conf);
if (tdesc.fee) txOpts.fee = tdesc.fee;else txOpts.fee = tdesc.operations.length * baseFee;
if (tdesc.memo) txOpts.memo = construct.memo(conf, tdesc.memo);
txOpts.timebounds = {
minTime: 0,
maxTime: 0
};
if (tdesc.minTime) txOpts.timebounds.minTime = construct.date(conf, tdesc.minTime);
if (tdesc.maxTime) txOpts.timebounds.maxTime = construct.date(conf, tdesc.maxTime);
_context9.next = 13;
return resolve.txSourceAccount(conf, tdesc.source, tdesc.sequence);
case 13:
sourceAccount = _context9.sent;
builder = new StellarSdk.TransactionBuilder(sourceAccount, txOpts); /// Check if memo is needed for destination account.
_context9.t0 = _regeneratorRuntime.keys(tdesc.operations);
case 16:
if ((_context9.t1 = _context9.t0()).done) {
_context9.next = 26;
break;
}
index = _context9.t1.value;
operation = tdesc.operations[index];
if (!operation.destination) {
_context9.next = 24;
break;
}
_context9.next = 22;
return resolve.address(conf, operation.destination);
case 22:
destination = _context9.sent;
if (destination.memo) {
memoType = destination.memo_type;
memoValue = destination.memo;
if (tdesc.memo && (tdesc.memo.type !== memoType || tdesc.memo.value !== memoValue)) {
_short = misc.shorter(operation.destination);
status.error(conf, "Memo conflict: ".concat(_short, " requires to set a memo"), "throw");
} else {
// eslint-disable-next-line require-atomic-updates
tdesc.memo = {
type: memoType,
value: memoValue
};
builder.addMemo(new StellarSdk.Memo(memoType, memoValue));
}
}
case 24:
_context9.next = 16;
break;
case 26:
return _context9.abrupt("return", builder);
case 27:
case "end":
return _context9.stop();
}
}
}, _callee9);
}));
return _makeTransactionBuilder.apply(this, arguments);
}
construct.field = /*#__PURE__*/function () {
var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(conf, field, value) {
var type;
return _regeneratorRuntime.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
type = specs.fieldType[field];
if (!type) {
_context3.next = 5;
break;
}
return _context3.abrupt("return", construct.type(conf, type, value));
case 5:
throw new Error("Invalid field: ".concat(field));
case 6:
case "end":
return _context3.stop();
}
}
}, _callee3);
}));
return function (_x7, _x8, _x9) {
return _ref3.apply(this, arguments);
};
}();
/**
* Prepare `value` using the preparing function for `type`.
*
* @param {string} type
* @param {any} value
*/
construct.type = /*#__PURE__*/function () {
var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(conf, type, value) {
return _regeneratorRuntime.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
return _context4.abrupt("return", construct[type](conf, value));
case 1:
case "end":
return _context4.stop();
}
}
}, _callee4);
}));
return function (_x10, _x11, _x12) {
return _ref4.apply(this, arguments);
};
}();
/******************************************************************************/
construct.address = /*#__PURE__*/function () {
var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(conf, address) {
var account;
return _regeneratorRuntime.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
_context5.next = 2;
return resolve.address(conf, address);
case 2:
account = _context5.sent;
return _context5.abrupt("return", account.account_id);
case 4:
case "end":
return _context5.stop();
}
}
}, _callee5);
}));
return function (_x13, _x14) {
return _ref5.apply(this, arguments);
};
}();
construct.asset = /*#__PURE__*/function () {
var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6(conf, asset) {
var publicKey;
return _regeneratorRuntime.wrap(function _callee6$(_context6) {
while (1) {
switch (_context6.prev = _context6.next) {
case 0:
if (!asset.issuer) {
_context6.next = 7;
break;
}
_context6.next = 3;
return construct.address(conf, asset.issuer);
case 3:
publicKey = _context6.sent;
return _context6.abrupt("return", new StellarSdk.Asset(asset.code, publicKey));
case 7:
return _context6.abrupt("return", StellarSdk.Asset["native"]());
case 8:
case "end":
return _context6.stop();
}
}
}, _callee6);
}));
return function (_x15, _x16) {
return _ref6.apply(this, arguments);
};
}();
construct.assetsArray = /*#__PURE__*/function () {
var _ref7 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee7(conf, assetsArray) {
var path, index, string, constructedAsset;
return _regeneratorRuntime.wrap(function _callee7$(_context7) {
while (1) {
switch (_context7.prev = _context7.next) {
case 0:
path = [];
_context7.t0 = _regeneratorRuntime.keys(assetsArray);
case 2:
if ((_context7.t1 = _context7.t0()).done) {
_context7.next = 11;
break;
}
index = _context7.t1.value;
string = assetsArray[index];
_context7.next = 7;
return construct.asset(conf, string);
case 7:
constructedAsset = _context7.sent;
path.push(constructedAsset);
_context7.next = 2;
break;
case 11:
return _context7.abrupt("return", path);
case 12:
case "end":
return _context7.stop();
}
}
}, _callee7);
}));
return function (_x17, _x18) {
return _ref7.apply(this, arguments);
};
}();
construct.buffer = function (conf, object) {
if (object.type === "base64") {
return Buffer.from(object.value, "base64");
} else {
return object.value || null;
}
};
construct.date = function (conf, string) {
return Date.parse(string) / 1000;
};
construct.memo = function (conf, memo) {
if (memo.type === "base64") {
return new StellarSdk.Memo("text", Buffer.from(memo.value, "base64"));
} else {
return new StellarSdk.Memo(memo.type, memo.value);
}
};
construct.signer = /*#__PURE__*/function () {
var _ref8 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8(conf, signer) {
var sdkSigner, publicKey;
return _regeneratorRuntime.wrap(function _callee8$(_context8) {
while (1) {
switch (_context8.prev = _context8.next) {
case 0:
sdkSigner = {
weight: +signer.weight
};
if (!(signer.type === "tx")) {
_context8.next = 5;
break;
}
sdkSigner.preAuthTx = signer.value;
_context8.next = 14;
break;
case 5:
if (!(signer.type === "hash")) {
_context8.next = 9;
break;
}
sdkSigner.sha256Hash = signer.value;
_context8.next = 14;
break;
case 9:
if (!(signer.type === "key")) {
_context8.next = 14;
break;
}
_context8.next = 12;
return construct.address(conf, signer.value);
case 12:
publicKey = _context8.sent;
sdkSigner.ed25519PublicKey = publicKey;
case 14:
return _context8.abrupt("return", sdkSigner);
case 15:
case "end":
return _context8.stop();
}
}
}, _callee8);
}));
return function (_x19, _x20) {
return _ref8.apply(this, arguments);
};
}();
/******************************************************************************/
/**
* Provide dummy aliases for every other type for convenience & backward
* compatibility.
*/
specs.types.forEach(function (type) {
if (!exports[type]) exports[type] = function (conf, value) {
return value;
};
});