diff --git a/docs/scripts/btcOperator.js b/docs/scripts/btcOperator.js index 7406ba2..ce8b09d 100644 --- a/docs/scripts/btcOperator.js +++ b/docs/scripts/btcOperator.js @@ -1,11 +1,11 @@ -(function(EXPORTS) { //btcOperator v1.0.10a +(function (EXPORTS) { //btcOperator v1.0.11 /* BTC Crypto and API Operator */ const btcOperator = EXPORTS; //This library uses API provided by chain.so (https://chain.so/) const URL = "https://chain.so/api/v2/"; - const fetch_api = btcOperator.fetch = function(api) { + const fetch_api = btcOperator.fetch = function (api) { return new Promise((resolve, reject) => { console.debug(URL + api); fetch(URL + api).then(response => { @@ -23,8 +23,8 @@ fetch('https://api.blockchain.info/mempool/fees').then(response => { if (response.ok) response.json() - .then(result => resolve(parseFloat((result.regular / SATOSHI_IN_BTC).toFixed(8)))) - .catch(error => reject(error)); + .then(result => resolve(parseFloat((result.regular / SATOSHI_IN_BTC).toFixed(8)))) + .catch(error => reject(error)); else reject(response); }).catch(error => reject(error)) @@ -39,7 +39,7 @@ "tx_hex": rawTxHex }, dataType: "json", - error: e => reject(e.responseJSON), + error: e => reject((e.responseJSON && e.responseJSON.status === "fail") ? null : e.responseJSON), success: r => r.status === "success" ? resolve(r.data.txid) : reject(r) }) }); @@ -69,7 +69,7 @@ coinjs.compressed = true; - const verifyKey = btcOperator.verifyKey = function(addr, key) { + const verifyKey = btcOperator.verifyKey = function (addr, key) { if (!addr || !key) return undefined; switch (coinjs.addressDecode(addr).type) { @@ -84,7 +84,7 @@ } } - const validateAddress = btcOperator.validateAddress = function(addr) { + const validateAddress = btcOperator.validateAddress = function (addr) { if (!addr) return undefined; let type = coinjs.addressDecode(addr).type; @@ -94,7 +94,7 @@ return false; } - btcOperator.multiSigAddress = function(pubKeys, minRequired) { + btcOperator.multiSigAddress = function (pubKeys, minRequired) { if (!Array.isArray(pubKeys)) throw "pubKeys must be an array of public keys"; else if (pubKeys.length < minRequired) @@ -105,7 +105,7 @@ //convert from one blockchain to another blockchain (target version) btcOperator.convert = {}; - btcOperator.convert.wif = function(source_wif, target_version = coinjs.priv) { + btcOperator.convert.wif = function (source_wif, target_version = coinjs.priv) { let keyHex = decodeLegacy(source_wif).hex; if (!keyHex || keyHex.length < 66 || !/01$/.test(keyHex)) return null; @@ -113,7 +113,7 @@ return encodeLegacy(keyHex, target_version); } - btcOperator.convert.legacy2legacy = function(source_addr, target_version = coinjs.pub) { + btcOperator.convert.legacy2legacy = function (source_addr, target_version = coinjs.pub) { let rawHex = decodeLegacy(source_addr).hex; if (!rawHex) return null; @@ -121,7 +121,7 @@ return encodeLegacy(rawHex, target_version); } - btcOperator.convert.legacy2bech = function(source_addr, target_version = coinjs.bech32.version, target_hrp = coinjs.bech32.hrp) { + btcOperator.convert.legacy2bech = function (source_addr, target_version = coinjs.bech32.version, target_hrp = coinjs.bech32.hrp) { let rawHex = decodeLegacy(source_addr).hex; if (!rawHex) return null; @@ -129,7 +129,7 @@ return encodeBech32(rawHex, target_version, target_hrp); } - btcOperator.convert.bech2bech = function(source_addr, target_version = coinjs.bech32.version, target_hrp = coinjs.bech32.hrp) { + btcOperator.convert.bech2bech = function (source_addr, target_version = coinjs.bech32.version, target_hrp = coinjs.bech32.hrp) { let rawHex = decodeBech32(source_addr).hex; if (!rawHex) return null; @@ -137,7 +137,7 @@ return encodeBech32(rawHex, target_version, target_hrp); } - btcOperator.convert.bech2legacy = function(source_addr, target_version = coinjs.pub) { + btcOperator.convert.bech2legacy = function (source_addr, target_version = coinjs.pub) { let rawHex = decodeBech32(source_addr).hex; if (!rawHex) return null; @@ -340,7 +340,7 @@ let net_fee = BASE_TX_SIZE * fee_rate; net_fee += (output_size * fee_rate); addUTXOs(tx, senders, redeemScripts, total_amount + net_fee, fee_rate).then(result => { - result.fee_amount = parseFloat((net_fee + (result.input_size * fee_rate)).toFixed(8)); + result.fee = parseFloat((net_fee + (result.input_size * fee_rate)).toFixed(8)); result.fee_rate = fee_rate; resolve(result); }).catch(error => reject(error)) @@ -386,7 +386,7 @@ script = Crypto.util.bytesToHex(s.buffer); } else //redeemScript for multisig script = rs; - tx.addinput(utxos[i].txid, utxos[i].output_no, script, 0xfffffffd /*sequence*/ ); //0xfffffffd for Replace-by-fee + tx.addinput(utxos[i].txid, utxos[i].output_no, script, 0xfffffffd /*sequence*/); //0xfffffffd for Replace-by-fee //update track values rec_args.input_size += size_per_input; rec_args.input_amount += parseFloat(utxos[i].value); @@ -450,7 +450,18 @@ } */ - btcOperator.sendTx = function(senders, privkeys, receivers, amounts, fee, change_addr = null) { + btcOperator.sendTx = function (senders, privkeys, receivers, amounts, fee, change_addr = null) { + return new Promise((resolve, reject) => { + createSignedTx(senders, privkeys, receivers, amounts, fee, change_addr).then(result => { + debugger; + broadcastTx(result.transaction.serialize()) + .then(txid => resolve(txid)) + .catch(error => reject(error)); + }).catch(error => reject(error)) + }) + } + + const createSignedTx = btcOperator.createSignedTx = function (senders, privkeys, receivers, amounts, fee, change_addr = null) { return new Promise((resolve, reject) => { try { ({ @@ -482,17 +493,14 @@ createTransaction(senders, redeemScripts, receivers, amounts, fee, change_addr || senders[0]).then(result => { let tx = result.transaction; console.debug("Unsigned:", tx.serialize()); - new Set(wif_keys).forEach(key => console.debug("Signing key:", key, tx.sign(key, 1 /*sighashtype*/ ))); //Sign the tx using private key WIF + new Set(wif_keys).forEach(key => console.debug("Signing key:", key, tx.sign(key, 1 /*sighashtype*/))); //Sign the tx using private key WIF console.debug("Signed:", tx.serialize()); - debugger; - broadcastTx(tx.serialize()) - .then(txid => resolve(txid)) - .catch(error => reject(error)); + resolve(result); }).catch(error => reject(error)); }) } - btcOperator.createTx = function(senders, receivers, amounts, fee = null, change_addr = null) { + btcOperator.createTx = function (senders, receivers, amounts, fee = null, change_addr = null) { return new Promise((resolve, reject) => { try { ({ @@ -521,7 +529,7 @@ }) } - btcOperator.createMultiSigTx = function(sender, redeemScript, receivers, amounts, fee) { + btcOperator.createMultiSigTx = function (sender, redeemScript, receivers, amounts, fee) { return new Promise((resolve, reject) => { //validate tx parameters if (validateAddress(sender) !== "multisig") @@ -566,7 +574,7 @@ return tx; } - btcOperator.signTx = function(tx, privkeys, sighashtype = 1) { + btcOperator.signTx = function (tx, privkeys, sighashtype = 1) { tx = deserializeTx(tx); if (!Array.isArray(privkeys)) privkeys = [privkeys]; @@ -577,7 +585,7 @@ return tx.serialize(); } - const checkSigned = btcOperator.checkSigned = function(tx, bool = true) { + const checkSigned = btcOperator.checkSigned = function (tx, bool = true) { tx = deserializeTx(tx); let n = []; for (let i in tx.ins) { @@ -602,7 +610,7 @@ return bool ? !(n.filter(x => x !== true).length) : n; } - btcOperator.checkIfSameTx = function(tx1, tx2) { + btcOperator.checkIfSameTx = function (tx1, tx2) { tx1 = deserializeTx(tx1); tx2 = deserializeTx(tx2); if (tx1.ins.length !== tx2.ins.length || tx1.outs.length !== tx2.outs.length) @@ -622,7 +630,7 @@ .catch(error => reject(error)) }); - btcOperator.parseTransaction = function(tx) { + btcOperator.parseTransaction = function (tx) { return new Promise((resolve, reject) => { tx = deserializeTx(tx); let result = {}; @@ -664,8 +672,17 @@ }) } + btcOperator.transactionID = function (tx) { + tx = deserializeTx(tx); + let clone = coinjs.clone(tx); + clone.witness = null; + let raw_bytes = Crypto.util.hexToBytes(clone.serialize()); + let txid = Crypto.SHA256(Crypto.SHA256(raw_bytes, { asBytes: true }), { asBytes: true }).reverse(); + return Crypto.util.bytesToHex(txid); + } + btcOperator.getTx = txid => new Promise((resolve, reject) => { - fetch_api(`get_tx/BTC/${txid}`) + fetch_api(`tx/BTC/${txid}`) .then(result => resolve(result.data)) .catch(error => reject(error)) }); diff --git a/docs/scripts/floBlockchainAPI.js b/docs/scripts/floBlockchainAPI.js index d250f86..5bb3cbb 100644 --- a/docs/scripts/floBlockchainAPI.js +++ b/docs/scripts/floBlockchainAPI.js @@ -1,4 +1,4 @@ -(function(EXPORTS) { //floBlockchainAPI v2.3.3b +(function (EXPORTS) { //floBlockchainAPI v2.3.3c /* FLO Blockchain Operator to send/receive data from blockchain using API calls*/ 'use strict'; const floBlockchainAPI = EXPORTS; @@ -11,6 +11,7 @@ }, sendAmt: 0.001, fee: 0.0005, + minChangeAmt: 0.0005, receiverID: floGlobals.adminID }; @@ -102,7 +103,7 @@ }); //Promised function to get data from API - const promisedAPI = floBlockchainAPI.promisedAPI = floBlockchainAPI.fetch = function(apicall) { + const promisedAPI = floBlockchainAPI.promisedAPI = floBlockchainAPI.fetch = function (apicall) { return new Promise((resolve, reject) => { //console.log(apicall); fetch_api(apicall) @@ -112,7 +113,7 @@ } //Get balance for the given Address - const getBalance = floBlockchainAPI.getBalance = function(addr) { + const getBalance = floBlockchainAPI.getBalance = function (addr) { return new Promise((resolve, reject) => { promisedAPI(`api/addr/${addr}/balance`) .then(balance => resolve(parseFloat(balance))) @@ -121,7 +122,7 @@ } //Send Tx to blockchain - const sendTx = floBlockchainAPI.sendTx = function(senderAddr, receiverAddr, sendAmt, privKey, floData = '', strict_utxo = true) { + const sendTx = floBlockchainAPI.sendTx = function (senderAddr, receiverAddr, sendAmt, privKey, floData = '', strict_utxo = true) { return new Promise((resolve, reject) => { if (!floCrypto.validateASCII(floData)) return reject("Invalid FLO_Data: only printable ASCII characters are allowed"); @@ -171,7 +172,7 @@ else { trx.addoutput(receiverAddr, sendAmt); var change = utxoAmt - sendAmt - fee; - if (change > 0) + if (change > DEFAULT.minChangeAmt) trx.addoutput(senderAddr, change); trx.addflodata(floData.replace(/\n/g, ' ')); var signedTxHash = trx.sign(privKey, 1); @@ -187,7 +188,7 @@ } //Write Data into blockchain - floBlockchainAPI.writeData = function(senderAddr, data, privKey, receiverAddr = DEFAULT.receiverID, options = {}) { + floBlockchainAPI.writeData = function (senderAddr, data, privKey, receiverAddr = DEFAULT.receiverID, options = {}) { let strict_utxo = options.strict_utxo === false ? false : true, sendAmt = isNaN(options.sendAmt) ? DEFAULT.sendAmt : options.sendAmt; return new Promise((resolve, reject) => { @@ -200,7 +201,7 @@ } //merge all UTXOs of a given floID into a single UTXO - floBlockchainAPI.mergeUTXOs = function(floID, privKey, floData = '') { + floBlockchainAPI.mergeUTXOs = function (floID, privKey, floData = '') { return new Promise((resolve, reject) => { if (!floCrypto.validateFloID(floID)) return reject(`Invalid floID`); @@ -234,7 +235,7 @@ * @param {boolean} preserveRatio (optional) preserve ratio or equal contribution * @return {Promise} */ - floBlockchainAPI.writeDataMultiple = function(senderPrivKeys, data, receivers = [DEFAULT.receiverID], preserveRatio = true) { + floBlockchainAPI.writeDataMultiple = function (senderPrivKeys, data, receivers = [DEFAULT.receiverID], preserveRatio = true) { return new Promise((resolve, reject) => { if (!Array.isArray(senderPrivKeys)) return reject("Invalid senderPrivKeys: SenderPrivKeys must be Array"); @@ -266,7 +267,7 @@ * @param {string} floData FLO data of the txn * @return {Promise} */ - const sendTxMultiple = floBlockchainAPI.sendTxMultiple = function(senderPrivKeys, receivers, floData = '') { + const sendTxMultiple = floBlockchainAPI.sendTxMultiple = function (senderPrivKeys, receivers, floData = '') { return new Promise((resolve, reject) => { if (!floCrypto.validateASCII(floData)) return reject("Invalid FLO_Data: only printable ASCII characters are allowed"); @@ -421,7 +422,7 @@ } //Broadcast signed Tx in blockchain using API - const broadcastTx = floBlockchainAPI.broadcastTx = function(signedTxHash) { + const broadcastTx = floBlockchainAPI.broadcastTx = function (signedTxHash) { return new Promise((resolve, reject) => { if (signedTxHash.length < 1) return reject("Empty Signature"); @@ -441,7 +442,7 @@ }) } - floBlockchainAPI.getTx = function(txid) { + floBlockchainAPI.getTx = function (txid) { return new Promise((resolve, reject) => { promisedAPI(`api/tx/${txid}`) .then(response => resolve(response)) @@ -450,7 +451,7 @@ } //Read Txs of Address between from and to - const readTxs = floBlockchainAPI.readTxs = function(addr, from, to) { + const readTxs = floBlockchainAPI.readTxs = function (addr, from, to) { return new Promise((resolve, reject) => { promisedAPI(`api/addrs/${addr}/txs?from=${from}&to=${to}`) .then(response => resolve(response)) @@ -459,7 +460,7 @@ } //Read All Txs of Address (newest first) - floBlockchainAPI.readAllTxs = function(addr) { + floBlockchainAPI.readAllTxs = function (addr) { return new Promise((resolve, reject) => { promisedAPI(`api/addrs/${addr}/txs?from=0&to=1`).then(response => { promisedAPI(`api/addrs/${addr}/txs?from=0&to=${response.totalItems}0`) @@ -481,7 +482,7 @@ sender : flo-id(s) of sender receiver : flo-id(s) of receiver */ - floBlockchainAPI.readData = function(addr, options = {}) { + floBlockchainAPI.readData = function (addr, options = {}) { options.limit = options.limit || 0; options.ignoreOld = options.ignoreOld || 0; if (typeof options.sender === "string") options.sender = [options.sender]; @@ -489,7 +490,7 @@ return new Promise((resolve, reject) => { promisedAPI(`api/addrs/${addr}/txs?from=0&to=1`).then(response => { var newItems = response.totalItems - options.ignoreOld; - promisedAPI(`api/addrs/${addr}/txs?from=0&to=${newItems*2}`).then(response => { + promisedAPI(`api/addrs/${addr}/txs?from=0&to=${newItems * 2}`).then(response => { if (options.limit <= 0) options.limit = response.items.length; var filteredData = []; @@ -555,6 +556,8 @@ d.txid = response.items[i].txid; d.time = response.items[i].time; d.blockheight = response.items[i].blockheight; + d.senders = new Set(response.items[i].vin.map(v => v.addr)); + d.receivers = new Set(response.items[i].vout.map(v => v.scriptPubKey.addresses[0])); d.data = response.items[i].floData; filteredData.push(d); } else diff --git a/docs/scripts/floCrypto.js b/docs/scripts/floCrypto.js index 6671ffa..563d77f 100644 --- a/docs/scripts/floCrypto.js +++ b/docs/scripts/floCrypto.js @@ -1,4 +1,4 @@ -(function(EXPORTS) { //floCrypto v2.3.3d +(function (EXPORTS) { //floCrypto v2.3.3e /* FLO Crypto Operators */ 'use strict'; const floCrypto = EXPORTS; @@ -78,14 +78,14 @@ } //generate a random Interger within range - floCrypto.randInt = function(min, max) { + floCrypto.randInt = function (min, max) { min = Math.ceil(min); max = Math.floor(max); return Math.floor(securedMathRandom() * (max - min + 1)) + min; } //generate a random String within length (options : alphaNumeric chars only) - floCrypto.randString = function(length, alphaNumeric = true) { + floCrypto.randString = function (length, alphaNumeric = true) { var result = ''; var characters = alphaNumeric ? 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_+-./*?@#&$<>=[]{}():'; @@ -95,7 +95,7 @@ } //Encrypt Data using public-key - floCrypto.encryptData = function(data, receiverPublicKeyHex) { + floCrypto.encryptData = function (data, receiverPublicKeyHex) { var senderECKeyData = getSenderPublicKeyString(); var senderDerivedKey = deriveSharedKeySender(receiverPublicKeyHex, senderECKeyData.privateKey); let senderKey = senderDerivedKey.XValue + senderDerivedKey.YValue; @@ -107,7 +107,7 @@ } //Decrypt Data using private-key - floCrypto.decryptData = function(data, privateKeyHex) { + floCrypto.decryptData = function (data, privateKeyHex) { var receiverECKeyData = {}; if (typeof privateKeyHex !== "string") throw new Error("No private key found."); let privateKey = wifToDecimal(privateKeyHex, true); @@ -120,7 +120,7 @@ } //Sign data using private-key - floCrypto.signData = function(data, privateKeyHex) { + floCrypto.signData = function (data, privateKeyHex) { var key = new Bitcoin.ECKey(privateKeyHex); var messageHash = Crypto.SHA256(data); var messageSign = Bitcoin.ECDSA.sign(messageHash, key.priv); @@ -129,7 +129,7 @@ } //Verify signatue of the data using public-key - floCrypto.verifySign = function(data, signatureHex, publicKeyHex) { + floCrypto.verifySign = function (data, signatureHex, publicKeyHex) { var msgHash = Crypto.SHA256(data); var sigBytes = Crypto.util.hexToBytes(signatureHex); var publicKeyPoint = ecparams.getCurve().decodePointHex(publicKeyHex); @@ -138,7 +138,7 @@ } //Generates a new flo ID and returns private-key, public-key and floID - const generateNewID = floCrypto.generateNewID = function() { + const generateNewID = floCrypto.generateNewID = function () { var key = new Bitcoin.ECKey(false); key.setCompressed(true); return { @@ -168,7 +168,7 @@ }); //Returns public-key from private-key - floCrypto.getPubKeyHex = function(privateKeyHex) { + floCrypto.getPubKeyHex = function (privateKeyHex) { if (!privateKeyHex) return null; var key = new Bitcoin.ECKey(privateKeyHex); @@ -179,7 +179,7 @@ } //Returns flo-ID from public-key or private-key - floCrypto.getFloID = function(keyHex) { + floCrypto.getFloID = function (keyHex) { if (!keyHex) return null; try { @@ -192,7 +192,7 @@ } } - floCrypto.getAddress = function(privateKeyHex, strict = false) { + floCrypto.getAddress = function (privateKeyHex, strict = false) { if (!privateKeyHex) return; var key = new Bitcoin.ECKey(privateKeyHex); @@ -212,7 +212,7 @@ } //Verify the private-key for the given public-key or flo-ID - floCrypto.verifyPrivKey = function(privateKeyHex, pubKey_floID, isfloID = true) { + floCrypto.verifyPrivKey = function (privateKeyHex, pubKey_floID, isfloID = true) { if (!privateKeyHex || !pubKey_floID) return false; try { @@ -232,7 +232,7 @@ } //Check if the given flo-id is valid or not - floCrypto.validateFloID = function(floID) { + floCrypto.validateFloID = function (floID) { if (!floID) return false; try { @@ -244,7 +244,7 @@ } //Check if the given address (any blockchain) is valid or not - floCrypto.validateAddr = function(address, std = true, bech = true) { + floCrypto.validateAddr = function (address, std = true, bech = true) { let raw = decodeAddress(address); if (!raw) return false; @@ -267,7 +267,7 @@ } //Check the public-key for the address (any blockchain) - floCrypto.verifyPubKey = function(pubKeyHex, address) { + floCrypto.verifyPubKey = function (pubKeyHex, address) { let raw = decodeAddress(address), pub_hash = Crypto.util.bytesToHex(ripemd160(Crypto.SHA256(Crypto.util.hexToBytes(pubKeyHex), { asBytes: true @@ -276,12 +276,18 @@ } //Convert the given address (any blockchain) to equivalent floID - floCrypto.toFloID = function(address) { + floCrypto.toFloID = function (address, options = null) { if (!address) return; let raw = decodeAddress(address); if (!raw) return; + else if (options) { + if (typeof raw.version !== 'undefined' && (!options.std || !options.std.includes(raw.version))) + return; + if (typeof raw.bech_version !== 'undefined' && (!options.bech || !options.bech.includes(raw.bech_version))) + return; + } raw.bytes.unshift(bitjs.pub); let hash = Crypto.SHA256(Crypto.SHA256(raw.bytes, { asBytes: true @@ -292,7 +298,7 @@ } //Checks if the given addresses (any blockchain) are same (w.r.t keys) - floCrypto.isSameAddr = function(addr1, addr2) { + floCrypto.isSameAddr = function (addr1, addr2) { if (!addr1 || !addr2) return; let raw1 = decodeAddress(addr1), @@ -303,7 +309,7 @@ return raw1.hex === raw2.hex; } - const decodeAddress = floCrypto.decodeAddr = function(address) { + const decodeAddress = floCrypto.decodeAddr = function (address) { if (!address) return; else if (address.length == 33 || address.length == 34) { //legacy encoding @@ -338,7 +344,7 @@ } //Split the str using shamir's Secret and Returns the shares - floCrypto.createShamirsSecretShares = function(str, total_shares, threshold_limit) { + floCrypto.createShamirsSecretShares = function (str, total_shares, threshold_limit) { try { if (str.length > 0) { var strHex = shamirSecretShare.str2hex(str); @@ -352,7 +358,7 @@ } //Returns the retrived secret by combining the shamirs shares - const retrieveShamirSecret = floCrypto.retrieveShamirSecret = function(sharesArray) { + const retrieveShamirSecret = floCrypto.retrieveShamirSecret = function (sharesArray) { try { if (sharesArray.length > 0) { var comb = shamirSecretShare.combine(sharesArray.slice(0, sharesArray.length)); @@ -366,7 +372,7 @@ } //Verifies the shares and str - floCrypto.verifyShamirsSecret = function(sharesArray, str) { + floCrypto.verifyShamirsSecret = function (sharesArray, str) { if (!str) return null; else if (retrieveShamirSecret(sharesArray) === str) @@ -375,7 +381,7 @@ return false; } - const validateASCII = floCrypto.validateASCII = function(string, bool = true) { + const validateASCII = floCrypto.validateASCII = function (string, bool = true) { if (typeof string !== "string") return null; if (bool) { @@ -393,8 +399,8 @@ if (x < 32 || x > 127) if (x in invalids) invalids[string[i]].push(i) - else - invalids[string[i]] = [i]; + else + invalids[string[i]] = [i]; } if (Object.keys(invalids).length) return invalids; @@ -403,7 +409,7 @@ } } - floCrypto.convertToASCII = function(string, mode = 'soft-remove') { + floCrypto.convertToASCII = function (string, mode = 'soft-remove') { let chars = validateASCII(string, false); if (chars === true) return string; @@ -414,9 +420,9 @@ ascii_alternatives.split('\n').forEach(a => refAlt[a[0]] = a.slice(2)); mode = mode.toLowerCase(); if (mode === "hard-unicode") - convertor = (c) => `\\u${('000'+c.charCodeAt().toString(16)).slice(-4)}`; + convertor = (c) => `\\u${('000' + c.charCodeAt().toString(16)).slice(-4)}`; else if (mode === "soft-unicode") - convertor = (c) => refAlt[c] || `\\u${('000'+c.charCodeAt().toString(16)).slice(-4)}`; + convertor = (c) => refAlt[c] || `\\u${('000' + c.charCodeAt().toString(16)).slice(-4)}`; else if (mode === "hard-remove") convertor = c => ""; else if (mode === "soft-remove") @@ -428,7 +434,7 @@ return result; } - floCrypto.revertUnicode = function(string) { + floCrypto.revertUnicode = function (string) { return string.replace(/\\u[\dA-F]{4}/gi, m => String.fromCharCode(parseInt(m.replace(/\\u/g, ''), 16))); }