cosmic-lib
Version:
A JavaScript implementation of the CosmicLink protocol for Stellar
831 lines (736 loc) • 29.4 kB
JavaScript
"use strict";
var _regeneratorRuntime = require("@babel/runtime/regenerator");
var _asyncToGenerator = require("@babel/runtime/helpers/asyncToGenerator");
var _classCallCheck = require("@babel/runtime/helpers/classCallCheck");
var _createClass = require("@babel/runtime/helpers/createClass");
var env = require("@cosmic-plus/jsutils/es5/env");
var misc = require("@cosmic-plus/jsutils/es5/misc");
var html = env.isBrowser && require("@cosmic-plus/domutils/es5/html");
var SideFrame = env.isBrowser && require("./helpers/side-frame");
var action = require("./action");
var config = require("./config");
var convert = require("./convert");
var format = env.isBrowser && require("./format");
var parse = require("./parse");
var resolve = require("./resolve");
var sep7Utils = require("./sep7-utils");
var status = require("./status");
/**
* | Formats | Data | Actions | Editor | HTML
* |---------------------------------------------|-------------------------------------|------------------------------------------------|----------------------------------------------|----------------------------------------
* |---------------------|---------------------|---------------------|---------------------|---------------------
* | [uri]{@link CosmicLink#uri} |[page]{@link CosmicLink#page} |[open]{@link CosmicLink#open} |[parse]{@link CosmicLink#parse} |[htmlDescription]{@link CosmicLink#htmlDescription}
* | [query]{@link CosmicLink#query} |[network]{@link CosmicLink#network} |[lock]{@link CosmicLink#lock} async |[setTxFields]{@link CosmicLink#setTxFields} |[htmlLink]{@link CosmicLink#htmlLink}
* | [tdesc]{@link CosmicLink#tdesc} |[horizon]{@link CosmicLink#horizon} |[sign]{@link CosmicLink#sign} |[addOperation]{@link CosmicLink#addOperation} |
* | [json]{@link CosmicLink#json} |[callback]{@link CosmicLink#callback}|[send]{@link CosmicLink#send} async |[setOperation]{@link CosmicLink#setOperation}
* | [transaction]{@link CosmicLink#transaction} |[source]{@link CosmicLink#source} |[signSep7]{@link CosmicLink#signSep7} |[insertOperation]{@link CosmicLink#insertOperation}
* | [xdr]{@link CosmicLink#xdr} |[status]{@link CosmicLink#status} |[verifySep7]{@link CosmicLink#verifySep7} async
* | [sep7]{@link CosmicLink#sep7} |[errors]{@link CosmicLink#errors} |
* | |[locker]{@link CosmicLink#locker}
* | |[cache]{@link CosmicLink#cache}
* | |[extra]{@link CosmicLink#extra}
* -----
*
* The **CosmicLink** class represents Stellar
* [transactions]{@link https://stellar.org/developers/guides/concepts/transactions.html}
* encoded in various formats. It allows to convert between those formats, to
* edit the underlying transaction, to build it, to sign it and to send it to
* the blockchain.
*
* There are 3 main formats from which the other are derived:
*
* * The StellarSdk [Transaction]{@link {@link https://stellar.github.io/js-stellar-sdk/Transaction.html}} object. (**transaction**)
* * The CosmicLink, which is a transaction encoded as a query. (**query**)
* * The Tdesc, which is an internal JSON-compatible format in-between those two.
* It is the easier format to work with. (**tdesc**)
*
* Those formats can be derived into other related formats:
*
* * The XDR, which's a base64 representation of StellarSdk Transaction. (**xdr**)
* * The Sep-0007 link, in its XDR form. (**sep7**)
* * The CosmicLink URL/URI, which is a page plus the query. (**uri**)
* * The Tdesc JSON, which is its stringified version. (**json**)
*
* A CosmicLink object can be created from any of those formats. Some of the
* other formats are immediately available, while others may need an
* `await cosmicLink.lock()` operation to become computable:
*
* * If you create a CosmicLink from an **uri**, a **query**, a **tdesc** or a
* **json**, only those 4 formats are available at first. Transaction, xdr &
* sep7 will become available after a `cosmicLink.lock()`. (**free formats**)
* * If you create a CosmicLink from a **transaction**, an **xdr** or a **sep7**,
* all formats will immediately be available. (**locked formats**)
*
* For a better efficiency, formats are lazy-evaluated. This means that they are
* computed once only if/when you call them:
*
* ```js
* const cosmicLink = new CosmicLink(xdr, { network: 'test' })
* console.log(cosmicLink.query)
* ```
*
* The role of `cosmicLink.lock()` is centric to this class. In practice, the
* free formats don't have to be tied to a **network**, a **source** or a
* **sequence number**. For example, the CosmicQuery `?inflation` is a valid
* generic transaction that can be locked to any network/source/sequence
* combination.
*
* On the other hand, locked formats are always tied to a particular combination
* of those, hence the need for a **lock** command:
*
* ```js
* const cosmicLib = require('cosmic-lib')
* cosmicLib.network = 'test'
* cosmicLib.source = 'tips*cosmic.link'
*
* const cosmicLink = new cosmicLib.CosmicLink('?inflation')
*
* console.log(cosmicLink.tdesc.source) // => undefined
* console.log(cosmicLink.tdesc.network) // => undefined
* console.log(cosmicLink.tdesc.sequence) // => undefined
* console.log(cosmicLink.xdr) // => undefined
*
* await cosmicLink.lock({)
*
* console.log(cosmicLink.tdesc.source) // => 'GC6Z...2JVW'
* console.log(cosmicLink.tdesc.network) // => 'test'
* console.log(cosmicLink.tdesc.sequence) // => 29...3903
* console.log(cosmicLink.xdr) // => 'AAAA....AA=='
* ```
*
* The **lock** command is asynchronous because free formats accept
* [federated addresses]{@link https://stellar.org/developers/guides/concepts/federation.html},
* but locked formats don't. The library automatically resolve
* those and this is an asynchronous operation. At the same time, it downloads
* the required data from the blockchain to handle multi-signers transactions.
*
* After the lock operation, all free formats are updated according to the new
* state of the transaction. It is now possible to `cosmicLink.sign(keypair)`
* it, and to `cosmicLink.send()` it to the blockchain.
*/
var CosmicLink = /*#__PURE__*/function () {
/**
* Create a new CosmicLink object. **transaction** can be one of the accepted
* format: uri, query, json, tdesc, transaction, xdr or sep7.
*
* @constructor
* @param {string|Object|Transaction} transaction A transaction in one of
* thoses formats: uri, query, json, tdesc, transaction, xdr, sep7
* @param {Object} options Additional options
* @param {string} options.page The base URI to use when converting transaction
* to URI format.
* @param {string} options.network For Transaction/XDR formats, the network for
* which it have been created
* @param {string} options.strip Remove an element from the original
* XDR transaction. Valid values are `source`, `sequence` and
* `signatures`. Stripping out sequence means that the transaction request
* can get signed anytime in the future, possibly several times.
* Stripping out source means that it can get signed by any account.
* @param {boolean} options.stripNeutralAccount If set, strip source account
* out of SEP-0007/XDR requests when it is equal to the neutral account
* (`GAAA...AWHF`).
* @param {boolean} options.stripNeutralSequence If set, strip sequence out
* of SEP-0007/XDR requests when it is equal to `0`.
* @return {CosmicLink}
*/
function CosmicLink(transaction, options) {
_classCallCheck(this, CosmicLink);
initCosmicLink(this, transaction, options);
}
/**
* Refer to the underlying global configuration
* @private
*/
_createClass(CosmicLink, [{
key: "parse",
/**
* Re-parse this CosmicLink. Useful in implementing transaction editors. The
* parameters are the same than [Constructor]{@link CosmicLink#Constructor},
* and the result is similar except that no new CosmicLink object is created.
*/
value: function parse(transaction, options) {
initCosmicLink(this, transaction, options);
} /// Formats
/**
* A CosmicLink is a URI that embed a Cosmic [Query]{@link CosmicLink#query}.
* This format is simply the `cosmicLink.query` appended to the
* `cosmicLink.page`
*/
}, {
key: "setTxFields",
/// Editor
/**
* Add/remove transaction fields and reparse the CosmicLink. **object** should
* follow the Tdesc format, but fields values can be written using query or
* StellarSdk format as well.
*
* @example
* cosmicLink.setTxFields({ minTime: '2018-10', maxTime: '2019-01' })
*
* @example
* cosmicLink.setTxFields({ minTime: null, maxTime: null })
*
* @example
* cosmicLink.setTxFields({ memo: 'Bonjour!' })
*
* @param {Object} object Transaction fields definition. Fields can be either
* written using the JSON format or the query format
* @return {CosmicLink}
*/
value: function setTxFields(object) {
checkLock(this);
this.parse(Object.assign(this.tdesc, object));
return this;
}
/**
* Add a new operation to CosmicLink. **params** should follow the Tdesc format,
* but fields values can be written using query or StellarSdk format as well.
*
* @example
* cosmicLink.addOperation('changeTrust', { asset: 'CNY:admin*ripplefox' })
*
* @example
* cosmicLink.addOperation('changeTrust', { asset: { code: 'CNY', issuer: 'admin*ripplefox } })
*
* @example
* cosmicLink.addOperation('changeTrust', { asset: new StellarSdk.Asset('CNY', ...) })
*
* @param {string} type The operation type.
* @param {Object} params The operation parameters.
* @return {CosmicLink}
*/
}, {
key: "addOperation",
value: function addOperation(type, params) {
checkLock(this);
var odesc = Object.assign({
type: type
}, params);
this.tdesc.operations.push(odesc);
this.parse(this.tdesc);
return this;
}
/**
* Insert an operation at **index**. **params** should follow the
* Tdesc format, but fields can be written using query or StellarSdk format
* as well.
*
* @example
* cosmicLink.insertOperation(0, 'changeTrust', {
* asset: 'CNY:admin*ripplefox'
* })
*
* @param {integer} index The operation index.
* @param {string} type The operation type.
* @param {params} params The operation parameters.
* @return {CosmicLink}
*/
}, {
key: "insertOperation",
value: function insertOperation(index, type, params) {
checkLock(this);
if (index > !this.tdesc.operations.length) {
throw new Error("Can't insert opereration at position ".concat(index, ": there are only ").concat(this.tdesc.operations.length, " operations"));
}
var odesc = Object.assign({
type: type
}, params);
this.tdesc.operations.splice(index, 0, odesc);
this.parse(this.tdesc);
return this;
}
/**
* Set/remove one of the CosmicLink operations. **params** should follow the
* Tdesc format, but fields can be written using query or StellarSdk format
* as well. If **type** is set to `null`, the operation at **index**
* is deleted.
*
* @example
* cosmicLink.setOperation(1, 'setOptions', { homeDomain: 'example.org' })
*
* @example
* cosmicLink.setOperation(2, null)
*
* @param {integer} index The operation index.
* @param {string} type The operation type.
* @param {params} params The operation parameters.
* @return {CosmicLink}
*/
}, {
key: "setOperation",
value: function setOperation(index, type, params) {
checkLock(this);
if (!this.tdesc.operations[index]) {
throw new Error("Operation ".concat(index, " doesn't exists"));
}
if (type === null) {
this.tdesc.operations.splice(index, 1);
} else {
this.tdesc.operations[index] = Object.assign({
type: type
}, params);
this.parse(this.tdesc);
}
return this;
} /// Actions
/**
* Select the network that this CosmicLink uses.
*
* @deprecated StellarSdk global `Network` setting is deprecated.
*/
}, {
key: "selectNetwork",
value: function selectNetwork() {
return resolve.useNetwork(this);
}
}, {
key: "lock",
value: function lock(options) {
return action.lock(this, options);
}
}, {
key: "sign",
value: function sign() {
for (var _len = arguments.length, keypairs_or_preimage = new Array(_len), _key = 0; _key < _len; _key++) {
keypairs_or_preimage[_key] = arguments[_key];
}
return action.sign.apply(action, [this].concat(keypairs_or_preimage));
}
}, {
key: "send",
value: function send(horizon) {
return action.send(this, horizon);
}
/**
* The HTML DOM node that displays a description of the current transaction.
* This is a browser-only property.
*
* If your HTML page contains an element with `id="cosmiclink_description"`,
* it will automatically get populated with the description of the last
* CosmicLink created.
*/
}, {
key: "open",
/**
* Open CosmicLink in **target**.
*
* - `frame` (default): Open cosmicLink in a side-frame.
* - `tab`: Open cosmicLink in a new tab.
* - `current`: Open cosmicLink into the current window.
* - `sep7`: Open cosmicLink using user's SEP-0007 handler.
*
* @param {String} [target="frame"] Open `cosmicLink` into the requested
* target. Valid targets are: `frame`, `tab`, `current` and `sep7`.
*/
value: function open() {
var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "frame";
if (env.isNode) {
console.error("Warning: cosmicLink.open() is not supported in Node.js environment.");
return;
}
if (this.status) throw new Error(this.status);
switch (target) {
case "frame":
return new SideFrame(this.uri);
case "tab":
window.open(this.uri);
break;
case "current":
location.href = this.uri;
break;
case "sep7":
if (!this.sep7) {
throw new Error("Please use cosmicLink.lock() to build SEP-0007 link.");
} else {
location.href = this.sep7;
}
break;
default:
throw new Error("Invalid cosmicLink.open() target: ".concat(target));
}
}
/**
* Sign SEP-0007 link for **domain**, using **keypair**.
*
* @see [SEP-0007 request signing](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0007.md#request-signing)
*
* @param {String} domain The domain or subdomain you want to sign the request
* for. (example: "a-domain.org")
* @param {Keypair} keypair A StellarSdk Keypair.
*/
}, {
key: "signSep7",
value: function signSep7(domain, keypair) {
if (!this.locker) throw new Error("cosmicLink is not locked.");
sep7Utils.signLink(this, domain, keypair);
}
/**
* Verify SEP-0007 signature by resolving [`cosmicLink.extra.domain`]{@link
* CosmicLink#extra}, if any.
* Throw an error if the signature is not valid.
*
* @return {undefined|String} The resolved `cosmicLink.extra.domain`, if any.
*/
}, {
key: "verifySep7",
value: function () {
var _verifySep = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
var domain;
return _regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
if (!(this.extra.originDomain instanceof Promise)) {
_context.next = 7;
break;
}
_context.next = 3;
return this.extra.originDomain;
case 3:
domain = _context.sent;
this.extra.originDomain = domain;
_context.next = 8;
break;
case 7:
if (this.extra.originDomain) {
sep7Utils.verifySignature(this, this.extra.originDomain);
}
case 8:
return _context.abrupt("return", this.extra.originDomain);
case 9:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
function verifySep7() {
return _verifySep.apply(this, arguments);
}
return verifySep7;
}()
}, {
key: "config",
get: function get() {
return this.__proto__.__proto__;
}
}, {
key: "uri",
get: function get() {
if (this.query) return this.page + this.query;else return undefined;
}
/**
* CosmicLink's transaction encoded in the Cosmic
* [Query]{@link tutorial:specs_query} format. This format allows to
* conveniently pass around Stellar transactions over any URI.
*/
}, {
key: "query",
get: function get() {
if (!this._query) {
if (this.xdr) this._query = convert.xdrToQuery(this, this.xdr, this.tdesc);else if (this.tdesc) this._query = convert.tdescToQuery(this, this.tdesc);else return undefined;
}
return this._query;
}
/**
* CosmicLink's transaction in Tdesc format. This is in-between an objectified
* query representation and a simplified StellarSdk Transaction object. It has
* been created to be convenient to understand, use and manipulate.
*
* If you need to read the transaction parameters, this is the format of
* choice:
*
* ```js
* console.log(cosmicLink.tdesc.network) // Does the transaction enforce a network?
* console.log(cosmicLink.tdesc.source) // Does the transaction enforce a source?
* console.log(cosmicLink.tdesc.memo) // A simplified memo object or undefined
* console.log(cosmicLink.operations) // Transaction operations in simplified format
* ```
*
* This formats authorize [federated addresses]{@link https://stellar.org/developers/guides/concepts/federation.html}
* everywhere StellarSdk Transaction accept public keys. Those addresses are
* resolved when running the [lock]{@link CosmicLink#lock} method, and the
* tdesc is replaced by a resolved one.
*
* Tdesc is also very convenient to edit. To keep the CosmicLink in sync, you
* either need to [parse]{@link CosmicLink#parse} the edited tdesc, or to edit
* it using the dedicated methods:
*
* * [setTxFields]{@link CosmicLink#setTxFields}: set/clear transaction fields
* * [addOperation]{@link CosmicLink#addOperation}: add a new operation
* * [setOperation]{@link CosmicLink#setOperation}: edit/clear an operation
*/
}, {
key: "tdesc",
get: function get() {
if (!this._tdesc) {
if (this.transaction) this._tdesc = convert.transactionToTdesc(this, this.transaction, this.locker);else return undefined;
}
return this._tdesc;
}
/**
* CosmicLink's transaction in JSON format. This is a stringified version of
* [Tdesc]{@link CosmicLink#tdesc} format.
*/
}, {
key: "json",
get: function get() {
if (!this._json) this._json = convert.tdescToJson(this, this.tdesc);
return this._json;
}
/**
* CosmicLink's transaction in StellarSdk
* [Transaction]{@link https://stellar.github.io/js-stellar-sdk/Transaction.html}
* format.
*
* If you created the CosmicLink from uri, query, tdesc or json format, a
* [lock()]{@link CosmicLink#lock} operation is needed to make this format
* available.
*/
}, {
key: "transaction",
get: function get() {
return this._transaction;
}
/**
* CosmicLink's transaction in
* [XDR]{@link https://stellar.org/developers/guides/concepts/xdr.html}
* format.
*
* If you created the CosmicLink from uri, query, tdesc or json format, a
* [lock()]{@link CosmicLink#lock} operation is needed to make this format
* available.
*/
}, {
key: "xdr",
get: function get() {
if (!this._xdr) {
if (!this.transaction) return undefined;
this._xdr = convert.transactionToXdr(this, this.transaction);
}
return this._xdr;
}
/**
* CosmicLink transaction in
* [SEP-0007]{@link https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0007.md}
* link format. Only the XDR part of this protocol is currently supported by
* CosmicLink, minus the signature verification.
*
* If you created the CosmicLink from uri, query, tdesc or json format, a
* [lock()]{@link CosmicLink#lock} operation is needed to make this format
* available.
*/
}, {
key: "sep7",
get: function get() {
if (!this._sep7) {
if (!this.xdr) return undefined;
this._sep7 = convert.xdrToSep7(this, this.xdr, this.tdesc);
}
return this._sep7;
} /// Data
/**
* The page this CosmicLink uses to construct its [URI]{@link CosmicLink#uri}.
*
* @var CosmicLink#page
*/
/**
* The source for this transaction. This can be defined either locally
* (`cosmicLink.tdesc.source`) or globally (`cosmicLib.config.source`). The
* local configuration takes precedence, or, in other words, the global source
* is a fallback value in case the transaction emitter doesn't set one.
*
* **Note:** cosmicLink.tdesc should be edited using [setTxFields]{@link
* CosmicLink#setTxFields}.
*/
}, {
key: "source",
get: function get() {
return this.tdesc && this.tdesc.source || this.config.source;
}
/**
* The network for this transaction. This can be defined either locally
* (`cosmicLink.tdesc.network`) or globally (`cosmicLib.config.network`). The
* local configuration takes precedence, or, in other words, the global
* network is a fallback value in case the transaction emitter doesn't set
* one.
*
* **Note:** cosmicLink.tdesc should be edited using [setTxFields]{@link
* CosmicLink#setTxFields}.
*/
}, {
key: "network",
get: function get() {
return this.tdesc && this.tdesc.network || this.config.network;
}
/**
* The URL of the horizon node from which ledger data will be retrieved, and
* to which the signed transaction will be posted if there's no
* [callback]{@link CosmicLink#callback}.
*
* This can be defined either locally (`cosmicLink.tdesc.horizon`) or globally
* (using [setupNetwork]{@link module:config.setupNetwork}). This parameter is
* special in the sense that it's the only one for which the global
* configuration takes precedence.
*
* The rationale for this behavior is that we want transaction emitter to
* provide a fallback Horizon URL in the special case none is known for a
* custom network, but generally speaking it won't be right to allow the
* transaction emitter to force us to use a particular Horizon node.
*
* **Note:** cosmicLink.tdesc should be edited using [setTxFields]{@link
* CosmicLink#setTxFields}.
*/
}, {
key: "horizon",
get: function get() {
return resolve.horizon(this.config, this.network) || this.tdesc && this.tdesc.horizon;
}
/**
* The URL at which the signed transaction will be posted. This can be defined
* either locally (`cosmicLink.tdesc.callback`) or globally
* (`cosmicLib.config.callback`). The local configuration takes precedence.
*
* When no callback is defined, the signed transaction is posted to
* [Horizon]{@link CosmicLink#horizon}. This is the default behavior.
*
* **Note:** cosmicLink.tdesc should be edited using [setTxFields]{@link
* CosmicLink#setTxFields}.
*/
}, {
key: "callback",
get: function get() {
return this.tdesc && this.tdesc.callback || this.config.callback;
}
}, {
key: "htmlDescription",
get: function get() {
if (!this._htmlDescription) makeHtmlDescription(this);
return this._htmlDescription;
}
/**
* A link HTML Element that points to `cosmicLink.uri`
*/
}, {
key: "htmlLink",
get: function get() {
if (!this._htmlLink) makeHtmlLink(this);
return this._htmlLink;
}
}]);
return CosmicLink;
}();
/**
* Initialize or reset a CosmicLink.
*
* @private
*/
function initCosmicLink(cosmicLink, transaction) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
checkLock(cosmicLink); /// Reset object in case of reparse.
formatsFields.forEach(function (type) {
return delete cosmicLink[type];
});
cosmicLink.page = cosmicLink.page || options.page || config.page;
/**
* The status of a CosmicLink. It becomes non-null in case of failure.
* @var CosmicLink#status
*/
/**
* By default `false`, or an *Array* of errors.
* @var CosmicLink#errors
*/
status.init(cosmicLink);
/**
* The CosmicLink cache contains the resolved federations addresses and the
* accounts object. Using the same set of data for all the CosmicLink related
* computations ensure consistent results.
*
* @var CosmicLink#cache
*/
cosmicLink.cache = {
destination: {},
account: {}
};
/**
* After parsing a SEP-0007 link, `cosmicLink.extra` contains SEP-0007
* specific information:
*
* - `cosmicLink.extra.type` indicates the operation encoded into the SEP-0007
* link (either `tx` or `pay`).
* - `cosmicLink.extra.originDomain` is a _Promise_ that resolves to the
* origin_domain parameter when the link signature is valid. It rejects an
* error when the signature check fails. This property is `undefined` when
* the link has no origin_domain.
* - `cosmicLink.extra.signature` contains the link signature, if any.
* - `cosmicLink.extra.pubkey` contains the tx operation `pubkey`, if any.
* - `cosmicLink.extra.msg` contains the parsed `msg`, if any. This is
* provided for compatibility purpose only. Displaying messages from
* untrusted sources into trusted interfaces opens hard to mitigate attack
* vectors & is discouraged.
*
* @var CosmicLink#extra
*/
cosmicLink.extra = {};
parse.dispatch(cosmicLink, transaction, options);
if (env.isBrowser) {
makeHtmlLink(cosmicLink);
if (!cosmicLink._htmlDescription) {
/// #cosmiclib_htmlNode: Backward compatibility (2018-09 -> 2019-03).
cosmicLink._htmlDescription = html.grab("#cosmiclink_description") || html.grab("#CL_htmlNode");
}
if (cosmicLink._htmlDescription) {
if (cosmicLink.htmlDescription.id === "#CL_htmlNode") {
misc.deprecated("2019-03", "id=\"#CL_htmlNode\"", "id=\"cosmiclink_description\"");
}
makeHtmlDescription(cosmicLink);
}
}
}
var formatsFields = ["_query", "_tdesc", "_json", "_transaction", "_xdr"];
/**
* Initialize CosmicLink html nodes.
*
* @private
*/
function makeHtmlDescription(cosmicLink) {
if (env.isNode) return;
var htmlDescription = cosmicLink._htmlDescription;
if (htmlDescription) {
html.clear(htmlDescription);
htmlDescription.className = "cosmiclink_description";
} else {
htmlDescription = html.create("div", ".cosmiclink_description");
cosmicLink._htmlDescription = htmlDescription;
}
cosmicLink._transactionNode = format.tdesc(cosmicLink, cosmicLink.tdesc);
cosmicLink._statusNode = status.makeHtmlNode(cosmicLink);
cosmicLink._signersNode = html.create("div", ".cosmiclib_signersNode");
html.append(htmlDescription, cosmicLink._transactionNode, cosmicLink._statusNode, cosmicLink._signersNode);
}
/**
* Make the HTML link.
* @private
*/
function makeHtmlLink(cosmicLink) {
if (env.isNode) return;
var htmlLink = html.grab("#cosmiclink") || html.create("a");
htmlLink.className = ".cosmiclink";
htmlLink.href = cosmicLink.page;
htmlLink.onclick = function () {
return htmlLink.href = cosmicLink.uri;
};
if (!htmlLink.title) htmlLink.title = "Sign transaction";
if (!htmlLink.textContent) htmlLink.textContent = "CosmicLink";
cosmicLink._htmlLink = htmlLink;
return htmlLink;
}
/**
* Throw an error if CosmicLink is locked.
* @private
*/
function checkLock(cosmicLink) {
if (cosmicLink.locker) throw new Error("Cosmic link is locked.");
}
CosmicLink.prototype.__proto__ = config;
module.exports = CosmicLink;