Compare commits

..

No commits in common. "master" and "dev" have entirely different histories.
master ... dev

5 changed files with 47 additions and 67 deletions

View File

@ -1,76 +1,73 @@
# FLO Wallet
# FLO_webWallet
FLO Web Wallet
These are client-side scripts that can generate FLO addresses, send FLO transactions to the blockchain and monitor FLO data from the blockchain
These are client side scripts that can generate FLO addresses, send FLO transactions to the blockchain and monitor FLO data from the blockchain
NOTE: Use respective file for mainnet and testnet
### Live URL for FLO Wallet:
*https://ranchimall.github.io/flowallet/*
NOTE : Use respective file for mainnet and testnet
## Instructions to use
Note: Web wallet uses IndedxedDB for storing data, which means data is stored in the respective browser you used to open web wallet. Data stored by one browser can't be accessed by other browsers.
Note : Web wallet uses IndedxedDB for storing data, which means data is stored in respective browser you used to open web wallet.Data stored by one browser can't be accessed by other browser.
There are 4 pages in this web app :
----------------------
### Monitor FLO Data
This app allows users to view the transactions done by the given address/es.
This apge allows user to view the transactions done by the given address/es.
1. Click/Tap on the '+' floating button at bottom-right hand side, which opens a popup window.
2. Enter the FLO address that you want to monitor, You can also specify a label for that address which will be displayed as a name for that address. If you left the label field empty, the default label will be 'Unknown'.
2. Enter the FLO address that you want to monitor, You can also specify a label to that address which will be displayed as name for that address.If you left label field empty, the default label will be 'Unknown'.
3. Click/Tap on 'Ok' and the address you added will be displayed on the monitoring page as a card. This address is also added to your local database. Once you add an address/label pair, It will stay there until you clear data(Option available on Settings page).
3. Click/Tap on 'Ok' and the address you added will be displayed on monitoring page as a card.This address is also added to your local database.Once you add an address/label pair, It will stay there untill you clear data(Option available in Settings page).
4. When you hover the mouse pointer on a monitoring card, three dots will appear. clicking on this allows the user to edit or remove that address from the monitoring list.(On mobile devices this option is always visible)
4. When you hover mouse pointer on a monitoring card, three dots will appear. clicking on this allows user to edit or remove that address from monitoring list.(On mobile devices this option is always visible)
5. To see transactions done by any address, click/Tap on the respective address card. It will open a follow-up window, which displays transactions in the message format. consisting of data sent/received to/from, date of transaction, and FLO data. Arrows on the message body indicate the direction of the transaction i.e. Data is sent or received. On the top of the window, we have the option to go back to the monitoring page or refresh the transaction history.
5. To see transactions done by any address, click/Tap on respective address card.It will open an follow up window, which displays transactions in messege format. consisting of data sent/received to/from, date of transaction and FLO data. Arrows on messege body indicate direction of transaction i.e. Data is sent or received.On the top of window we have option to go back to monitoring page or refresh the transaction history.
### Send FLO Data
This page allows users to send FLO data and transactions to the blockchain. To send any data you have to check your balance first, to make sure you have enough balance as each transaction requires 0.0005 FLOs to be valid.
This page allows user to send FLO data and transactions to the blockchain.To send any data you have to check your balance first, to make sure you have enough balance as each transaction requires 0.0005 FLOs to be valid.
1. Enter the sender's address
2. Click check balance.
3. Balance of the respective address will be displayed
4. Enter the Receiver's address
5. Enter the amount
5. Enter amount
6. Enter FLO data (if required)
7. Click Send
8. Enter the private key for the address in the prompt
9. The transaction will be sent to the blockchain and returns the txid (returns error if any).
Note: Transaction fee is set to 0.0005
Note : Transcation fee is set to 0.0005
### FLO address generation/recovery page
This page can be used to generate or recover FLO addresses and private key pairs. This page has two buttons
#### generate a new address
As the name implies this button when clicked/tapped generates a new FLO address and private key pair. Also, there is a one-click/tap option that allows the user to copy the FLO address or private key.
This page can be used to generate or recover FLO address and private key pairs.This page has two buttons
#### generate new address
As the name implies this button when clicked/tapped generates new FLO address and private key pair.Also there is an one click/tap option that allows user to copy FLO address or private key.
#### Recover FLO address
This button when click/tapped opens a popup, which prompts the user to enter private key associated with the FLO address that has to be recovered. Once the correct private key is entered corresponding FLO address is displayed again.
#### recover FLO address
This button when click/tapped opens a popup, which prompts user to enter private key associated with the FLO address that has to be recovered. Once correct private key is entered corresponding FLO address is displayed again.
Note: Do not share your private key with anyone and keep it safe. Once lost a private key can't be recovered.
Note : Do not share your private key with anyone and keep it safe. Once lost a private key can't be recovered.
### Settings page
This page contains settings and information about Webapp.
This page contains settings and information about webapp.
#### Dark mode setting
This section allows the user to set a color scheme (light/dark) with two options, either automatic or manual.
1. Automatic - If this toggle is turned on, Dark mode is enabled automatically from 6 pm to 6 am (Custom timing will be added in future versions).
This section allows user to set color scheme (light/dark) with two options, either automatic or manual.
1. Automatic - If this toggle is turned on, Dark mode is enabled automatically from 6pm to 6am(Custom timing will be added in future versions).
2. Manual - Turning this toggle on/off changes the color scheme and stays in that mode unless changed by the user again.
2. Manual - Turning this toggle on/off changes color scheme and stayes in that mode unless changed by user again.
#### CLear all local data
This option clears all the data stored in IndexedDB databases from the browser. This is the same as clearing browser data and cache. After deleting data, it may take more time to load transactions as they are now fetched again from the blockchain. Also, you have to add addresses to start monitoring again.
This option clears all the data stored in IndexedDB databases from browser. This is same as clearing browser data and cache.After deleting data, it may take more time to load transactions as they are now fetched again from blockchain. Also you have to add addresses to start monitoring again.
#### About
This section contains information about the version and underlying technologies.
This section contains information about version and underlying technologies.
Note: For reducing API calls and processing time, monitored data are stored in the local browser. While monitoring the same address, the data from the browser database (IndexedDB) is used and only the new transactions are obtained using API.
Note : For reducing API calls and processing time , monitored data are stored in local browser. While monitoring the same address, the data from browser database (IndexedDB) is used and only the new transactions are obtained using API.

