From 34c30aea05c6df6c2f0af9aed1d80fa7328614e9 Mon Sep 17 00:00:00 2001 From: sairajzero Date: Thu, 1 Jun 2023 20:03:42 +0530 Subject: [PATCH 1/9] btcOperator v1.1.3: increase fee - editFee: increase the fee for the given transaction. can pass either tx hex directly to edit it, or pass txid of unconfirmed tx to edit it for rebroadcasting - transaction outputs will be removed if the value is less than DUST amount (546 satoshi) --- btcOperator.js | 114 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 107 insertions(+), 7 deletions(-) diff --git a/btcOperator.js b/btcOperator.js index ff86fb9..f61f605 100644 --- a/btcOperator.js +++ b/btcOperator.js @@ -1,10 +1,12 @@ -(function (EXPORTS) { //btcOperator v1.1.2a +(function (EXPORTS) { //btcOperator v1.1.3 /* BTC Crypto and API Operator */ const btcOperator = EXPORTS; //This library uses API provided by chain.so (https://chain.so/) const URL = "https://blockchain.info/"; + const DUST_AMT = 546; + const fetch_api = btcOperator.fetch = function (api, json_res = true) { return new Promise((resolve, reject) => { console.debug(URL + api); @@ -400,7 +402,7 @@ return reject("Send amount is less than fee"); } - tx.outs = tx.outs.filter(o => o.value != 0); //remove all output with value 0 + tx.outs = tx.outs.filter(o => o.value <= DUST_AMT); //remove all output with value less than DUST amount result.output_size = output_size; result.output_amount = total_amount - (fee_from_receiver ? result.fee : 0); result.total_size = BASE_TX_SIZE + output_size + result.input_size; @@ -456,7 +458,7 @@ let size_per_input = _sizePerInput(addr, rs); fetch_api(`unspent?active=${addr}`).then(result => { let utxos = result.unspent_outputs; - console.debug("add-utxo", addr, rs, required_amount, utxos); + //console.debug("add-utxo", addr, rs, required_amount, utxos); for (let i = 0; i < utxos.length && required_amount > 0; i++) { if (!utxos[i].confirmations) //ignore unconfirmed utxo continue; @@ -536,6 +538,104 @@ } */ + function tx_fetch_for_editing(tx) { + return new Promise((resolve, reject) => { + if (typeof tx == 'string' && /^[0-9a-f]{64}$/i.test(tx)) { //tx is txid + getTx.hex(tx) + .then(txhex => resolve(deserializeTx(txhex))) + .catch(error => reject(error)) + } else resolve(deserializeTx(tx)); + }) + } + + + btcOperator.editFee = function (tx_hex, new_fee, private_keys, change_only = true) { + return new Promise((resolve, reject) => { + if (!Array.isArray(private_keys)) + private_keys = [private_keys]; + tx_fetch_for_editing(tx_hex).then(tx => { + parseTransaction(tx).then(tx_parsed => { + if (tx_parsed.fee >= new_fee) + return reject("Fees can only be increased"); + + //editable addresses in output values (for fee increase) + var edit_output_address = new Set(); + if (change_only === true) //allow only change values (ie, sender address) to be edited to inc fee + tx_parsed.inputs.forEach(inp => edit_output_address.add(inp.address)); + else if (change_only === false) //allow all output values to be edited + tx_parsed.outputs.forEach(out => edit_output_address.add(out.address)); + else if (typeof change_only == 'string') // allow only given receiver id output to be edited + edit_output_address.add(change_only); + else if (Array.isArray(change_only)) //allow only given set of receiver id outputs to be edited + change_only.forEach(id => edit_output_address.add(id)); + + //edit output values to increase fee + let inc_fee = util.BTC_to_Sat(new_fee - tx_parsed.fee); + for (let i = tx.outs.length - 1; i >= 0 && inc_fee > 0; i--) //reduce in reverse order + if (edit_output_address.has(tx_parsed.outputs[i].address)) { + let current_value = tx.outs[i].value; + if (current_value instanceof BigInteger) //convert BigInteger class to inv value + current_value = current_value.intValue(); + //edit the value as required + if (current_value > inc_fee) { + tx.out[i].value = current_value - inc_fee; + inc_fee = 0; + } else { + inc_fee -= current_value; + tx.out[i].value = 0; + } + } + if (inc_fee > 0) { + let max_possible_fee = util.BTC_to_Sat(new_fee) - inc_fee; //in satoshi + return reject(`Insufficient output values to increase fee. Maximum fee possible: ${util.Sat_to_BTC(max_possible_fee)}`); + } + tx.outs = tx.outs.filter(o => o.value <= DUST_AMT); //remove all output with value less than DUST amount + + //remove existing signatures and reset the scripts + let wif_keys = []; + for (let i in tx.ins) { + var addr = tx_parsed.inputs[i].address, + value = util.BTC_to_Sat(tx_parsed.inputs[i].value); + let addr_decode = coinjs.addressDecode(addr); + //find the correct key for addr + var privKey = private_keys.find(pk => verifyKey(addr, pk)); + if (!privKey) + return reject(`Private key missing for ${addr}`); + //find redeemScript (if any) + const rs = _redeemScript(addr, privKey); + rs === false ? wif_keys.unshift(privKey) : wif_keys.push(privKey); //sorting private-keys (wif) + //reset the script for re-signing + var script; + if (!rs || !rs.length) { + //legacy script (derive from address) + let s = coinjs.script(); + s.writeOp(118); //OP_DUP + s.writeOp(169); //OP_HASH160 + s.writeBytes(addr_decode.bytes); + s.writeOp(136); //OP_EQUALVERIFY + s.writeOp(172); //OP_CHECKSIG + script = Crypto.util.bytesToHex(s.buffer); + } else if (((rs.match(/^00/) && rs.length == 44)) || (rs.length == 40 && rs.match(/^[a-f0-9]+$/gi)) || addr_decode.type === 'multisigBech32') { + //redeemScript for segwit/bech32 and multisig (bech32) + let s = coinjs.script(); + s.writeBytes(Crypto.util.hexToBytes(rs)); + s.writeOp(0); + s.writeBytes(coinjs.numToBytes(value.toFixed(0), 8)); + script = Crypto.util.bytesToHex(s.buffer); + } else //redeemScript for multisig (segwit) + script = rs; + tx.ins[i].script = coinjs.script(script); + } + tx.witness = false; //remove all witness signatures + console.debug("Unsigned:", tx.serialize()); + //re-sign the transaction + new Set(wif_keys).forEach(key => tx.sign(key, 1 /*sighashtype*/)); //Sign the tx using private key WIF + resolve(tx.serialize()); + }).catch(error => reject(error)) + }).catch(error => reject(error)) + }) + } + btcOperator.sendTx = function (senders, privkeys, receivers, amounts, fee = null, options = {}) { return new Promise((resolve, reject) => { createSignedTx(senders, privkeys, receivers, amounts, fee, options).then(result => { @@ -579,7 +679,7 @@ createTransaction(senders, redeemScripts, receivers, amounts, fee, options.change_address || senders[0], options.fee_from_receiver).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 => tx.sign(key, 1 /*sighashtype*/)); //Sign the tx using private key WIF console.debug("Signed:", tx.serialize()); resolve(result); }).catch(error => reject(error)); @@ -723,7 +823,7 @@ .catch(error => reject(error)) }); - btcOperator.parseTransaction = function (tx) { + const parseTransaction = btcOperator.parseTransaction = function (tx) { return new Promise((resolve, reject) => { tx = deserializeTx(tx); let result = {}; @@ -780,7 +880,7 @@ .catch(error => reject(error)) }) - btcOperator.getTx = txid => new Promise((resolve, reject) => { + const getTx = btcOperator.getTx = txid => new Promise((resolve, reject) => { fetch_api(`rawtx/${txid}`).then(result => { getLatestBlock().then(latest_block => resolve({ block: result.block_height, @@ -797,7 +897,7 @@ }).catch(error => reject(error)) }); - btcOperator.getTx.hex = txid => new Promise((resolve, reject) => { + getTx.hex = txid => new Promise((resolve, reject) => { fetch_api(`rawtx/${txid}?format=hex`, false) .then(result => resolve(result)) .catch(error => reject(error)) From 365d3d450324958bbe654f83c6d4d44a34aaa882 Mon Sep 17 00:00:00 2001 From: sairajzero Date: Thu, 1 Jun 2023 21:06:04 +0530 Subject: [PATCH 2/9] btcOperator v1.1.3a: bug fix - Fixed: minor syntax errors and typos - Fixed: createTransaction not giving correct fee and output value when dust is ignored --- btcOperator.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/btcOperator.js b/btcOperator.js index f61f605..6d45a62 100644 --- a/btcOperator.js +++ b/btcOperator.js @@ -1,4 +1,4 @@ -(function (EXPORTS) { //btcOperator v1.1.3 +(function (EXPORTS) { //btcOperator v1.1.3a /* BTC Crypto and API Operator */ const btcOperator = EXPORTS; @@ -402,7 +402,12 @@ return reject("Send amount is less than fee"); } - tx.outs = tx.outs.filter(o => o.value <= DUST_AMT); //remove all output with value less than DUST amount + //remove all output with value less than DUST amount + let filtered_outputs = [], dust_value = 0; + tx.outs.forEach(o => o.value >= DUST_AMT ? filtered_outputs.push(o) : dust_value += o.value); + tx.outs = filtered_outputs; + //update result values + result.fee += util.Sat_to_BTC(dust_value); result.output_size = output_size; result.output_amount = total_amount - (fee_from_receiver ? result.fee : 0); result.total_size = BASE_TX_SIZE + output_size + result.input_size; @@ -578,18 +583,18 @@ current_value = current_value.intValue(); //edit the value as required if (current_value > inc_fee) { - tx.out[i].value = current_value - inc_fee; + tx.outs[i].value = current_value - inc_fee; inc_fee = 0; } else { inc_fee -= current_value; - tx.out[i].value = 0; + tx.outs[i].value = 0; } } if (inc_fee > 0) { let max_possible_fee = util.BTC_to_Sat(new_fee) - inc_fee; //in satoshi return reject(`Insufficient output values to increase fee. Maximum fee possible: ${util.Sat_to_BTC(max_possible_fee)}`); } - tx.outs = tx.outs.filter(o => o.value <= DUST_AMT); //remove all output with value less than DUST amount + tx.outs = tx.outs.filter(o => o.value >= DUST_AMT); //remove all output with value less than DUST amount //remove existing signatures and reset the scripts let wif_keys = []; From 49d5c2411c28a8781f2abc1f80974d8bade34d35 Mon Sep 17 00:00:00 2001 From: sairajzero Date: Thu, 1 Jun 2023 21:09:50 +0530 Subject: [PATCH 3/9] btcOperator v1.1.3b: fix - Fixed: fee increment minimum value Minimum fee increment should be atleast MIN_FEE_UPDATE (219 satoshi) --- btcOperator.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/btcOperator.js b/btcOperator.js index 6d45a62..2abb80f 100644 --- a/btcOperator.js +++ b/btcOperator.js @@ -1,11 +1,12 @@ -(function (EXPORTS) { //btcOperator v1.1.3a +(function (EXPORTS) { //btcOperator v1.1.3b /* BTC Crypto and API Operator */ const btcOperator = EXPORTS; //This library uses API provided by chain.so (https://chain.so/) const URL = "https://blockchain.info/"; - const DUST_AMT = 546; + const DUST_AMT = 546, + MIN_FEE_UPDATE = 219; const fetch_api = btcOperator.fetch = function (api, json_res = true) { return new Promise((resolve, reject) => { @@ -576,6 +577,8 @@ //edit output values to increase fee let inc_fee = util.BTC_to_Sat(new_fee - tx_parsed.fee); + if (inc_fee < MIN_FEE_UPDATE) + return reject(`Insufficient additional fee. Minimum increment: ${MIN_FEE_UPDATE}`); for (let i = tx.outs.length - 1; i >= 0 && inc_fee > 0; i--) //reduce in reverse order if (edit_output_address.has(tx_parsed.outputs[i].address)) { let current_value = tx.outs[i].value; From d15af057647472d6e4a592ee6c0b1ebb8412aae3 Mon Sep 17 00:00:00 2001 From: sairajzero Date: Tue, 4 Jul 2023 00:20:24 +0530 Subject: [PATCH 4/9] floBlockchainAPI v3.0.0: BlockBook API - Converting API calls to FLO blockbook API - Changes and fixes required for the same --- floBlockchainAPI.js | 271 +++++++++++++++++++------------------------- 1 file changed, 117 insertions(+), 154 deletions(-) diff --git a/floBlockchainAPI.js b/floBlockchainAPI.js index 6fec5b8..589279f 100644 --- a/floBlockchainAPI.js +++ b/floBlockchainAPI.js @@ -1,13 +1,13 @@ -(function (EXPORTS) { //floBlockchainAPI v2.5.6b - /* FLO Blockchain Operator to send/receive data from blockchain using API calls*/ +(function (EXPORTS) { //floBlockchainAPI v3.0.0 + /* FLO Blockchain Operator to send/receive data from blockchain using API calls via FLO Blockbook*/ 'use strict'; const floBlockchainAPI = EXPORTS; const DEFAULT = { blockchain: floGlobals.blockchain, apiURL: { - FLO: ['https://flosight.ranchimall.net/'], - FLO_TEST: ['https://flosight-testnet.ranchimall.net/'] + FLO: ['https://blockbook.ranchimall.net/'], + FLO_TEST: [] }, sendAmt: 0.0003, fee: 0.0002, @@ -61,9 +61,9 @@ var serverList = Array.from(allServerList); var curPos = floCrypto.randInt(0, serverList.length - 1); - function fetch_retry(apicall, rm_flosight) { + function fetch_retry(apicall, rm_node) { return new Promise((resolve, reject) => { - let i = serverList.indexOf(rm_flosight) + let i = serverList.indexOf(rm_node) if (i != -1) serverList.splice(i, 1); curPos = floCrypto.randInt(0, serverList.length - 1); fetch_api(apicall, false) @@ -82,19 +82,19 @@ .then(result => resolve(result)) .catch(error => reject(error)); } else - reject("No floSight server working"); + reject("No FLO blockbook server working"); } else { - let flosight = serverList[curPos]; - fetch(flosight + apicall).then(response => { + let serverURL = serverList[curPos]; + fetch(serverURL + apicall).then(response => { if (response.ok) response.json().then(data => resolve(data)); else { - fetch_retry(apicall, flosight) + fetch_retry(apicall, serverURL) .then(result => resolve(result)) .catch(error => reject(error)); } }).catch(error => { - fetch_retry(apicall, flosight) + fetch_retry(apicall, serverURL) .then(result => resolve(result)) .catch(error => reject(error)); }) @@ -124,43 +124,27 @@ } //Get balance for the given Address - const getBalance = floBlockchainAPI.getBalance = function (addr, after = null) { + const getBalance = floBlockchainAPI.getBalance = function (addr) { return new Promise((resolve, reject) => { - let api = `api/addr/${addr}/balance`, query_params = {}; - if (after) { - if (typeof after === 'string' && /^[0-9a-z]{64}$/i.test(after)) - query_params.after = after; - else return reject("Invalid 'after' parameter"); - } - promisedAPI(api, query_params).then(result => { - if (typeof result === 'object' && result.lastItem) { - getBalance(addr, result.lastItem) - .then(r => resolve(util.toFixed(r + result.data))) - .catch(error => reject(error)) - } else resolve(result); - }).catch(error => reject(error)) + let api = `api/address/${addr}`; + promisedAPI(api, { details: "basic" }) + .then(result => resolve(result["balance"])) + .catch(error => reject(error)) }); } - const getUTXOs = address => new Promise((resolve, reject) => { - promisedAPI(`api/addr/${address}/utxo`) - .then(utxo => resolve(utxo)) - .catch(error => reject(error)) - }) + function getScriptPubKey(address) { + var tx = bitjs.transaction(); + tx.addoutput(address, 0); + let outputBuffer = tx.outputs.pop().script; + return Crypto.util.bytesToHex(outputBuffer) + } - const getUnconfirmedSpent = address => new Promise((resolve, reject) => { - readTxs(address, { mempool: "only" }).then(result => { - let unconfirmedSpent = {}; - for (let tx of result.items) - if (tx.confirmations == 0) - for (let vin of tx.vin) - if (vin.addr === address) { - if (Array.isArray(unconfirmedSpent[vin.txid])) - unconfirmedSpent[vin.txid].push(vin.vout); - else - unconfirmedSpent[vin.txid] = [vin.vout]; - } - resolve(unconfirmedSpent); + const getUTXOs = address => new Promise((resolve, reject) => { + promisedAPI(`api/utxo/${address}`, { confirmed: true }).then(utxos => { + let scriptPubKey = getScriptPubKey(address); + utxos.forEach(u => u.scriptPubKey = scriptPubKey); + resolve(utxos); }).catch(error => reject(error)) }) @@ -180,32 +164,28 @@ var fee = DEFAULT.fee; if (balance < sendAmt + fee) return reject("Insufficient FLO balance!"); - getUnconfirmedSpent(senderAddr).then(unconfirmedSpent => { - getUTXOs(senderAddr).then(utxos => { - //form/construct the transaction data - var trx = bitjs.transaction(); - var utxoAmt = 0.0; - for (var i = utxos.length - 1; - (i >= 0) && (utxoAmt < sendAmt + fee); i--) { - //use only utxos with confirmations (strict_utxo mode) - if (utxos[i].confirmations || !strict_utxo) { - if (utxos[i].txid in unconfirmedSpent && unconfirmedSpent[utxos[i].txid].includes(utxos[i].vout)) - continue; //A transaction has already used the utxo, but is unconfirmed. - trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i].scriptPubKey); - utxoAmt += utxos[i].amount; - }; - } - if (utxoAmt < sendAmt + fee) - reject("Insufficient FLO: Some UTXOs are unconfirmed"); - else { - trx.addoutput(receiverAddr, sendAmt); - var change = utxoAmt - sendAmt - fee; - if (change > DEFAULT.minChangeAmt) - trx.addoutput(senderAddr, change); - trx.addflodata(floData.replace(/\n/g, ' ')); - resolve(trx); - } - }).catch(error => reject(error)) + getUTXOs(senderAddr).then(utxos => { + //form/construct the transaction data + var trx = bitjs.transaction(); + var utxoAmt = 0.0; + for (var i = utxos.length - 1; + (i >= 0) && (utxoAmt < sendAmt + fee); i--) { + //use only utxos with confirmations (strict_utxo mode) + if (utxos[i].confirmations || !strict_utxo) { + trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i].scriptPubKey); + utxoAmt += utxos[i].amount; + }; + } + if (utxoAmt < sendAmt + fee) + reject("Insufficient FLO: Some UTXOs are unconfirmed"); + else { + trx.addoutput(receiverAddr, sendAmt); + var change = utxoAmt - sendAmt - fee; + if (change > DEFAULT.minChangeAmt) + trx.addoutput(senderAddr, change); + trx.addflodata(floData.replace(/\n/g, ' ')); + resolve(trx); + } }).catch(error => reject(error)) }).catch(error => reject(error)) }) @@ -293,34 +273,30 @@ if (balance < totalAmt + fee) return reject("Insufficient FLO balance!"); //get unconfirmed tx list - getUnconfirmedSpent(floID).then(unconfirmedSpent => { - getUTXOs(floID).then(utxos => { - var trx = bitjs.transaction(); - var utxoAmt = 0.0; - for (let i = utxos.length - 1; (i >= 0) && (utxoAmt < totalAmt + fee); i--) { - //use only utxos with confirmations (strict_utxo mode) - if (utxos[i].confirmations || !strict_utxo) { - if (utxos[i].txid in unconfirmedSpent && unconfirmedSpent[utxos[i].txid].includes(utxos[i].vout)) - continue; //A transaction has already used the utxo, but is unconfirmed. - trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i].scriptPubKey); - utxoAmt += utxos[i].amount; - }; - } - if (utxoAmt < totalAmt + fee) - reject("Insufficient FLO: Some UTXOs are unconfirmed"); - else { - for (let i = 0; i < count; i++) - trx.addoutput(floID, splitAmt); - var change = utxoAmt - totalAmt - fee; - if (change > DEFAULT.minChangeAmt) - trx.addoutput(floID, change); - trx.addflodata(floData.replace(/\n/g, ' ')); - var signedTxHash = trx.sign(privKey, 1); - broadcastTx(signedTxHash) - .then(txid => resolve(txid)) - .catch(error => reject(error)) - } - }).catch(error => reject(error)) + getUTXOs(floID).then(utxos => { + var trx = bitjs.transaction(); + var utxoAmt = 0.0; + for (let i = utxos.length - 1; (i >= 0) && (utxoAmt < totalAmt + fee); i--) { + //use only utxos with confirmations (strict_utxo mode) + if (utxos[i].confirmations || !strict_utxo) { + trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i].scriptPubKey); + utxoAmt += utxos[i].amount; + }; + } + if (utxoAmt < totalAmt + fee) + reject("Insufficient FLO: Some UTXOs are unconfirmed"); + else { + for (let i = 0; i < count; i++) + trx.addoutput(floID, splitAmt); + var change = utxoAmt - totalAmt - fee; + if (change > DEFAULT.minChangeAmt) + trx.addoutput(floID, change); + trx.addflodata(floData.replace(/\n/g, ' ')); + var signedTxHash = trx.sign(privKey, 1); + broadcastTx(signedTxHash) + .then(txid => resolve(txid)) + .catch(error => reject(error)) + } }).catch(error => reject(error)) }).catch(error => reject(error)) }) @@ -551,33 +527,29 @@ var fee = DEFAULT.fee; if (balance < sendAmt + fee) return reject("Insufficient FLO balance!"); - getUnconfirmedSpent(senderAddr).then(unconfirmedSpent => { - getUTXOs(senderAddr).then(utxos => { - //form/construct the transaction data - var trx = bitjs.transaction(); - var utxoAmt = 0.0; - for (var i = utxos.length - 1; - (i >= 0) && (utxoAmt < sendAmt + fee); i--) { - //use only utxos with confirmations (strict_utxo mode) - if (utxos[i].confirmations || !strict_utxo) { - if (utxos[i].txid in unconfirmedSpent && unconfirmedSpent[utxos[i].txid].includes(utxos[i].vout)) - continue; //A transaction has already used the utxo, but is unconfirmed. - trx.addinput(utxos[i].txid, utxos[i].vout, redeemScript); //for multisig, script=redeemScript - utxoAmt += utxos[i].amount; - }; - } - if (utxoAmt < sendAmt + fee) - reject("Insufficient FLO: Some UTXOs are unconfirmed"); - else { - for (let i in receivers) - trx.addoutput(receivers[i], amounts[i]); - var change = utxoAmt - sendAmt - fee; - if (change > DEFAULT.minChangeAmt) - trx.addoutput(senderAddr, change); - trx.addflodata(floData.replace(/\n/g, ' ')); - resolve(trx); - } - }).catch(error => reject(error)) + getUTXOs(senderAddr).then(utxos => { + //form/construct the transaction data + var trx = bitjs.transaction(); + var utxoAmt = 0.0; + for (var i = utxos.length - 1; + (i >= 0) && (utxoAmt < sendAmt + fee); i--) { + //use only utxos with confirmations (strict_utxo mode) + if (utxos[i].confirmations || !strict_utxo) { + trx.addinput(utxos[i].txid, utxos[i].vout, redeemScript); //for multisig, script=redeemScript + utxoAmt += utxos[i].amount; + }; + } + if (utxoAmt < sendAmt + fee) + reject("Insufficient FLO: Some UTXOs are unconfirmed"); + else { + for (let i in receivers) + trx.addoutput(receivers[i], amounts[i]); + var change = utxoAmt - sendAmt - fee; + if (change > DEFAULT.minChangeAmt) + trx.addoutput(senderAddr, change); + trx.addflodata(floData.replace(/\n/g, ' ')); + resolve(trx); + } }).catch(error => reject(error)) }).catch(error => reject(error)) }); @@ -773,20 +745,11 @@ const broadcastTx = floBlockchainAPI.broadcastTx = function (signedTxHash) { return new Promise((resolve, reject) => { if (signedTxHash.length < 1) - return reject("Empty Signature"); - var url = serverList[curPos] + 'api/tx/send'; - fetch(url, { - method: "POST", - headers: { - 'Content-Type': 'application/json' - }, - body: `{"rawtx":"${signedTxHash}"}` - }).then(response => { - if (response.ok) - response.json().then(data => resolve(data.txid.result)); - else - response.text().then(data => resolve(data)); - }).catch(error => reject(error)); + return reject("Empty Transaction Data"); + + promisedAPI('/api/sendtx/' + signedTxHash) + .then(response => resolve(response["result"])) + .catch(error => reject(error)) }) } @@ -825,27 +788,27 @@ }) } - //Read Txs of Address between from and to + //Read Txs of Address const readTxs = floBlockchainAPI.readTxs = function (addr, options = {}) { return new Promise((resolve, reject) => { let api = `api/addrs/${addr}/txs`; //API options let query_params = {}; - if (!isUndefined(options.after) || !isUndefined(options.before)) { - if (!isUndefined(options.after)) - query_params.after = options.after; - if (!isUndefined(options.before)) - query_params.before = options.before; - } else { - if (!isUndefined(options.from)) - query_params.from = options.from; - if (!isUndefined(options.to)) - query_params.to = options.to; - } - if (!isUndefined(options.latest)) - query_params.latest = options.latest; - if (!isUndefined(options.mempool)) - query_params.mempool = options.mempool; + //page options + if (!isUndefined(options.page) && Number.isInteger(options.page)) + query_params.page = options.page; + if (!isUndefined(options.pageSize) && Number.isInteger(options.pageSize)) + query_params.pageSize = options.pageSize; + //only confirmed tx + if (options.confirmed) //Default is false in server, so only add confirmed filter if confirmed has a true value + query_params.confirmed = true; + //from block number + if (!isUndefined(options.fromBlock) && Number.isInteger(options.fromBlock)) + query_params.from = options.fromBlock; + //to block number + if (!isUndefined(options.toBlock) && Number.isInteger(options.toBlock)) + query_params.to = options.toBlock; + promisedAPI(api, query_params) .then(response => resolve(response)) .catch(error => reject(error)) From c1bbac92ea3ba67a09a92a08d002be391eebd3fb Mon Sep 17 00:00:00 2001 From: sairaj mote Date: Wed, 5 Jul 2023 03:08:23 +0530 Subject: [PATCH 5/9] New app name format --- docs/css/main.css | 34 ++++++++++++++++------------------ docs/css/main.min.css | 2 +- docs/css/main.scss | 34 ++++++++++++++++------------------ docs/index.html | 11 +++++++---- 4 files changed, 40 insertions(+), 41 deletions(-) diff --git a/docs/css/main.css b/docs/css/main.css index 74d3859..69bc0d7 100644 --- a/docs/css/main.css +++ b/docs/css/main.css @@ -453,24 +453,6 @@ ul { align-content: flex-start; } -.logo { - display: grid; - align-items: center; - grid-template-columns: auto 1fr; - gap: 0 0.3rem; - margin-right: auto; -} -.logo h4 { - text-transform: capitalize; - font-weight: 600; -} -.logo .main-logo { - height: 1.4rem; - width: 1.4rem; - fill: rgba(var(--text-color), 1); - stroke: none; -} - details:not(:last-of-type) { border-bottom: thin solid rgba(var(--text-color), 0.3); } @@ -683,6 +665,22 @@ sm-checkbox { align-items: center; } +.app-brand { + display: flex; + gap: 0.3rem; + align-items: center; +} +.app-brand .icon { + height: 1.7rem; + width: 1.7rem; +} + +.app-name__company { + font-size: 0.8rem; + font-weight: 500; + color: rgba(var(--text-color), 0.8); +} + #user_popup_button { background-color: rgba(var(--text-color), 0.06); border-radius: 2rem; diff --git a/docs/css/main.min.css b/docs/css/main.min.css index d14e003..abdbeb1 100644 --- a/docs/css/main.min.css +++ b/docs/css/main.min.css @@ -1 +1 @@ -*{padding:0;margin:0;box-sizing:border-box;font-family:"Roboto",sans-serif}:root{font-size:clamp(1rem,1.2vmax,1.2rem)}html,body{height:100%;scroll-behavior:smooth}body{--accent-color: #516beb;--text-color: 20, 20, 20;--foreground-color: 252, 253, 255;--background-color: 241, 243, 248;--danger-color: rgb(255, 75, 75);--green: #1cad59;--yellow: #bd7200;scrollbar-width:thin;scrollbar-gutter:stable;color:rgba(var(--text-color), 1);background-color:rgba(var(--background-color), 1);transition:background-color .3s}body[data-theme=dark]{--accent-color: #a4b3ff;--text-color: 220, 220, 220;--foreground-color: 27, 28, 29;--background-color: 21, 22, 22;--danger-color: rgb(255, 106, 106);--green: #00e676;--yellow: #ffeb3b}body[data-theme=dark] sm-popup::part(popup){background-color:rgba(var(--foreground-color), 1)}p,strong{font-size:.9rem;max-width:70ch;line-height:1.7;color:rgba(var(--text-color), 0.8)}p:not(:last-of-type),strong:not(:last-of-type){margin-bottom:1.5rem}a:where([class]){color:inherit;text-decoration:none}a:where([class]):focus-visible{box-shadow:0 0 0 .1rem rgba(var(--text-color), 1) inset}a{text-decoration:none;color:var(--accent-color)}a:focus-visible{box-shadow:0 0 0 .1rem rgba(var(--text-color), 1) inset}fieldset{border:none;padding:0;margin:0}button,.button{-webkit-user-select:none;-moz-user-select:none;user-select:none;position:relative;display:inline-flex;border:none;background-color:rgba(0,0,0,0);overflow:hidden;color:inherit;-webkit-tap-highlight-color:rgba(0,0,0,0);align-items:center;font-size:inherit;font-weight:500;white-space:nowrap;padding:.8rem;border-radius:.3rem;justify-content:center;flex-shrink:0}button:focus-visible,.button:focus-visible{outline:var(--accent-color) solid medium}button:not(:disabled),.button:not(:disabled){cursor:pointer}.button{background-color:rgba(var(--text-color), 0.02);border:solid thin rgba(var(--text-color), 0.06)}.button--primary{color:rgba(var(--background-color), 1);background-color:var(--accent-color)}.button--primary .icon{fill:rgba(var(--background-color), 1)}.button--colored{color:var(--accent-color)}.button--colored .icon{fill:var(--accent-color)}.button--danger{background-color:rgba(255,115,115,.062745098);color:var(--danger-color)}.button--danger .icon{fill:var(--danger-color)}.button--small{padding:.4rem .6rem}.button--outlined{border:solid rgba(var(--text-color), 0.3) .1rem;background-color:rgba(var(--foreground-color), 1)}.button--transparent{background-color:rgba(0,0,0,0)}button:disabled{opacity:.4;cursor:not-allowed;filter:saturate(0)}.cta{text-transform:uppercase;font-size:.8rem;font-weight:700;letter-spacing:.05em;padding:.8rem 1rem}a:-webkit-any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:-moz-any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}input{accent-color:var(--accent-color)}sm-input{font-size:.9rem;--border-radius: 0.3rem}sm-form{--gap: 1rem}sm-copy{font-size:.9rem}ul{list-style:none}.hidden{display:none !important}.overflow-ellipsis{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.wrap-around{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-webkit-hyphens:auto;hyphens:auto}.sticky{position:-webkit-sticky;position:sticky;top:0;z-index:1}.full-bleed{grid-column:1/4}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.flex{display:flex}.flex-1{flex:1}.flex-wrap{flex-wrap:wrap}.flex-direction-column{flex-direction:column}.grid{display:grid}.grid-3{grid-template-columns:1fr auto auto}.flow-column{grid-auto-flow:column}.gap-0-3{gap:.3rem}.gap-0-5{gap:.5rem}.gap-1{gap:1rem}.gap-1-5{gap:1.5rem}.gap-2{gap:2rem}.gap-3{gap:3rem}.text-align-right{text-align:right}.align-start{align-items:flex-start}.align-center{align-items:center}.text-center{text-align:center}.justify-start{justify-content:start}.justify-center{justify-content:center}.justify-right{margin-left:auto}.align-self-center{align-self:center}.justify-self-center{justify-self:center}.justify-self-start{justify-self:start}.justify-self-end{justify-self:end}.space-between{justify-content:space-between}.w-100{width:100%}.interact{position:relative;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0)}.ripple{height:8rem;width:8rem;position:absolute;border-radius:50%;transform:scale(0);background:radial-gradient(circle, rgba(var(--text-color), 0.3) 0%, rgba(0, 0, 0, 0) 50%);pointer-events:none}.icon{width:1.2rem;height:1.2rem;fill:rgba(var(--text-color), 0.8)}.margin-right-0-5{margin-right:.5rem}.margin-right-auto{margin-right:auto}.margin-left-0-5{margin-left:.5rem}.margin-left-auto{margin-left:auto}.icon-only{padding:.5rem;aspect-ratio:1/1;background-color:rgba(0,0,0,0)}.icon-button{padding:.6rem;border-radius:.8rem;background-color:var(--accent-color--light);height:-webkit-max-content;height:-moz-max-content;height:max-content}.icon-button .icon{fill:var(--accent-color)}.empty-state{display:grid;text-align:center;justify-items:center;width:100%;max-width:none;padding:1.5rem}.empty-state__icon{height:3rem;width:3rem;padding:.6rem;border-radius:1rem;background-color:rgba(var(--text-color), 0.06);margin-bottom:1rem}.observe-empty-state:empty{display:none !important}.observe-empty-state:not(:empty)+.empty-state{display:none !important}#confirmation_popup,#prompt_popup{flex-direction:column}#confirmation_popup h4,#prompt_popup h4{font-size:1.2rem;margin-bottom:1rem}#confirmation_popup .flex,#prompt_popup .flex{margin-top:1rem}#prompt_message{margin-bottom:1.5rem}.popup__header{display:grid;gap:.5rem;width:100%;padding:0 1.5rem;align-items:center;justify-items:flex-start}.popup__header__close{padding:.5rem;margin-left:-0.5rem}#main_page{padding:1.5rem}#main_page>section:nth-of-type(1){align-content:flex-start}.logo{display:grid;align-items:center;grid-template-columns:auto 1fr;gap:0 .3rem;margin-right:auto}.logo h4{text-transform:capitalize;font-weight:600}.logo .main-logo{height:1.4rem;width:1.4rem;fill:rgba(var(--text-color), 1);stroke:none}details:not(:last-of-type){border-bottom:thin solid rgba(var(--text-color), 0.3)}details summary{display:flex;justify-content:space-between;-webkit-user-select:none;-moz-user-select:none;user-select:none;cursor:pointer;padding:1rem 0}details .icon{flex-shrink:0}details[open]{padding-bottom:1rem}details[open] summary .icon{transform:rotate(180deg)}sm-chips{--gap: 0;background-color:rgba(var(--text-color), 0.06);border-radius:.2rem}sm-chip{position:relative;font-size:.9rem;--border-radius: 0.5rem;--padding: 0.5rem 0.8rem;--background: rgba(var(--text-color), 0.06);-webkit-user-select:none;-moz-user-select:none;user-select:none;font-weight:500}sm-chip[selected]{--background: var(--accent-color);color:rgba(var(--background-color), 1)}sm-chip:first-of-type{--border-radius: 0.3rem 0 0 0.3rem}sm-chip:last-of-type{--border-radius: 0 0.3rem 0.3rem 0}sm-checkbox{--height: 1rem;--width: 1rem;-webkit-tap-highlight-color:rgba(0,0,0,0)}.warning{background-color:khaki;color:rgba(0,0,0,.7);padding:1rem;border-radius:.5rem;line-height:1.5}.tip{border-radius:1.5rem;background-color:rgba(var(--text-color), 0.06);padding:.3rem .8rem;font-size:.85rem}.tip .icon{fill:var(--accent-color);flex-shrink:0}.tooltip{display:flex;position:relative;z-index:8;cursor:pointer}.tooltip .banner{position:absolute;right:0;top:100%;width:min(20rem,100vw - 1rem);display:none;font-size:.9rem;background-color:rgba(var(--foreground-color), 1);padding:1rem;border-radius:.5rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.1);border:solid thin rgba(var(--text-color), 0.2)}.tooltip:hover .banner{display:block}.page-layout{display:grid;grid-template-columns:1.5rem minmax(0, 1fr) 1.5rem}.page-layout>*{grid-column:2/3}.page{height:100%}.mobile-page{align-items:flex-start}#loading .rm-logo{height:3rem;width:3rem;padding:.8rem;background-color:rgba(var(--text-color), 0.06);border-radius:5rem;justify-self:center}#landing{grid-template-rows:auto 1fr}#landing header{padding:1.5rem 0}#landing>.grid{align-content:flex-start;text-align:center;gap:1rem}#sign_up{grid-template-rows:auto 1fr;align-items:center}#sign_up section{margin-top:-6rem;justify-self:center;width:min(24rem,100%)}#sign_up header{padding:1.5rem 0}#sign_up .h2{margin-bottom:.5rem}#sign_up h5{font-weight:500;color:rgba(var(--text-color), 0.8)}#sign_up .warning{margin-top:2rem}.loader-button-wrapper{display:grid;text-align:center}.loader-button-wrapper>*{grid-area:1/1/2/2}.loader-button-wrapper button{z-index:1}.loader-button-wrapper sm-spinner{justify-self:center;align-self:center}#home{height:100%;display:flex;flex-direction:column;align-items:flex-start;align-content:flex-start}#login_section{display:flex;width:100%}#login_form__priv_key{margin-top:1rem}#flo_id_warning{padding-bottom:1.5rem}#flo_id_warning .icon{height:3rem;width:3rem;padding:.8rem;overflow:visible;background-color:#ffc107;border-radius:3rem;fill:rgba(0,0,0,.8)}#main_header{display:flex;flex-wrap:wrap;gap:1rem;padding:1rem 1.5rem;width:100%;align-items:center}#user_popup_button{background-color:rgba(var(--text-color), 0.06);border-radius:2rem;font-size:.8rem}#main_navbar{width:100%}.main_navbar__item{display:flex;flex-direction:column;align-items:center;flex:1;padding:.5rem 0}.main_navbar__item .item__title,.main_navbar__item .icon{transition:transform .3s cubic-bezier(0.175, 0.885, 0.32, 1.275),opacity .3s}.main_navbar__item .item__title{color:rgba(var(--text-color), 0.8);font-size:.8rem;font-weight:500}.main_navbar__item .icon{height:1.2rem;margin-bottom:.3rem}.main_navbar__item--active .item__title{color:var(--accent-color)}.main_navbar__item--active .icon{fill:var(--accent-color)}#pages_container{display:flex;flex:1;width:100%;height:100%;justify-content:center;overflow-y:auto}#pages_container>*{padding:0 1.5rem;min-width:min(26rem,100%)}.listed-asset{position:relative;gap:.5rem;padding:1rem 0;border-radius:.5rem;font-weight:400;transition:background-color .3s;-webkit-user-select:none;-moz-user-select:none;user-select:none;color:inherit;grid-template-columns:auto 1fr auto auto;grid-template-areas:"icon name rate right-arrow" "icon name countdown right-arrow"}.listed-asset__icon{grid-area:icon;padding:.5rem;border-radius:1rem;display:flex;background-color:var(--accent-color)}.listed-asset__icon .icon{height:1.2rem;width:1.2rem;fill:rgba(var(--background-color), 1)}.listed-asset__name{grid-area:name;margin-left:.3rem}.listed-asset__rate{grid-area:rate}.listed-asset__countdown{display:flex;align-items:center;grid-area:countdown;justify-self:flex-end;font-size:.8rem;color:var(--accent-color)}.listed-asset__countdown .icon{margin-left:.3rem;overflow:visible;stroke-width:3;fill:none}.listed-asset__countdown .icon .path-a{stroke:var(--accent-color);stroke-dashoffset:var(--path-length, 0);stroke-dasharray:63}.listed-asset__countdown .icon .path-b{stroke:rgba(var(--text-color), 0.2)}.listed-asset__right-arrow{grid-area:right-arrow;background-color:rgba(var(--text-color), 0.1);border-radius:1rem;padding:.1rem;margin-left:.3rem}.quantity-selector .button{flex:1;padding:.5rem .6rem;margin-left:.5rem}#quantity_selector_tip::first-letter{text-transform:uppercase}#quantity_type,#portfolio_quantity_type{font-size:.8rem;padding-right:.5rem;border-right:thin solid rgba(var(--text-color), 0.3);margin-right:auto;color:rgba(var(--text-color), 0.8);line-height:1.5;font-weight:500;min-width:8ch}#exchange_wrapper{display:flex;flex-direction:column;height:100%}#asset_page{position:relative;display:flex;flex-direction:column;height:100%;align-items:flex-start}#asset_page_wrapper{display:flex;flex-direction:column;height:100%;width:100%}#trade_form{height:100%}#trade_form::part(form){display:flex;flex-direction:column;gap:0}#trade_form>*{margin-bottom:1rem}#trade_form>:last-child{margin-top:auto}#my_orders,#market{width:min(46rem,100%);height:-webkit-max-content;height:-moz-max-content;height:max-content}#my_orders{grid-template-rows:auto 1fr}.orders_section__header{min-height:2.8rem;position:-webkit-sticky;position:sticky;top:0;background-color:rgba(var(--background-color), 1);z-index:2;transition:background-color .3s}.list__item{padding:.5rem 0;display:grid}.order-card{position:relative;outline:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;align-items:center;gap:.5rem;grid-template-columns:-webkit-min-content 1fr auto;grid-template-columns:min-content 1fr auto;border-radius:.5rem;grid-template-areas:"checkbox quantity quantity time" "checkbox price amount cancel"}.order-card>.grid:nth-of-type(2){grid-area:price}.order-card>.grid:nth-of-type(3){grid-area:amount}.order-card__type{font-size:.9rem;font-weight:500;margin-bottom:.3rem}.order-card[data-type=buy] .order-card__type{color:var(--green)}.order-card[data-type=sell] .order-card__type{color:var(--danger-color)}.order-card--selected{background-color:rgba(var(--text-color), 0.08)}.order-card--selected .cancel-order{visibility:hidden;pointer-events:none}.order-card sm-checkbox{grid-area:checkbox;cursor:pointer;margin-right:.5rem}.order-card__quantity,.order-card__price{font-size:.9rem;color:rgba(var(--text-color), 0.9)}.order-card__time{grid-area:time;font-size:.8rem;color:rgba(var(--text-color), 0.8)}.order-card .cancel-order{grid-area:cancel;color:var(--danger-color)}.order-card .cancel-order .icon{fill:var(--danger-color)}.cancel-order{align-items:center;padding:.4rem .6rem}.cancel-order span{margin-left:.3rem}.completed-trade,.transaction-card,.live-order{gap:0 1rem}.completed-trade__type,.transaction-card__type,.live-order__type{font-size:.9rem;font-weight:500;margin-bottom:.3rem}.completed-trade[data-type=Bought] .completed-trade__type,.completed-trade--buy .completed-trade__type,.completed-trade[data-type=Bought] .transaction-card__type,.completed-trade--buy .transaction-card__type,.completed-trade[data-type=Bought] .live-order__type,.completed-trade--buy .live-order__type,.transaction-card[data-type=Bought] .completed-trade__type,.transaction-card--buy .completed-trade__type,.transaction-card[data-type=Bought] .transaction-card__type,.transaction-card--buy .transaction-card__type,.transaction-card[data-type=Bought] .live-order__type,.transaction-card--buy .live-order__type,.live-order[data-type=Bought] .completed-trade__type,.live-order--buy .completed-trade__type,.live-order[data-type=Bought] .transaction-card__type,.live-order--buy .transaction-card__type,.live-order[data-type=Bought] .live-order__type,.live-order--buy .live-order__type{color:var(--green)}.completed-trade[data-type=Sold] .completed-trade__type,.completed-trade--sell .completed-trade__type,.completed-trade[data-type=Sold] .transaction-card__type,.completed-trade--sell .transaction-card__type,.completed-trade[data-type=Sold] .live-order__type,.completed-trade--sell .live-order__type,.transaction-card[data-type=Sold] .completed-trade__type,.transaction-card--sell .completed-trade__type,.transaction-card[data-type=Sold] .transaction-card__type,.transaction-card--sell .transaction-card__type,.transaction-card[data-type=Sold] .live-order__type,.transaction-card--sell .live-order__type,.live-order[data-type=Sold] .completed-trade__type,.live-order--sell .completed-trade__type,.live-order[data-type=Sold] .transaction-card__type,.live-order--sell .transaction-card__type,.live-order[data-type=Sold] .live-order__type,.live-order--sell .live-order__type{color:var(--danger-color)}.completed-trade__total,.transaction-card__total,.live-order__total{font-weight:700;font-size:.9rem;color:rgba(var(--text-color), 0.8)}.completed-trade__quantity,.completed-trade__price,.transaction-card__quantity,.transaction-card__price,.live-order__quantity,.live-order__price{font-size:.9rem;color:rgba(var(--text-color), 0.9)}.completed-trade__time,.transaction-card__time,.live-order__time{font-size:.8rem;color:rgba(var(--text-color), 0.8)}.completed-trade .more-info,.transaction-card .more-info,.live-order .more-info{flex-shrink:0;padding:.3rem}.transaction-card{content-visibility:auto;contain-intrinsic-size:2.5rem;grid-template-columns:repeat(3, 1fr) 2rem}.completed-trade{display:grid;gap:.5rem;grid-template-columns:1fr 1fr;background-color:rgba(var(--text-color), 0.03);border-radius:.5rem;padding:1rem;margin-bottom:.5rem}#market_asset_rates{display:grid;gap:.5rem}#market_asset_rates .listed-asset{padding:1rem;background-color:rgba(var(--text-color), 0.03)}#market_orders_wrapper .list__header{font-size:.8rem;font-weight:500}#market_orders_wrapper .list__header div{padding:.5rem 0}#market_orders_wrapper .list__header{margin-bottom:.5rem;grid-template-columns:repeat(3, 1fr) 2rem}.live-order{display:grid;gap:1rem;padding:1rem;border-radius:.5rem;background-color:rgba(var(--text-color), 0.03)}.live-order:not(:last-of-type){margin-bottom:.5rem}.live-order[data-type=buy]{background-color:rgba(0,250,154,.062745098)}.live-order[data-type=sell]{background-color:rgba(226,19,81,.062745098)}#portfolio{display:grid;gap:1.5rem;grid-template-columns:minmax(0, 1fr);align-content:flex-start;width:min(32rem,100%)}.label{font-size:.8rem;color:rgba(var(--text-color), 0.8);margin-bottom:.2rem}#my_assets{gap:.5rem;margin-top:.5rem;padding-bottom:1.5rem;border:none}.balance-card{display:grid;align-items:center;gap:0 .5rem;padding:1rem;padding-left:.6rem;border-radius:.3rem;color:inherit;background-color:rgba(var(--text-color), 0.03)}.balance-card.is-locked{grid-template-columns:auto 1fr auto}.balance-card.is-locked .balance-card__icon{grid-row:span 2}.balance-card.is-locked .balance-card__right-arrow{grid-area:1/3/3/4}.balance-card.is-locked .balance-card__amount-wrapper{grid-area:2/2/3/3}.balance-card:not(.is-locked){grid-template-columns:auto 1fr auto auto}.balance-card:not(.is-locked) .balance-card__right-arrow{grid-area:1/4/2/5}.balance-card__icon{display:flex;align-content:center;justify-content:center;margin:0 .5rem;border-radius:.8rem;align-self:flex-start;background-color:var(--accent-color--light)}.balance-card__icon .icon{height:1.3rem;width:1.3rem;fill:var(--accent-color)}.balance-card__token{font-size:.9rem;font-weight:500}.balance-card__amount-wrapper{margin-top:.5rem;grid-column:3/-1;gap:.3rem 1rem;grid-template-columns:1fr 1fr}.balance-card__amount-wrapper>:nth-child(even){text-align:right}.balance-card__right-arrow{background-color:rgba(var(--text-color), 0.1);border-radius:1rem;padding:.1rem;fill:var(--accent-color)}#history{padding-top:0 !important;width:min(36rem,100%)}#history .sticky{margin-left:-0.7rem;padding:1rem 0;background-color:rgba(var(--background-color), 1)}#exchange_history{margin-top:.5rem}.history-entry{display:grid;grid-template-columns:auto 1fr auto;gap:.5rem 1rem;align-items:center;margin-bottom:2rem}.history-entry[data-status=SUCCESS] .history-entry__status .icon{fill:var(--green)}.history-entry[data-status=PENDING] .history-entry__status .icon,.history-entry[data-status=WAITING_CONFIRMATION] .history-entry__status .icon{fill:var(--yellow)}.history-entry__status{display:flex;align-items:center;justify-content:center;grid-row:1/3;width:2.5rem;height:2.5rem;background-color:rgba(var(--text-color), 0.03);border-radius:2rem}.history-entry__token-action{font-weight:500}.history-entry__amount{font-weight:500;text-align:right}.history-entry[data-type=deposit] .history-entry__amount:not(:empty){color:var(--green)}.history-entry[data-type=deposit] .history-entry__amount:not(:empty)::before{content:"+ "}.history-entry[data-type=withdraw] .history-entry__amount:not(:empty)::before{content:"- "}.history-entry__time{font-size:.8rem;color:rgba(var(--text-color), 0.8)}.history-entry__txid{font-weight:500;font-size:.9rem;text-align:right}#portfolio_asset_page .sticky{margin-top:-1.5rem;margin-left:-0.7rem;padding:1rem 0;background-color:rgba(var(--background-color), 1)}#portfolio_asset__history{margin-top:1rem}#portfolio_cards_wrapper{display:grid;gap:.5rem;grid-template-columns:repeat(auto-fit, minmax(12rem, 1fr))}.personal-asset-balance{align-content:flex-start;padding:1rem;border-radius:.5rem;color:rgba(0,0,0,.8);width:100%}.personal-asset-balance:not(:last-of-type){margin-right:.5rem}.personal-asset-balance:nth-of-type(1){background:url("bg-art2.svg") no-repeat bottom right,#c2ffd7;background-size:contain}.personal-asset-balance:nth-of-type(1) .icon{background-color:rgba(102,255,156,.5)}.personal-asset-balance:nth-of-type(1) .button{border:solid thin rgba(102,255,156,.5)}.personal-asset-balance:nth-of-type(2){background:url("back.svg") no-repeat top right,#fcffa8;background-size:contain}.personal-asset-balance:nth-of-type(2) .icon{background-color:rgba(255,234,0,.5)}.personal-asset-balance>.flex{margin-bottom:.3rem}.personal-asset-balance>.flex .icon{height:2rem;width:2rem;padding:.4rem;border-radius:.3rem;fill:rgba(0,0,0,.8);margin-right:.5rem}.personal-asset-balance .button{display:flex;align-items:center;margin-top:.5rem;padding-right:.8rem;justify-self:flex-start;border-radius:1rem;background-color:rgba(var(--foreground-color), 1);color:rgba(var(--text-color), 1);transition:box-shadow .3s}.personal-asset-balance .button .icon{height:1rem;background-color:rgba(0,0,0,0);margin-right:.3rem}.personal-asset-balance .button:hover{box-shadow:0 .3rem .5rem rgba(0,0,0,.16)}#personal_rupee_balance span:first-of-type,#personal_flo_balance span:first-of-type{font-size:1.5rem}#personal_rupee_balance span:last-of-type,#personal_flo_balance span:last-of-type{font-size:.9rem}#portfolio_result{justify-content:center;text-align:center}#portfolio_result__icon{display:flex;padding:1rem;border-radius:50%;background-color:rgba(var(--text-color), 0.06);justify-self:center;-webkit-animation:pop-up .3s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275);animation:pop-up .3s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275)}#portfolio_result__icon .icon{height:2rem;width:2rem}.icon--success{fill:var(--green)}.icon--failure,.icon--error{fill:var(--danger-color)}@-webkit-keyframes pop-up{from{transform:translateY(3rem) scale(0.5);opacity:0}to{transform:translateY(0) scale(1);opacity:1}}@keyframes pop-up{from{transform:translateY(3rem) scale(0.5);opacity:0}to{transform:translateY(0) scale(1);opacity:1}}#portfolio_result__cta{padding:1.5rem 1rem;border-radius:.5rem;background-color:rgba(var(--text-color), 0.06)}.stateful-result{overflow:hidden;position:absolute;display:flex;justify-content:center;align-items:center;height:100%;width:100%;left:0}.stateful-result>*{position:absolute}.stateful-result--success .result__background{background-color:var(--green)}.stateful-result--failure .result__background{background-color:var(--danger-color)}.stateful-result .icon-wrapper{-webkit-animation:pop .4s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275);animation:pop .4s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275)}.stateful-result .icon{height:1.5rem;width:1.5rem;fill:rgba(var(--background-color), 1)}.stateful-result span{font-weight:500;color:rgba(var(--background-color), 1)}.stateful-result .result__background{-webkit-animation:ripple-reveal 1s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275);animation:ripple-reveal 1s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275)}.result__background{border-radius:.3rem;height:100%;width:100%;-webkit-clip-path:circle(10%);clip-path:circle(10%)}@-webkit-keyframes pop{from{opacity:0;transform:translateY(2rem)}to{opacity:1;transform:translateY(0)}}@keyframes pop{from{opacity:0;transform:translateY(2rem)}to{opacity:1;transform:translateY(0)}}@-webkit-keyframes ripple-reveal{to{-webkit-clip-path:circle(100%);clip-path:circle(100%)}}@keyframes ripple-reveal{to{-webkit-clip-path:circle(100%);clip-path:circle(100%)}}#help{width:min(60ch,100%);margin-bottom:3rem;align-content:flex-start}#help ul{list-style:initial;display:grid;gap:1rem}#help ul li{margin-left:1rem;padding-left:.5rem;font-size:.9rem}@media screen and (max-width: 40rem)and (any-hover: none){.cancel-order span{display:none !important}}@media screen and (max-width: 40rem){.empty-state{align-self:center}#user_popup_button{width:100%}.main_navbar__item--active .item__title{transform:translateY(100%);opacity:0}.main_navbar__item--active .icon{transform:translateY(50%) scale(1.2)}#asset_list_wrapper{padding:0 1.5rem}.listed-asset{border-radius:0;border-bottom:solid thin rgba(var(--text-color), 0.1)}#exchange{margin:0;padding:0}#login_section{padding:0 1.5rem}#login_form{margin-top:3rem}#asset_page__header{display:flex;padding:1rem 1.5rem .5rem .8rem}#chart_header{padding:0 1.5rem .5rem 1.5rem}#trade_form{padding:0 1.5rem}#price_chart_container{flex:1}#asset_page__footer button{display:flex;flex-direction:column;align-items:center;flex:1;padding:.5rem 0;color:rgba(var(--text-color), 0.8);font-size:.8rem;font-weight:500}#asset_page__footer button .icon{height:1.2rem;margin-bottom:.3rem;margin-right:.3rem}#asset_page__footer button.active{color:var(--accent-color)}#asset_page__footer button.active .icon{fill:var(--accent-color)}.hide-on-mobile{display:none !important}}@media screen and (min-width: 40rem){sm-popup{--width: 24rem}.popup__header{grid-column:1/-1;padding:1rem 1.5rem 0 1.5rem}#confirmation_popup{--width: 24rem}.page-layout{grid-template-columns:1fr 90vw 1fr}.mobile-page{align-self:flex-start;padding:2rem;border-radius:.5rem;background-color:rgba(var(--foreground-color), 1)}.hide-on-desktop{display:none !important}#home{display:grid;grid-template-columns:auto 1fr;grid-template-rows:auto 1fr;grid-template-areas:"header header" "nav pages"}#main_header{grid-area:header}#user_popup_button{justify-self:flex-end}#main_navbar{grid-area:nav;flex-direction:column;height:100%;padding-left:.5rem}.main_navbar__item{padding:1.5rem 2rem 1.5rem 1rem;width:100%;flex:0;flex-direction:row;border-radius:.5rem;transition:background-color .3s}.main_navbar__item .icon{margin-bottom:0;margin-right:.5rem}.main_navbar__item .item__title{font-size:.9rem}.main_navbar__item--active{background-color:rgba(var(--text-color), 0.06)}#pages_container{grid-area:pages}#pages_container>*{margin:0 1.5rem;padding:2rem}#login_section{width:24rem}.is-signed-in #exchange{display:flex;width:100%}.is-signed-in #exchange_wrapper{display:grid;width:100%;height:100%;gap:1.5rem;grid-template-columns:17rem minmax(0, 1fr);align-items:flex-start}#price_history_chart{height:20rem}#asset_list_wrapper{grid-row:1/3}.listed-asset{padding:1rem}.listed-asset--active{opacity:1;background-color:rgba(var(--text-color), 0.06)}.listed-asset--active::before{content:"";position:absolute;width:.25rem;border-radius:0 .2rem .2rem 0;height:2rem;background-color:var(--accent-color)}.order-card{grid-template-columns:auto 1fr 1fr 1fr auto;grid-template-areas:"checkbox quantity price amount time cancel"}.orders_section__header{background-color:rgba(var(--foreground-color), 1)}#history .sticky,#portfolio_asset_page .sticky{background-color:rgba(var(--foreground-color), 1)}}@media screen and (max-width: 80rem)and (min-width: 40rem){.main_navbar__item{padding:1.5rem 1rem}.main_navbar__item .icon{margin-right:0}.main_navbar__item .item__title{display:none !important}}@media screen and (min-width: 52rem){body:not(.is-signed-in) #market{gap:2rem;width:100%;grid-template-columns:18rem 1fr}.completed-trade{grid-template-columns:1fr 1fr 1fr 8rem;grid-template-areas:"quantity price amount info"}.completed-trade .quantity-block{grid-area:quantity}.completed-trade .price-block{grid-area:price}.completed-trade .amount-block{grid-area:amount}.completed-trade .info-block{grid-area:info}}@media screen and (min-width: 64rem){#home{grid-template-columns:auto 1fr}#asset_page_wrapper{display:grid;gap:1.5rem;grid-template-columns:minmax(0, 1fr) 20rem}}@media screen and (min-width: 72rem){.page-layout{grid-template-columns:1fr 80vw 1fr}}@media screen and (min-width: 120rem){.page-layout{grid-template-columns:1fr 70vw 1fr}}@media(any-hover: hover){::-webkit-scrollbar{width:.5rem;height:.5rem}::-webkit-scrollbar-thumb{background:rgba(var(--text-color), 0.3);border-radius:1rem}::-webkit-scrollbar-thumb:hover{background:rgba(var(--text-color), 0.5)}.order-card .cancel-order{justify-self:flex-end;overflow:hidden}.order-card .cancel-order .icon,.order-card .cancel-order span{transition:opacity .3s,transform .3s}.order-card .cancel-order .icon{transform:translateX(100%)}.order-card .cancel-order span{transform:translateX(100%);opacity:0}.order-card:hover .cancel-order .icon,.order-card:focus-within .cancel-order .icon{opacity:1}.order-card .cancel-order:hover .icon,.order-card .cancel-order:hover span{opacity:1;transform:translateX(0)}} \ No newline at end of file +*{padding:0;margin:0;box-sizing:border-box;font-family:"Roboto",sans-serif}:root{font-size:clamp(1rem,1.2vmax,1.2rem)}html,body{height:100%;scroll-behavior:smooth}body{--accent-color: #516beb;--text-color: 20, 20, 20;--foreground-color: 252, 253, 255;--background-color: 241, 243, 248;--danger-color: rgb(255, 75, 75);--green: #1cad59;--yellow: #bd7200;scrollbar-width:thin;scrollbar-gutter:stable;color:rgba(var(--text-color), 1);background-color:rgba(var(--background-color), 1);transition:background-color .3s}body[data-theme=dark]{--accent-color: #a4b3ff;--text-color: 220, 220, 220;--foreground-color: 27, 28, 29;--background-color: 21, 22, 22;--danger-color: rgb(255, 106, 106);--green: #00e676;--yellow: #ffeb3b}body[data-theme=dark] sm-popup::part(popup){background-color:rgba(var(--foreground-color), 1)}p,strong{font-size:.9rem;max-width:70ch;line-height:1.7;color:rgba(var(--text-color), 0.8)}p:not(:last-of-type),strong:not(:last-of-type){margin-bottom:1.5rem}a:where([class]){color:inherit;text-decoration:none}a:where([class]):focus-visible{box-shadow:0 0 0 .1rem rgba(var(--text-color), 1) inset}a{text-decoration:none;color:var(--accent-color)}a:focus-visible{box-shadow:0 0 0 .1rem rgba(var(--text-color), 1) inset}fieldset{border:none;padding:0;margin:0}button,.button{-webkit-user-select:none;-moz-user-select:none;user-select:none;position:relative;display:inline-flex;border:none;background-color:rgba(0,0,0,0);overflow:hidden;color:inherit;-webkit-tap-highlight-color:rgba(0,0,0,0);align-items:center;font-size:inherit;font-weight:500;white-space:nowrap;padding:.8rem;border-radius:.3rem;justify-content:center;flex-shrink:0}button:focus-visible,.button:focus-visible{outline:var(--accent-color) solid medium}button:not(:disabled),.button:not(:disabled){cursor:pointer}.button{background-color:rgba(var(--text-color), 0.02);border:solid thin rgba(var(--text-color), 0.06)}.button--primary{color:rgba(var(--background-color), 1);background-color:var(--accent-color)}.button--primary .icon{fill:rgba(var(--background-color), 1)}.button--colored{color:var(--accent-color)}.button--colored .icon{fill:var(--accent-color)}.button--danger{background-color:rgba(255,115,115,.062745098);color:var(--danger-color)}.button--danger .icon{fill:var(--danger-color)}.button--small{padding:.4rem .6rem}.button--outlined{border:solid rgba(var(--text-color), 0.3) .1rem;background-color:rgba(var(--foreground-color), 1)}.button--transparent{background-color:rgba(0,0,0,0)}button:disabled{opacity:.4;cursor:not-allowed;filter:saturate(0)}.cta{text-transform:uppercase;font-size:.8rem;font-weight:700;letter-spacing:.05em;padding:.8rem 1rem}a:-webkit-any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:-moz-any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}input{accent-color:var(--accent-color)}sm-input{font-size:.9rem;--border-radius: 0.3rem}sm-form{--gap: 1rem}sm-copy{font-size:.9rem}ul{list-style:none}.hidden{display:none !important}.overflow-ellipsis{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.wrap-around{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-webkit-hyphens:auto;hyphens:auto}.sticky{position:-webkit-sticky;position:sticky;top:0;z-index:1}.full-bleed{grid-column:1/4}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.flex{display:flex}.flex-1{flex:1}.flex-wrap{flex-wrap:wrap}.flex-direction-column{flex-direction:column}.grid{display:grid}.grid-3{grid-template-columns:1fr auto auto}.flow-column{grid-auto-flow:column}.gap-0-3{gap:.3rem}.gap-0-5{gap:.5rem}.gap-1{gap:1rem}.gap-1-5{gap:1.5rem}.gap-2{gap:2rem}.gap-3{gap:3rem}.text-align-right{text-align:right}.align-start{align-items:flex-start}.align-center{align-items:center}.text-center{text-align:center}.justify-start{justify-content:start}.justify-center{justify-content:center}.justify-right{margin-left:auto}.align-self-center{align-self:center}.justify-self-center{justify-self:center}.justify-self-start{justify-self:start}.justify-self-end{justify-self:end}.space-between{justify-content:space-between}.w-100{width:100%}.interact{position:relative;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0)}.ripple{height:8rem;width:8rem;position:absolute;border-radius:50%;transform:scale(0);background:radial-gradient(circle, rgba(var(--text-color), 0.3) 0%, rgba(0, 0, 0, 0) 50%);pointer-events:none}.icon{width:1.2rem;height:1.2rem;fill:rgba(var(--text-color), 0.8)}.margin-right-0-5{margin-right:.5rem}.margin-right-auto{margin-right:auto}.margin-left-0-5{margin-left:.5rem}.margin-left-auto{margin-left:auto}.icon-only{padding:.5rem;aspect-ratio:1/1;background-color:rgba(0,0,0,0)}.icon-button{padding:.6rem;border-radius:.8rem;background-color:var(--accent-color--light);height:-webkit-max-content;height:-moz-max-content;height:max-content}.icon-button .icon{fill:var(--accent-color)}.empty-state{display:grid;text-align:center;justify-items:center;width:100%;max-width:none;padding:1.5rem}.empty-state__icon{height:3rem;width:3rem;padding:.6rem;border-radius:1rem;background-color:rgba(var(--text-color), 0.06);margin-bottom:1rem}.observe-empty-state:empty{display:none !important}.observe-empty-state:not(:empty)+.empty-state{display:none !important}#confirmation_popup,#prompt_popup{flex-direction:column}#confirmation_popup h4,#prompt_popup h4{font-size:1.2rem;margin-bottom:1rem}#confirmation_popup .flex,#prompt_popup .flex{margin-top:1rem}#prompt_message{margin-bottom:1.5rem}.popup__header{display:grid;gap:.5rem;width:100%;padding:0 1.5rem;align-items:center;justify-items:flex-start}.popup__header__close{padding:.5rem;margin-left:-0.5rem}#main_page{padding:1.5rem}#main_page>section:nth-of-type(1){align-content:flex-start}details:not(:last-of-type){border-bottom:thin solid rgba(var(--text-color), 0.3)}details summary{display:flex;justify-content:space-between;-webkit-user-select:none;-moz-user-select:none;user-select:none;cursor:pointer;padding:1rem 0}details .icon{flex-shrink:0}details[open]{padding-bottom:1rem}details[open] summary .icon{transform:rotate(180deg)}sm-chips{--gap: 0;background-color:rgba(var(--text-color), 0.06);border-radius:.2rem}sm-chip{position:relative;font-size:.9rem;--border-radius: 0.5rem;--padding: 0.5rem 0.8rem;--background: rgba(var(--text-color), 0.06);-webkit-user-select:none;-moz-user-select:none;user-select:none;font-weight:500}sm-chip[selected]{--background: var(--accent-color);color:rgba(var(--background-color), 1)}sm-chip:first-of-type{--border-radius: 0.3rem 0 0 0.3rem}sm-chip:last-of-type{--border-radius: 0 0.3rem 0.3rem 0}sm-checkbox{--height: 1rem;--width: 1rem;-webkit-tap-highlight-color:rgba(0,0,0,0)}.warning{background-color:khaki;color:rgba(0,0,0,.7);padding:1rem;border-radius:.5rem;line-height:1.5}.tip{border-radius:1.5rem;background-color:rgba(var(--text-color), 0.06);padding:.3rem .8rem;font-size:.85rem}.tip .icon{fill:var(--accent-color);flex-shrink:0}.tooltip{display:flex;position:relative;z-index:8;cursor:pointer}.tooltip .banner{position:absolute;right:0;top:100%;width:min(20rem,100vw - 1rem);display:none;font-size:.9rem;background-color:rgba(var(--foreground-color), 1);padding:1rem;border-radius:.5rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.1);border:solid thin rgba(var(--text-color), 0.2)}.tooltip:hover .banner{display:block}.page-layout{display:grid;grid-template-columns:1.5rem minmax(0, 1fr) 1.5rem}.page-layout>*{grid-column:2/3}.page{height:100%}.mobile-page{align-items:flex-start}#loading .rm-logo{height:3rem;width:3rem;padding:.8rem;background-color:rgba(var(--text-color), 0.06);border-radius:5rem;justify-self:center}#landing{grid-template-rows:auto 1fr}#landing header{padding:1.5rem 0}#landing>.grid{align-content:flex-start;text-align:center;gap:1rem}#sign_up{grid-template-rows:auto 1fr;align-items:center}#sign_up section{margin-top:-6rem;justify-self:center;width:min(24rem,100%)}#sign_up header{padding:1.5rem 0}#sign_up .h2{margin-bottom:.5rem}#sign_up h5{font-weight:500;color:rgba(var(--text-color), 0.8)}#sign_up .warning{margin-top:2rem}.loader-button-wrapper{display:grid;text-align:center}.loader-button-wrapper>*{grid-area:1/1/2/2}.loader-button-wrapper button{z-index:1}.loader-button-wrapper sm-spinner{justify-self:center;align-self:center}#home{height:100%;display:flex;flex-direction:column;align-items:flex-start;align-content:flex-start}#login_section{display:flex;width:100%}#login_form__priv_key{margin-top:1rem}#flo_id_warning{padding-bottom:1.5rem}#flo_id_warning .icon{height:3rem;width:3rem;padding:.8rem;overflow:visible;background-color:#ffc107;border-radius:3rem;fill:rgba(0,0,0,.8)}#main_header{display:flex;flex-wrap:wrap;gap:1rem;padding:1rem 1.5rem;width:100%;align-items:center}.app-brand{display:flex;gap:.3rem;align-items:center}.app-brand .icon{height:1.7rem;width:1.7rem}.app-name__company{font-size:.8rem;font-weight:500;color:rgba(var(--text-color), 0.8)}#user_popup_button{background-color:rgba(var(--text-color), 0.06);border-radius:2rem;font-size:.8rem}#main_navbar{width:100%}.main_navbar__item{display:flex;flex-direction:column;align-items:center;flex:1;padding:.5rem 0}.main_navbar__item .item__title,.main_navbar__item .icon{transition:transform .3s cubic-bezier(0.175, 0.885, 0.32, 1.275),opacity .3s}.main_navbar__item .item__title{color:rgba(var(--text-color), 0.8);font-size:.8rem;font-weight:500}.main_navbar__item .icon{height:1.2rem;margin-bottom:.3rem}.main_navbar__item--active .item__title{color:var(--accent-color)}.main_navbar__item--active .icon{fill:var(--accent-color)}#pages_container{display:flex;flex:1;width:100%;height:100%;justify-content:center;overflow-y:auto}#pages_container>*{padding:0 1.5rem;min-width:min(26rem,100%)}.listed-asset{position:relative;gap:.5rem;padding:1rem 0;border-radius:.5rem;font-weight:400;transition:background-color .3s;-webkit-user-select:none;-moz-user-select:none;user-select:none;color:inherit;grid-template-columns:auto 1fr auto auto;grid-template-areas:"icon name rate right-arrow" "icon name countdown right-arrow"}.listed-asset__icon{grid-area:icon;padding:.5rem;border-radius:1rem;display:flex;background-color:var(--accent-color)}.listed-asset__icon .icon{height:1.2rem;width:1.2rem;fill:rgba(var(--background-color), 1)}.listed-asset__name{grid-area:name;margin-left:.3rem}.listed-asset__rate{grid-area:rate}.listed-asset__countdown{display:flex;align-items:center;grid-area:countdown;justify-self:flex-end;font-size:.8rem;color:var(--accent-color)}.listed-asset__countdown .icon{margin-left:.3rem;overflow:visible;stroke-width:3;fill:none}.listed-asset__countdown .icon .path-a{stroke:var(--accent-color);stroke-dashoffset:var(--path-length, 0);stroke-dasharray:63}.listed-asset__countdown .icon .path-b{stroke:rgba(var(--text-color), 0.2)}.listed-asset__right-arrow{grid-area:right-arrow;background-color:rgba(var(--text-color), 0.1);border-radius:1rem;padding:.1rem;margin-left:.3rem}.quantity-selector .button{flex:1;padding:.5rem .6rem;margin-left:.5rem}#quantity_selector_tip::first-letter{text-transform:uppercase}#quantity_type,#portfolio_quantity_type{font-size:.8rem;padding-right:.5rem;border-right:thin solid rgba(var(--text-color), 0.3);margin-right:auto;color:rgba(var(--text-color), 0.8);line-height:1.5;font-weight:500;min-width:8ch}#exchange_wrapper{display:flex;flex-direction:column;height:100%}#asset_page{position:relative;display:flex;flex-direction:column;height:100%;align-items:flex-start}#asset_page_wrapper{display:flex;flex-direction:column;height:100%;width:100%}#trade_form{height:100%}#trade_form::part(form){display:flex;flex-direction:column;gap:0}#trade_form>*{margin-bottom:1rem}#trade_form>:last-child{margin-top:auto}#my_orders,#market{width:min(46rem,100%);height:-webkit-max-content;height:-moz-max-content;height:max-content}#my_orders{grid-template-rows:auto 1fr}.orders_section__header{min-height:2.8rem;position:-webkit-sticky;position:sticky;top:0;background-color:rgba(var(--background-color), 1);z-index:2;transition:background-color .3s}.list__item{padding:.5rem 0;display:grid}.order-card{position:relative;outline:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;align-items:center;gap:.5rem;grid-template-columns:-webkit-min-content 1fr auto;grid-template-columns:min-content 1fr auto;border-radius:.5rem;grid-template-areas:"checkbox quantity quantity time" "checkbox price amount cancel"}.order-card>.grid:nth-of-type(2){grid-area:price}.order-card>.grid:nth-of-type(3){grid-area:amount}.order-card__type{font-size:.9rem;font-weight:500;margin-bottom:.3rem}.order-card[data-type=buy] .order-card__type{color:var(--green)}.order-card[data-type=sell] .order-card__type{color:var(--danger-color)}.order-card--selected{background-color:rgba(var(--text-color), 0.08)}.order-card--selected .cancel-order{visibility:hidden;pointer-events:none}.order-card sm-checkbox{grid-area:checkbox;cursor:pointer;margin-right:.5rem}.order-card__quantity,.order-card__price{font-size:.9rem;color:rgba(var(--text-color), 0.9)}.order-card__time{grid-area:time;font-size:.8rem;color:rgba(var(--text-color), 0.8)}.order-card .cancel-order{grid-area:cancel;color:var(--danger-color)}.order-card .cancel-order .icon{fill:var(--danger-color)}.cancel-order{align-items:center;padding:.4rem .6rem}.cancel-order span{margin-left:.3rem}.completed-trade,.transaction-card,.live-order{gap:0 1rem}.completed-trade__type,.transaction-card__type,.live-order__type{font-size:.9rem;font-weight:500;margin-bottom:.3rem}.completed-trade[data-type=Bought] .completed-trade__type,.completed-trade--buy .completed-trade__type,.completed-trade[data-type=Bought] .transaction-card__type,.completed-trade--buy .transaction-card__type,.completed-trade[data-type=Bought] .live-order__type,.completed-trade--buy .live-order__type,.transaction-card[data-type=Bought] .completed-trade__type,.transaction-card--buy .completed-trade__type,.transaction-card[data-type=Bought] .transaction-card__type,.transaction-card--buy .transaction-card__type,.transaction-card[data-type=Bought] .live-order__type,.transaction-card--buy .live-order__type,.live-order[data-type=Bought] .completed-trade__type,.live-order--buy .completed-trade__type,.live-order[data-type=Bought] .transaction-card__type,.live-order--buy .transaction-card__type,.live-order[data-type=Bought] .live-order__type,.live-order--buy .live-order__type{color:var(--green)}.completed-trade[data-type=Sold] .completed-trade__type,.completed-trade--sell .completed-trade__type,.completed-trade[data-type=Sold] .transaction-card__type,.completed-trade--sell .transaction-card__type,.completed-trade[data-type=Sold] .live-order__type,.completed-trade--sell .live-order__type,.transaction-card[data-type=Sold] .completed-trade__type,.transaction-card--sell .completed-trade__type,.transaction-card[data-type=Sold] .transaction-card__type,.transaction-card--sell .transaction-card__type,.transaction-card[data-type=Sold] .live-order__type,.transaction-card--sell .live-order__type,.live-order[data-type=Sold] .completed-trade__type,.live-order--sell .completed-trade__type,.live-order[data-type=Sold] .transaction-card__type,.live-order--sell .transaction-card__type,.live-order[data-type=Sold] .live-order__type,.live-order--sell .live-order__type{color:var(--danger-color)}.completed-trade__total,.transaction-card__total,.live-order__total{font-weight:700;font-size:.9rem;color:rgba(var(--text-color), 0.8)}.completed-trade__quantity,.completed-trade__price,.transaction-card__quantity,.transaction-card__price,.live-order__quantity,.live-order__price{font-size:.9rem;color:rgba(var(--text-color), 0.9)}.completed-trade__time,.transaction-card__time,.live-order__time{font-size:.8rem;color:rgba(var(--text-color), 0.8)}.completed-trade .more-info,.transaction-card .more-info,.live-order .more-info{flex-shrink:0;padding:.3rem}.transaction-card{content-visibility:auto;contain-intrinsic-size:2.5rem;grid-template-columns:repeat(3, 1fr) 2rem}.completed-trade{display:grid;gap:.5rem;grid-template-columns:1fr 1fr;background-color:rgba(var(--text-color), 0.03);border-radius:.5rem;padding:1rem;margin-bottom:.5rem}#market_asset_rates{display:grid;gap:.5rem}#market_asset_rates .listed-asset{padding:1rem;background-color:rgba(var(--text-color), 0.03)}#market_orders_wrapper .list__header{font-size:.8rem;font-weight:500}#market_orders_wrapper .list__header div{padding:.5rem 0}#market_orders_wrapper .list__header{margin-bottom:.5rem;grid-template-columns:repeat(3, 1fr) 2rem}.live-order{display:grid;gap:1rem;padding:1rem;border-radius:.5rem;background-color:rgba(var(--text-color), 0.03)}.live-order:not(:last-of-type){margin-bottom:.5rem}.live-order[data-type=buy]{background-color:rgba(0,250,154,.062745098)}.live-order[data-type=sell]{background-color:rgba(226,19,81,.062745098)}#portfolio{display:grid;gap:1.5rem;grid-template-columns:minmax(0, 1fr);align-content:flex-start;width:min(32rem,100%)}.label{font-size:.8rem;color:rgba(var(--text-color), 0.8);margin-bottom:.2rem}#my_assets{gap:.5rem;margin-top:.5rem;padding-bottom:1.5rem;border:none}.balance-card{display:grid;align-items:center;gap:0 .5rem;padding:1rem;padding-left:.6rem;border-radius:.3rem;color:inherit;background-color:rgba(var(--text-color), 0.03)}.balance-card.is-locked{grid-template-columns:auto 1fr auto}.balance-card.is-locked .balance-card__icon{grid-row:span 2}.balance-card.is-locked .balance-card__right-arrow{grid-area:1/3/3/4}.balance-card.is-locked .balance-card__amount-wrapper{grid-area:2/2/3/3}.balance-card:not(.is-locked){grid-template-columns:auto 1fr auto auto}.balance-card:not(.is-locked) .balance-card__right-arrow{grid-area:1/4/2/5}.balance-card__icon{display:flex;align-content:center;justify-content:center;margin:0 .5rem;border-radius:.8rem;align-self:flex-start;background-color:var(--accent-color--light)}.balance-card__icon .icon{height:1.3rem;width:1.3rem;fill:var(--accent-color)}.balance-card__token{font-size:.9rem;font-weight:500}.balance-card__amount-wrapper{margin-top:.5rem;grid-column:3/-1;gap:.3rem 1rem;grid-template-columns:1fr 1fr}.balance-card__amount-wrapper>:nth-child(even){text-align:right}.balance-card__right-arrow{background-color:rgba(var(--text-color), 0.1);border-radius:1rem;padding:.1rem;fill:var(--accent-color)}#history{padding-top:0 !important;width:min(36rem,100%)}#history .sticky{margin-left:-0.7rem;padding:1rem 0;background-color:rgba(var(--background-color), 1)}#exchange_history{margin-top:.5rem}.history-entry{display:grid;grid-template-columns:auto 1fr auto;gap:.5rem 1rem;align-items:center;margin-bottom:2rem}.history-entry[data-status=SUCCESS] .history-entry__status .icon{fill:var(--green)}.history-entry[data-status=PENDING] .history-entry__status .icon,.history-entry[data-status=WAITING_CONFIRMATION] .history-entry__status .icon{fill:var(--yellow)}.history-entry__status{display:flex;align-items:center;justify-content:center;grid-row:1/3;width:2.5rem;height:2.5rem;background-color:rgba(var(--text-color), 0.03);border-radius:2rem}.history-entry__token-action{font-weight:500}.history-entry__amount{font-weight:500;text-align:right}.history-entry[data-type=deposit] .history-entry__amount:not(:empty){color:var(--green)}.history-entry[data-type=deposit] .history-entry__amount:not(:empty)::before{content:"+ "}.history-entry[data-type=withdraw] .history-entry__amount:not(:empty)::before{content:"- "}.history-entry__time{font-size:.8rem;color:rgba(var(--text-color), 0.8)}.history-entry__txid{font-weight:500;font-size:.9rem;text-align:right}#portfolio_asset_page .sticky{margin-top:-1.5rem;margin-left:-0.7rem;padding:1rem 0;background-color:rgba(var(--background-color), 1)}#portfolio_asset__history{margin-top:1rem}#portfolio_cards_wrapper{display:grid;gap:.5rem;grid-template-columns:repeat(auto-fit, minmax(12rem, 1fr))}.personal-asset-balance{align-content:flex-start;padding:1rem;border-radius:.5rem;color:rgba(0,0,0,.8);width:100%}.personal-asset-balance:not(:last-of-type){margin-right:.5rem}.personal-asset-balance:nth-of-type(1){background:url("bg-art2.svg") no-repeat bottom right,#c2ffd7;background-size:contain}.personal-asset-balance:nth-of-type(1) .icon{background-color:rgba(102,255,156,.5)}.personal-asset-balance:nth-of-type(1) .button{border:solid thin rgba(102,255,156,.5)}.personal-asset-balance:nth-of-type(2){background:url("back.svg") no-repeat top right,#fcffa8;background-size:contain}.personal-asset-balance:nth-of-type(2) .icon{background-color:rgba(255,234,0,.5)}.personal-asset-balance>.flex{margin-bottom:.3rem}.personal-asset-balance>.flex .icon{height:2rem;width:2rem;padding:.4rem;border-radius:.3rem;fill:rgba(0,0,0,.8);margin-right:.5rem}.personal-asset-balance .button{display:flex;align-items:center;margin-top:.5rem;padding-right:.8rem;justify-self:flex-start;border-radius:1rem;background-color:rgba(var(--foreground-color), 1);color:rgba(var(--text-color), 1);transition:box-shadow .3s}.personal-asset-balance .button .icon{height:1rem;background-color:rgba(0,0,0,0);margin-right:.3rem}.personal-asset-balance .button:hover{box-shadow:0 .3rem .5rem rgba(0,0,0,.16)}#personal_rupee_balance span:first-of-type,#personal_flo_balance span:first-of-type{font-size:1.5rem}#personal_rupee_balance span:last-of-type,#personal_flo_balance span:last-of-type{font-size:.9rem}#portfolio_result{justify-content:center;text-align:center}#portfolio_result__icon{display:flex;padding:1rem;border-radius:50%;background-color:rgba(var(--text-color), 0.06);justify-self:center;-webkit-animation:pop-up .3s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275);animation:pop-up .3s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275)}#portfolio_result__icon .icon{height:2rem;width:2rem}.icon--success{fill:var(--green)}.icon--failure,.icon--error{fill:var(--danger-color)}@-webkit-keyframes pop-up{from{transform:translateY(3rem) scale(0.5);opacity:0}to{transform:translateY(0) scale(1);opacity:1}}@keyframes pop-up{from{transform:translateY(3rem) scale(0.5);opacity:0}to{transform:translateY(0) scale(1);opacity:1}}#portfolio_result__cta{padding:1.5rem 1rem;border-radius:.5rem;background-color:rgba(var(--text-color), 0.06)}.stateful-result{overflow:hidden;position:absolute;display:flex;justify-content:center;align-items:center;height:100%;width:100%;left:0}.stateful-result>*{position:absolute}.stateful-result--success .result__background{background-color:var(--green)}.stateful-result--failure .result__background{background-color:var(--danger-color)}.stateful-result .icon-wrapper{-webkit-animation:pop .4s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275);animation:pop .4s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275)}.stateful-result .icon{height:1.5rem;width:1.5rem;fill:rgba(var(--background-color), 1)}.stateful-result span{font-weight:500;color:rgba(var(--background-color), 1)}.stateful-result .result__background{-webkit-animation:ripple-reveal 1s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275);animation:ripple-reveal 1s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275)}.result__background{border-radius:.3rem;height:100%;width:100%;-webkit-clip-path:circle(10%);clip-path:circle(10%)}@-webkit-keyframes pop{from{opacity:0;transform:translateY(2rem)}to{opacity:1;transform:translateY(0)}}@keyframes pop{from{opacity:0;transform:translateY(2rem)}to{opacity:1;transform:translateY(0)}}@-webkit-keyframes ripple-reveal{to{-webkit-clip-path:circle(100%);clip-path:circle(100%)}}@keyframes ripple-reveal{to{-webkit-clip-path:circle(100%);clip-path:circle(100%)}}#help{width:min(60ch,100%);margin-bottom:3rem;align-content:flex-start}#help ul{list-style:initial;display:grid;gap:1rem}#help ul li{margin-left:1rem;padding-left:.5rem;font-size:.9rem}@media screen and (max-width: 40rem)and (any-hover: none){.cancel-order span{display:none !important}}@media screen and (max-width: 40rem){.empty-state{align-self:center}#user_popup_button{width:100%}.main_navbar__item--active .item__title{transform:translateY(100%);opacity:0}.main_navbar__item--active .icon{transform:translateY(50%) scale(1.2)}#asset_list_wrapper{padding:0 1.5rem}.listed-asset{border-radius:0;border-bottom:solid thin rgba(var(--text-color), 0.1)}#exchange{margin:0;padding:0}#login_section{padding:0 1.5rem}#login_form{margin-top:3rem}#asset_page__header{display:flex;padding:1rem 1.5rem .5rem .8rem}#chart_header{padding:0 1.5rem .5rem 1.5rem}#trade_form{padding:0 1.5rem}#price_chart_container{flex:1}#asset_page__footer button{display:flex;flex-direction:column;align-items:center;flex:1;padding:.5rem 0;color:rgba(var(--text-color), 0.8);font-size:.8rem;font-weight:500}#asset_page__footer button .icon{height:1.2rem;margin-bottom:.3rem;margin-right:.3rem}#asset_page__footer button.active{color:var(--accent-color)}#asset_page__footer button.active .icon{fill:var(--accent-color)}.hide-on-mobile{display:none !important}}@media screen and (min-width: 40rem){sm-popup{--width: 24rem}.popup__header{grid-column:1/-1;padding:1rem 1.5rem 0 1.5rem}#confirmation_popup{--width: 24rem}.page-layout{grid-template-columns:1fr 90vw 1fr}.mobile-page{align-self:flex-start;padding:2rem;border-radius:.5rem;background-color:rgba(var(--foreground-color), 1)}.hide-on-desktop{display:none !important}#home{display:grid;grid-template-columns:auto 1fr;grid-template-rows:auto 1fr;grid-template-areas:"header header" "nav pages"}#main_header{grid-area:header}#user_popup_button{justify-self:flex-end}#main_navbar{grid-area:nav;flex-direction:column;height:100%;padding-left:.5rem}.main_navbar__item{padding:1.5rem 2rem 1.5rem 1rem;width:100%;flex:0;flex-direction:row;border-radius:.5rem;transition:background-color .3s}.main_navbar__item .icon{margin-bottom:0;margin-right:.5rem}.main_navbar__item .item__title{font-size:.9rem}.main_navbar__item--active{background-color:rgba(var(--text-color), 0.06)}#pages_container{grid-area:pages}#pages_container>*{margin:0 1.5rem;padding:2rem}#login_section{width:24rem}.is-signed-in #exchange{display:flex;width:100%}.is-signed-in #exchange_wrapper{display:grid;width:100%;height:100%;gap:1.5rem;grid-template-columns:17rem minmax(0, 1fr);align-items:flex-start}#price_history_chart{height:20rem}#asset_list_wrapper{grid-row:1/3}.listed-asset{padding:1rem}.listed-asset--active{opacity:1;background-color:rgba(var(--text-color), 0.06)}.listed-asset--active::before{content:"";position:absolute;width:.25rem;border-radius:0 .2rem .2rem 0;height:2rem;background-color:var(--accent-color)}.order-card{grid-template-columns:auto 1fr 1fr 1fr auto;grid-template-areas:"checkbox quantity price amount time cancel"}.orders_section__header{background-color:rgba(var(--foreground-color), 1)}#history .sticky,#portfolio_asset_page .sticky{background-color:rgba(var(--foreground-color), 1)}}@media screen and (max-width: 80rem)and (min-width: 40rem){.main_navbar__item{padding:1.5rem 1rem}.main_navbar__item .icon{margin-right:0}.main_navbar__item .item__title{display:none !important}}@media screen and (min-width: 52rem){body:not(.is-signed-in) #market{gap:2rem;width:100%;grid-template-columns:18rem 1fr}.completed-trade{grid-template-columns:1fr 1fr 1fr 8rem;grid-template-areas:"quantity price amount info"}.completed-trade .quantity-block{grid-area:quantity}.completed-trade .price-block{grid-area:price}.completed-trade .amount-block{grid-area:amount}.completed-trade .info-block{grid-area:info}}@media screen and (min-width: 64rem){#home{grid-template-columns:auto 1fr}#asset_page_wrapper{display:grid;gap:1.5rem;grid-template-columns:minmax(0, 1fr) 20rem}}@media screen and (min-width: 72rem){.page-layout{grid-template-columns:1fr 80vw 1fr}}@media screen and (min-width: 120rem){.page-layout{grid-template-columns:1fr 70vw 1fr}}@media(any-hover: hover){::-webkit-scrollbar{width:.5rem;height:.5rem}::-webkit-scrollbar-thumb{background:rgba(var(--text-color), 0.3);border-radius:1rem}::-webkit-scrollbar-thumb:hover{background:rgba(var(--text-color), 0.5)}.order-card .cancel-order{justify-self:flex-end;overflow:hidden}.order-card .cancel-order .icon,.order-card .cancel-order span{transition:opacity .3s,transform .3s}.order-card .cancel-order .icon{transform:translateX(100%)}.order-card .cancel-order span{transform:translateX(100%);opacity:0}.order-card:hover .cancel-order .icon,.order-card:focus-within .cancel-order .icon{opacity:1}.order-card .cancel-order:hover .icon,.order-card .cancel-order:hover span{opacity:1;transform:translateX(0)}} \ No newline at end of file diff --git a/docs/css/main.scss b/docs/css/main.scss index 2eccc84..d9a8de2 100644 --- a/docs/css/main.scss +++ b/docs/css/main.scss @@ -427,24 +427,6 @@ ul { align-content: flex-start; } } -.logo { - display: grid; - align-items: center; - grid-template-columns: auto 1fr; - gap: 0 0.3rem; - margin-right: auto; - h4 { - text-transform: capitalize; - font-weight: 600; - } - - .main-logo { - height: 1.4rem; - width: 1.4rem; - fill: rgba(var(--text-color), 1); - stroke: none; - } -} details { &:not(:last-of-type) { border-bottom: thin solid rgba(var(--text-color), 0.3); @@ -643,6 +625,22 @@ sm-checkbox { width: 100%; align-items: center; } +.app-brand{ + display: flex; + gap: 0.3rem; + align-items: center; + .icon{ + height: 1.7rem; + width: 1.7rem; + } +} +.app-name{ + &__company{ + font-size: 0.8rem; + font-weight: 500; + color: rgba(var(--text-color), 0.8); + } +} #user_popup_button { background-color: rgba(var(--text-color), 0.06); border-radius: 2rem; diff --git a/docs/index.html b/docs/index.html index 1b70631..825e37b 100644 --- a/docs/index.html +++ b/docs/index.html @@ -71,14 +71,17 @@