Compare commits

...

10 Commits

Author SHA1 Message Date
SaketAnand
a5934d830f
Update README.md
Some checks failed
Workflow push to Dappbundle / Build (push) Has been cancelled
2026-01-13 15:55:10 +05:30
SaketAnand
fc5f8b250f
Merge pull request #12 from void-57/patch-1
Change git push user in repopush workflow
2026-01-13 15:49:24 +05:30
66c96f06ea
Change git push user in repopush workflow 2026-01-13 01:23:15 +05:30
SaketAnand
f39de21198 updated default fee required for sending tokens
updated the send amount, fee required, and the minimum change amount needed for sending tokens using the "send token" section of the UI
2025-09-13 12:36:59 +05:30
SaketAnand
e3efa64271 Updated required FLO balance to send tokens
Updated required FLO balance from '0.001' to '0.00001' for sending tokens directly in the UI
2025-09-13 09:23:18 +05:30
31b0e5c81a
Update index.html 2025-09-01 07:29:36 +05:30
637c14952f
Fixing All, Sent, Mining classification 2025-08-20 17:20:49 +05:30
a0df5f1986
Update index.html 2025-08-20 12:46:44 +05:30
a7504d6248
Update index.min.html 2025-08-20 12:46:16 +05:30
7b2dae1b07
Update index.min.html 2025-08-20 12:38:43 +05:30
6 changed files with 3177 additions and 217 deletions

View File

@ -29,4 +29,4 @@ jobs:
cd ${{ secrets.DEPLOYMENT_LOCATION}}/dappbundle && git clone https://github.com/ranchimall/${{ github.event.repository.name }}
cd "${{ secrets.DEPLOYMENT_LOCATION}}/dappbundle/${{ github.event.repository.name }}" && rm -rf .gitattributes .git .github .gitignore
cd ${{ secrets.DEPLOYMENT_LOCATION}}/dappbundle/ && git add . && git commit -m "Workflow updating files of ${{ github.event.repository.name }}" && git push "https://ranchimalldev:${{ secrets.RM_ACCESS_TOKEN }}@github.com/ranchimall/dappbundle.git"
cd ${{ secrets.DEPLOYMENT_LOCATION}}/dappbundle/ && git add . && git commit -m "Workflow updating files of ${{ github.event.repository.name }}" && git push "https://saketongit:${{ secrets.RM_ACCESS_TOKEN }}@github.com/ranchimall/dappbundle.git"

View File

@ -1,5 +1,5 @@
# FLO Wallet
FLO Web Wallet
RanchiMall 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

View File