View File

@ -780,8 +780,6 @@ h3 {
padding: 1rem;
background-color: rgba(var(--text-color), 0.03);
border-radius: 0.3rem;
content-visibility: auto;
contain-intrinsic-size: 10rem;
}
.transaction:not(:last-of-type) {
margin-bottom: 1rem;
@ -797,9 +795,6 @@ h3 {
color: rgba(var(--text-color), 0.9);
font-weight: 500;
}
.transaction__receiver:hover {
color: var(--accent-color);
}
.transaction__amount {
font-weight: 700;
}

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -745,8 +745,6 @@ h3 {
padding: 1rem;
background-color: rgba(var(--text-color), 0.03);
border-radius: 0.3rem;
content-visibility: auto;
contain-intrinsic-size: 10rem;
&:not(:last-of-type) {
margin-bottom: 1rem;
}
@ -762,9 +760,6 @@ h3 {
margin-left: 0.5rem;
color: rgba(var(--text-color), 0.9);
font-weight: 500;
&:hover {
color: var(--accent-color);
}
}
&__amount {
font-weight: 700;

View File

@ -188,7 +188,7 @@
</div>
<section class="grid gap-1">
<div class="flex align-center space-between sticky top-0 flex-wrap gap-1"
style="background-color: rgba(var(--foreground-color), 1);transition: background-color .3s; padding-bottom: 0.5rem; z-index: 2">
style="background-color: rgba(var(--foreground-color), 1);transition: background-color .3s; padding-bottom: 0.5rem;">
<h4>Transactions</h4>
<sm-chips id="filter_selector" class="hidden">
<sm-chip value="all" selected>All</sm-chip>
@ -828,8 +828,8 @@
<template id="transaction_template">
<li class="transaction grid">
<div class="flex align-center">
<div class="transaction__icon flex"></div>
<a href="" class="transaction__receiver breakable"></a>
<div class="transaction__icon"></div>
<div class="transaction__receiver breakable"></div>
</div>
<div class="grid gap-0-3">
<div class="label">Amount</div>
@ -1216,7 +1216,11 @@
page = parseInt(page)
if (floGlobals.query.string !== query) {
checkBalance(query)
}
}/* else if (floGlobals.query.totalPages <= page * txsPerPage) {
loadMoreTransactions()
} else {
render.paginatedTransactions(page)
}*/
fetchTransactions(query, page).then(() => {
filterFetchedTransactions()
render.paginatedTransactions(page)
@ -1226,6 +1230,7 @@
}
break;
case 'txid':
// location.href = `#/tx/${query}`
break;
}
}
@ -1882,27 +1887,24 @@
transactionCard(details) {
const { sender, receiver, floData, time, txid, netValue, mine } = details
const { query: queriedFloId } = pagesData.params
let displayAddress
const clone = getRef('transaction_template').content.cloneNode(true).firstElementChild;
if (mine) {
clone.classList.add('mined')
clone.querySelector('.transaction__icon').innerHTML = `<svg class="icon" width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" clip-rule="evenodd" d="M22.0861 14.6534C22.3924 14.3472 22.7898 14.1486 23.2186 14.0876L44.6946 11.0319C45.2676 10.9504 45.8455 11.1432 46.2547 11.5524C47.2381 12.5358 46.8168 14.2128 45.4853 14.6146L28.6869 19.6843C28.3711 19.7796 28.0838 19.9515 27.8505 20.1848L27.0092 21.0261L28.3236 22.3404C29.0306 23.0475 29.0976 24.1522 28.5245 24.9346L52.2562 48.6662C53.0372 49.4473 53.0372 50.7136 52.2562 51.4946L51.4947 52.2561C50.7137 53.0372 49.4473 53.0372 48.6663 52.2561L24.9346 28.5245C24.1522 29.0976 23.0475 29.0306 22.3404 28.3236L21.0261 27.0092L20.1848 27.8505C19.9515 28.0838 19.7796 28.3711 19.6843 28.6869L14.6146 45.4853C14.2128 46.8168 12.5358 47.2381 11.5524 46.2547C11.1432 45.8455 10.9504 45.2675 11.0319 44.6946L14.0876 23.2186C14.1486 22.7898 14.3472 22.3924 14.6534 22.0861L15.3949 21.3447C14.8777 20.6386 14.8818 19.67 15.4072 18.9681C14.8209 18.1848 14.8837 17.0693 15.5958 16.3572L16.3573 15.5958C17.0694 14.8837 18.1848 14.8208 18.9681 15.4072C19.6701 14.8818 20.6386 14.8777 21.3447 15.3949L22.0861 14.6534Z"/> </svg>`;
displayAddress = 'Coinbase'
clone.querySelector('.transaction__receiver').textContent = 'Coinbase'
} else if (sender === receiver) {
clone.classList.add('self')
clone.querySelector('.transaction__icon').innerHTML = `<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><title>sender and receiver is same</title><path d="M.01 0h24v24h-24V0z" fill="none"/><path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"/></svg>`;
displayAddress = receiver
clone.querySelector('.transaction__receiver').textContent = receiver
} else if (queriedFloId === sender) {
clone.classList.add('sent')
clone.querySelector('.transaction__icon').innerHTML = `<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z"/></svg>`;
displayAddress = receiver
clone.querySelector('.transaction__receiver').textContent = receiver
} else {
clone.classList.add('received')
clone.querySelector('.transaction__icon').innerHTML = `<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"/></svg>`;
displayAddress = sender
clone.querySelector('.transaction__receiver').textContent = sender
}
clone.querySelector('.transaction__receiver').textContent = displayAddress
clone.querySelector('.transaction__receiver').href = `https://ranchimall.github.io/flowallet/#/search?type=address&query=${displayAddress}&page=1`
if (netValue) {
clone.querySelector('.transaction__amount').textContent = `${netValue} FLO`
} else {
@ -2309,14 +2311,14 @@
}, 100))
function checkSenderBalance() {
renderBalance({ balance: 0, showLoader: true })
renderBalance(0, true)
const senderPrivateKey = getRef('get_private_key_field').value.trim()
const senderFloAddr = floCrypto.getFloID(senderPrivateKey)
Promise.all([
floWebWallet.getBalance(senderFloAddr),
fetchJSON(`${floGlobals.tokenApiUrl}/api/v2/floAddressBalance/${senderFloAddr}`)
]).then(([retrievedBal, { floAddressBalances }]) => {
renderBalance({ balance: parseFloat(retrievedBal), address: senderFloAddr })
renderBalance(parseFloat(retrievedBal))
let ownedTokens = []
for (const token in floAddressBalances) {
ownedTokens.push(html`
@ -2361,7 +2363,6 @@
getRef('flo_data_textarea').value = ''
getRef('tx_flo_amount').value = ''
getRef('tx_flo_amount').classList.remove('hidden')
renderElem(getRef('tx_receiver_wrapper'), html``)
renderElem(getRef('tx_receiver_wrapper'), html`
<sm-input id="tx_receiver" class="w-100" placeholder="Receiver's FLO address" error-text="Invalid FLO address" data-flo-address animate required>
<button slot="right" class="icon-only" onclick="openPopup('saved_ids_popup')" title="Select from saved IDs">
@ -2382,10 +2383,11 @@
getRef('flo_data_wrapper').classList.add('hidden')
getRef('tx_flo_amount').value = '0.001'
getRef('tx_flo_amount').classList.add('hidden')
getRef('tx_receiver_wrapper').innerHTML = ''
renderElem(getRef('tx_receiver_wrapper'), html``)
addTokenReceiver()
getRef('add_token_receiver').classList.remove('hidden')
floGlobals.sendType = 'token'
getRef('send_form').elementsChanged()
}
function addTokenReceiver() {
const selectedToken = document.getElementById('sender_tokens_wrapper').querySelector('input[type="radio"]:checked')
@ -2422,26 +2424,20 @@
e.target.setAttribute('error-text', `You can send FLO upto ${parseFloat(document.getElementById('sender_balance').textContent) - floGlobals.fee} only`)
})
function renderBalance(options = {}) {
const { balance = 0, showLoader, address = '' } = options
console.log(options)
function renderBalance(balance = 0, loading = false) {
getRef('tx_flo_amount').setAttribute('max', balance)
renderElem(getRef('balance_card'), html`
<div class="grid gap-1">
<div class="grid">
<div class="flex align-center space-between">
<h5>Balance</h5>
<button id="refresh_balance_button" class="button button--small button--colored hidden"
onclick="checkSenderBalance()">Refresh</button>
</div>
<div class="flex align-end gap-0-3">
<b id="sender_balance" style="font-size: 2.5rem;line-height: 1;">${showLoader ? html`<sm-spinner></sm-spinner>` : balance}</b>
<b id="sender_balance" style="font-size: 2.5rem;line-height: 1;">${loading ? html`<sm-spinner></sm-spinner>` : balance}</b>
<span>FLO</span>
</div>
<div class="grid gap-0-3">
<span class="label">Sender FLO Address</span>
<h4>${address}</h4>
</div>
${!showLoader && balance == 0 ? html`
${!loading && balance == 0 ? html`
<p style="margin-top: 1.5rem; color: var(--danger-color)">
You don't have any FLO in your wallet. Please add some FLO to your wallet to send FLO.
</p>
@ -2618,9 +2614,6 @@
}
async function processQuery() {
const query = getRef('search_query_input').value.trim()
if (pagesData.params.query === query) {
return routeTo(window.location.hash)
}
categorizeText(query).then(async type => {
window.location.hash = `#/search?type=${type}&query=${query}&page=1`
}).catch(err => {