@ -2339,6 +2339,7 @@
resetBalance();
}
}
function openAddressSelector(e) {
floGlobals.addressSelectorTarget = e.target.closest('sm-input')
openPopup('saved_ids_popup')
@ -2368,7 +2369,7 @@
const tokenName = selectedToken.value
const tokenBalance = parseFloat(selectedToken.dataset.balance)
getRef('flo_data_wrapper').classList.add('hidden')
getRef('tx_flo_amount').value = '0.001'
getRef('tx_flo_amount').value = '0.00001'
getRef('tx_flo_amount').classList.add('hidden')
getRef('tx_receiver_wrapper').innerHTML = ''
addTokenReceiver()
@ -2499,43 +2500,80 @@
}
async function checkBalance(address) {
try {
getRef('address_details_wrapper').classList.remove('hidden')
floWebWallet.getLabels().then(allLabels => {
if (allLabels[queriedFloId]) {
getRef('queried_flo_address').innerHTML = `<h4>${allLabels[queriedFloId]}</h4> <sm-copy clip-text value=${queriedFloId}></sm-copy>`;
} else {
getRef('queried_flo_address').innerHTML = `
<p class="label">FLO Address </p>
<h4><sm-copy clip-text value=${queriedFloId}></sm-copy></h4>
`;
}
})
const queriedFloId = address || getRef('search_query_input').value.trim()
getRef('token_list_wrapper').classList.add('hidden')
getRef('flo_balance').innerHTML = `<sm-spinner></sm-spinner>`;
const [floBalance, tokenBalances] = await Promise.all([
floWebWallet.getBalance(queriedFloId),
fetchJson(`${floGlobals.tokenURL}api/v2/floAddressBalance/${queriedFloId}`).then(({ floAddressBalances }) => floAddressBalances)
])
let ownedTokens = []
for (const token in tokenBalances) {
ownedTokens.push(html`
<li class="token-item">
<span>${token}: </span><span>${parseFloat((tokenBalances[token].balance || 0).toFixed(8))}</span>
</li>
`)
}
if (ownedTokens.length) {
renderElem(getRef('token_list'), html`${ownedTokens}`)
getRef('token_list_wrapper').classList.remove('hidden')
}
// retrieve FLO balance
getRef('flo_balance').textContent = `${parseFloat(floBalance.toFixed(8))} FLO`;
} catch (e) {
console.error(e)
try {
const queriedFloId = address || getRef('search_query_input').value.trim(); // define first
getRef('address_details_wrapper').classList.remove('hidden');
getRef('token_list_wrapper').classList.add('hidden');
getRef('token_list').innerHTML = '';
getRef('flo_balance').innerHTML = `<sm-spinner></sm-spinner>`;
// Show label (if any)
floWebWallet.getLabels().then(allLabels => {
if (allLabels?.[queriedFloId]) {
getRef('queried_flo_address').innerHTML =
`<h4>${allLabels[queriedFloId]}</h4> <sm-copy clip-text value=${queriedFloId}></sm-copy>`;
} else {
getRef('queried_flo_address').innerHTML = `
<p class="label">FLO Address</p>
<h4><sm-copy clip-text value=${queriedFloId}></sm-copy></h4>
`;
}
}).catch(() => {
// non-fatal
getRef('queried_flo_address').innerHTML = `
<p class="label">FLO Address</p>
<h4><sm-copy clip-text value=${queriedFloId}></sm-copy></h4>
`;
});
// Fetch both, but don't let one failure block the other
const [floBalRes, tokenRes] = await Promise.allSettled([
floWebWallet.getBalance(queriedFloId),
fetchJson(`${floGlobals.tokenURL}api/v2/floAddressBalance/${queriedFloId}`)
]);
// --- FLO coin ---
if (floBalRes.status === 'fulfilled') {
const floBal = Number(floBalRes.value || 0);
getRef('flo_balance').textContent = `${floBal.toFixed(8)} FLO`;
} else {
// show fallback, but don't throw
getRef('flo_balance').textContent = `—`;
}
// --- FLO-based tokens ---
if (tokenRes.status === 'fulfilled') {
const tokenBalances = tokenRes.value?.floAddressBalances || {};
const ownedTokens = [];
for (const token in tokenBalances) {
const bal = Number(tokenBalances[token]?.balance || 0);
// Only list tokens you want (optionally filter > 0)
ownedTokens.push(html`
<li class="token-item">
<span>${token}: </span><span>${bal.toFixed(8)}</span>
</li>
`);
}
if (ownedTokens.length) {
renderElem(getRef('token_list'), html`${ownedTokens}`);
getRef('token_list_wrapper').classList.remove('hidden');
} else {
getRef('token_list_wrapper').classList.add('hidden');
}
} else {
// token call failed — keep tokens hidden
getRef('token_list_wrapper').classList.add('hidden');
}
} catch (e) {
console.error(e);
// optional: show an error toast / keep current UI as-is
}
}
function categorizeText(text) {
return new Promise((resolve, reject) => {
if (text.length == 34 && floCrypto.validateFloID(text)) {
@ -2802,7 +2840,7 @@
function hasUnconfirmedTransactions(address) {
return new Promise((resolve, reject) => {
fetchJson(`https://blockbook.flocard.app/api/v2/address/${address}?details=basic`)
fetchJson(`https://blockbook.ranchimall.net/api/v2/address/${address}?details=basic`)
.then(details => {
resolve(details.unconfirmedTxs > 0)
if (details.unconfirmedTxs > 0) {

File diff suppressed because one or more lines are too long

View File

@ -49,63 +49,80 @@
}
function formatTx(address, tx) {
let result = {
time: tx.time,
block: tx.blockheight,
blockhash: tx.blockhash,
txid: tx.txid,
floData: tx.floData,
confirmations: tx.confirmations
}
const result = {
time: tx.time,
block: tx.blockheight,
blockhash: tx.blockhash,
txid: tx.txid,
floData: tx.floData,
confirmations: tx.confirmations
};
//format receivers
let receivers = {};
for (let vout of tx.vout) {
if (vout.scriptPubKey.isAddress) {
let id = vout.scriptPubKey.addresses[0];
if (id in receivers)
receivers[id] += vout.value;
else receivers[id] = vout.value;
}
// ---- Receivers (outputs) ----
const receivers = {};
for (const vout of tx.vout || []) {
const outAddrs =
(vout.addresses && vout.addresses.length ? vout.addresses :
vout.scriptPubKey && vout.scriptPubKey.addresses ? vout.scriptPubKey.addresses : null);
if (outAddrs && outAddrs.length) {
const id = outAddrs[0];
receivers[id] = (receivers[id] || 0) + Number(vout.value || 0);
}
result.receivers = receivers;
//format senders (or mined)
if (!tx.vin[0].isAddress) { //mined (ie, coinbase)
let coinbase = tx.vin[0].coinbase;
result.mine = coinbase;
result.mined = { [coinbase]: tx.valueOut }
} else {
result.sender = tx.vin[0].addresses[0];
result.receiver = tx.vout[0].scriptPubKey.addresses[0];
result.fees = tx.fees;
let senders = {};
for (let vin of tx.vin) {
if (vin.isAddress) {
let id = vin.addresses[0];
if (id in senders)
senders[id] += vin.value;
else senders[id] = vin.value;
}
}
result.senders = senders;
}
result.receivers = receivers;
//remove change amounts
for (let id in senders) {
if (id in receivers) {
if (senders[id] > receivers[id]) {
senders[id] -= receivers[id];
delete receivers[id];
} else if (senders[id] < receivers[id]) { //&& id != address
receivers[id] -= senders[id];
delete senders[id];
}
}
}
}
// ---- Coinbase vs normal ----
const isCoinbase = !!(tx.vin && tx.vin[0] && tx.vin[0].coinbase);
if (isCoinbase) {
const coinbase = tx.vin[0].coinbase; // string
result.mine = coinbase;
result.mined = { [coinbase]: Number(tx.valueOut || 0) };
return result;
}
// ---- Normal tx: senders, fees, first-party heuristics ----
result.fees = tx.fees;
const firstInAddr = (tx.vin && tx.vin[0] && tx.vin[0].addresses && tx.vin[0].addresses[0]) || undefined;
const firstOutAddrs =
(tx.vout && tx.vout[0] &&
((tx.vout[0].addresses && tx.vout[0].addresses[0]) ||
(tx.vout[0].scriptPubKey && tx.vout[0].scriptPubKey.addresses && tx.vout[0].scriptPubKey.addresses[0]))) || undefined;
if (firstInAddr) result.sender = firstInAddr;
if (firstOutAddrs) result.receiver = firstOutAddrs;
const senders = {};
for (const vin of tx.vin || []) {
const inAddrs = vin.addresses;
if (inAddrs && inAddrs.length) {
const id = inAddrs[0];
senders[id] = (senders[id] || 0) + Number(vin.value || 0);
}
}
result.senders = senders;
// ---- Remove change (net flow) ----
for (const id of Object.keys(senders)) {
if (receivers[id] != null) {
if (senders[id] > receivers[id]) {
senders[id] -= receivers[id];
delete receivers[id];
} else if (senders[id] < receivers[id]) {
receivers[id] -= senders[id];
delete senders[id];
} else {
// equal -> cancel both
delete senders[id];
delete receivers[id];
}
}
}
return result;
}
floWebWallet.listTransactions = function (address, page_options = {}) {
return new Promise((resolve, reject) => {
let options = {};
@ -141,4 +158,4 @@
})
}
})(window.floWebWallet = {});
})(window.floWebWallet = {});

View File

@ -9,9 +9,9 @@
FLO: ['https://blockbook.ranchimall.net/'],
FLO_TEST: ['https://blockbook-testnet.ranchimall.net/']
},
sendAmt: 0.0003,
fee: 0.0002,
minChangeAmt: 0.0002,
sendAmt: 0.00001,
fee: 0.00001,
minChangeAmt: 0.00001,
receiverID: floGlobals.adminID
};