From f57095d96977784d1057a44203214e6b3d7d58f8 Mon Sep 17 00:00:00 2001 From: RanchiMall Dev Date: Mon, 8 Jan 2024 21:51:50 +0000 Subject: [PATCH] Workflow updating files of flowallet --- flowallet/index.html | 13 +- flowallet/index.min.html | 448 +++++++++++++++++++++++++++ flowallet/scripts/floTokenAPI.js | 10 +- flowallet/scripts/floTokenAPI.min.js | 2 +- 4 files changed, 460 insertions(+), 13 deletions(-) create mode 100644 flowallet/index.min.html diff --git a/flowallet/index.html b/flowallet/index.html index 54ee498..b81d645 100644 --- a/flowallet/index.html +++ b/flowallet/index.html @@ -17,8 +17,7 @@ /* Constants for FLO blockchain operations !!Make sure to add this at beginning!! */ const floGlobals = { blockchain: "FLO", - tokenApiUrl: 'https://ranchimallflo.duckdns.org', - tokenURL: 'https://ranchimallflo.duckdns.org/', + tokenURL: 'https://ranchimallflo.ranchimall.net/', expirationDays: 60, } @@ -42,7 +41,7 @@ compactIDB.initDB("FLOwebWallet", IDBObjects).then(async result => { render.savedIds(); if (!floGlobals.tokens || !floGlobals.smartContracts) { - fetchJson(`${floGlobals.tokenApiUrl}/api/v2/tokenSmartContractList`).then(({ tokens, smartContracts }) => { + fetchJson(`${floGlobals.tokenURL}api/v2/tokenSmartContractList`).then(({ tokens, smartContracts }) => { floGlobals.scMap = new Map() floGlobals.tokens = tokens.sort((a, b) => a.localeCompare(b)) floGlobals.smartContracts = smartContracts @@ -2265,7 +2264,7 @@ const senderFloAddr = floCrypto.getFloID(senderPrivateKey) Promise.all([ floWebWallet.getBalance(senderFloAddr), - fetchJson(`${floGlobals.tokenApiUrl}/api/v2/floAddressBalance/${senderFloAddr}`) + fetchJson(`${floGlobals.tokenURL}api/v2/floAddressBalance/${senderFloAddr}`) ]).then(([retrievedBal, { floAddressBalances }]) => { renderBalance({ balance: parseFloat(retrievedBal), address: senderFloAddr }) let ownedTokens = [] @@ -2483,7 +2482,7 @@ getRef('flo_balance').innerHTML = ``; const [floBalance, tokenBalances] = await Promise.all([ floWebWallet.getBalance(queriedFloId), - fetchJson(`${floGlobals.tokenApiUrl}/api/v2/floAddressBalance/${queriedFloId}`).then(({ floAddressBalances }) => floAddressBalances) + fetchJson(`${floGlobals.tokenURL}api/v2/floAddressBalance/${queriedFloId}`).then(({ floAddressBalances }) => floAddressBalances) ]) let ownedTokens = [] for (const token in tokenBalances) { @@ -2509,7 +2508,7 @@ //console.log('data entered is a FLO address'); resolve('address') } else if (text.length == 64 && returnHexNumber(text)) { - fetchJson(`${floGlobals.tokenApiUrl}/api/v2/categoriseString/` + text) + fetchJson(`${floGlobals.tokenURL}api/v2/categoriseString/` + text) .then(function (myJson) { resolve(myJson['type']) }).catch(err => { @@ -2788,7 +2787,7 @@ name = floGlobals.smartContracts[0].contractName address = floGlobals.smartContracts[0].contractAddress } - fetchJson(`${floGlobals.tokenApiUrl}/api/v2/smartContractInfo?contractName=${name}&contractAddress=${address}`) + fetchJson(`${floGlobals.tokenURL}api/v2/smartContractInfo?contractName=${name}&contractAddress=${address}`) .then(info => { console.log(info) const { diff --git a/flowallet/index.min.html b/flowallet/index.min.html new file mode 100644 index 0000000..3b5fcc9 --- /dev/null +++ b/flowallet/index.min.html @@ -0,0 +1,448 @@ + FLO Wallet
RanchiMall

FLO Wallet

Saved FLO addresses

Click 'Add FLO address' to add a new FLO address.

No Saved FLO address

FLO address

Keep your keys safe!

Don't share with anyone. Once lost private key can't be recovered.

Forgot FLO address?

In case of FLO address being lost and you have the private key associated with it. You can recover it.

No saved FLO addresses

\ No newline at end of file diff --git a/flowallet/scripts/floTokenAPI.js b/flowallet/scripts/floTokenAPI.js index 3ef5575..871f9f7 100644 --- a/flowallet/scripts/floTokenAPI.js +++ b/flowallet/scripts/floTokenAPI.js @@ -1,4 +1,4 @@ -(function (EXPORTS) { //floTokenAPI v1.0.4a +(function (EXPORTS) { //floTokenAPI v1.1.0 /* Token Operator to send/receive tokens via blockchain using API calls*/ 'use strict'; const tokenAPI = EXPORTS; @@ -67,15 +67,15 @@ const getBalance = tokenAPI.getBalance = function (floID, token = DEFAULT.currency) { return new Promise((resolve, reject) => { - fetch_api(`api/v1.0/getFloAddressBalance?token=${token}&floAddress=${floID}`) - .then(result => resolve(result.balance || 0)) + fetch_api(`api/v2/floAddressInfo/${floID}`) + .then(result => resolve(result.floAddressBalances[token]?.balance || 0)) .catch(error => reject(error)) }) } tokenAPI.getTx = function (txID) { return new Promise((resolve, reject) => { - fetch_api(`api/v1.0/getTransactionDetails/${txID}`).then(res => { + fetch_api(`api/v2/transactionDetails/${txID}`).then(res => { if (res.result === "error") reject(res.description); else if (!res.parsedFloData) @@ -169,7 +169,7 @@ tokenAPI.getAllTxs = function (floID, token = DEFAULT.currency) { return new Promise((resolve, reject) => { - fetch_api(`api/v1.0/getFloAddressTransactions?token=${token}&floAddress=${floID}`) + fetch_api(`api/v2/floAddressTransactions/${floID}${token ? `?token=${token}` : ''}`) .then(result => resolve(result)) .catch(error => reject(error)) }) diff --git a/flowallet/scripts/floTokenAPI.min.js b/flowallet/scripts/floTokenAPI.min.js index 1f9412f..20431a1 100644 --- a/flowallet/scripts/floTokenAPI.min.js +++ b/flowallet/scripts/floTokenAPI.min.js @@ -1 +1 @@ -!function(EXPORTS){"use strict";const tokenAPI="object"===typeof module?module.exports:window.floTokenAPI={},DEFAULT={apiURL:[floGlobals.tokenURL||"https://ranchimallflo.ranchimall.net/"],currency:floGlobals.currency||"rupee"},checkIfTor=tokenAPI.checkIfTor=()=>fetch("https://check.torproject.org/api/ip",{mode:"no-cors"}).then((response=>response.json())).then((result=>result.IsTor)).catch((error=>!1));let isTor=!1;checkIfTor().then((result=>{isTor=result,isTor&&(DEFAULT.apiURL=["http://omwkzk6bd6zuragdqsrhdyzgxzre7yx4vzrou4vzftintzc2dmagp6qd.onion:5017/"])})),Object.defineProperties(tokenAPI,{URL:{get:()=>DEFAULT.apiURL[0]},currency:{get:()=>DEFAULT.currency,set:currency=>DEFAULT.currency=currency}}),floGlobals.currency&&(tokenAPI.currency=floGlobals.currency),Object.defineProperties(floGlobals,{currency:{get:()=>DEFAULT.currency,set:currency=>DEFAULT.currency=currency}});const fetch_api=tokenAPI.fetch=function(apicall,apiURLs=DEFAULT.apiURL){return new Promise(((resolve,reject)=>{if(0===apiURLs.length)return void reject("No API URLs available");const currentURL=apiURLs[0];console.debug(currentURL+apicall),fetch(currentURL+apicall).then((response=>{response.ok?response.json().then((data=>resolve(data))):reject(response)})).catch((error=>{console.error(`Failed to fetch from ${currentURL}: ${error}`),fetch_api(apicall,apiURLs.slice(1)).then(resolve).catch(reject)}))}))},getBalance=tokenAPI.getBalance=function(floID,token=DEFAULT.currency){return new Promise(((resolve,reject)=>{fetch_api(`api/v1.0/getFloAddressBalance?token=${token}&floAddress=${floID}`).then((result=>resolve(result.balance||0))).catch((error=>reject(error)))}))};function sendTokens_raw(privKey,receiverID,token,amount,utxo,vout,scriptPubKey){return new Promise(((resolve,reject)=>{var trx=bitjs.transaction();trx.addinput(utxo,vout,scriptPubKey),trx.addoutput(receiverID,floBlockchainAPI.sendAmt),trx.addflodata(`send ${amount} ${token}#`);var signedTxHash=trx.sign(privKey,1);floBlockchainAPI.broadcastTx(signedTxHash).then((txid=>resolve([receiverID,txid]))).catch((error=>reject([receiverID,error])))}))}tokenAPI.getTx=function(txID){return new Promise(((resolve,reject)=>{fetch_api(`api/v1.0/getTransactionDetails/${txID}`).then((res=>{"error"===res.result?reject(res.description):res.parsedFloData?res.transactionDetails?resolve(res):reject("Data piece (transactionDetails) missing"):reject("Data piece (parsedFloData) missing")})).catch((error=>reject(error)))}))},tokenAPI.sendToken=function(privKey,amount,receiverID,message="",token=DEFAULT.currency,options={}){return new Promise(((resolve,reject)=>{let senderID=floCrypto.getFloID(privKey);if("number"!=typeof amount||isNaN(amount)||amount<=0)return reject("Invalid amount");getBalance(senderID,token).then((bal=>{if(amount>bal)return reject(`Insufficient ${token}# balance`);floBlockchainAPI.writeData(senderID,`send ${amount} ${token}# ${message}`,privKey,receiverID,options).then((txid=>resolve(txid))).catch((error=>reject(error)))})).catch((error=>reject(error)))}))},tokenAPI.bulkTransferTokens=function(sender,privKey,token,receivers){return new Promise(((resolve,reject)=>{if("object"!=typeof receivers)return reject("receivers must be object in format {receiver1: amount1, receiver2:amount2...}");let receiver_list=Object.keys(receivers),amount_list=Object.values(receivers),invalidReceivers=receiver_list.filter((id=>!floCrypto.validateFloID(id))),invalidAmount=amount_list.filter((val=>"number"!=typeof val||val<=0));if(invalidReceivers.length)return reject(`Invalid receivers: ${invalidReceivers}`);if(invalidAmount.length)return reject(`Invalid amounts: ${invalidAmount}`);if(0==receiver_list.length)return reject("Receivers cannot be empty");if(1==receiver_list.length){let receiver=receiver_list[0],amount=amount_list[0];floTokenAPI.sendToken(privKey,amount,receiver,"",token).then((txid=>resolve({success:{[receiver]:txid}}))).catch((error=>reject(error)))}else floTokenAPI.getBalance(sender,token).then((token_balance=>{if(amount_list.reduce(((a,e)=>a+e),0)>token_balance)return reject(`Insufficient ${token}# balance`);floBlockchainAPI.splitUTXOs(sender,privKey,receiver_list.length).then((split_txid=>{floBlockchainAPI.waitForConfirmation(split_txid).then((split_tx=>{var scriptPubKey=split_tx.vout[0].scriptPubKey.hex;let promises=[];for(let i in receiver_list)promises.push(sendTokens_raw(privKey,receiver_list[i],token,amount_list[i],split_txid,i,scriptPubKey));Promise.allSettled(promises).then((results=>{let success=Object.fromEntries(results.filter((r=>"fulfilled"==r.status)).map((r=>r.value))),failed=Object.fromEntries(results.filter((r=>"rejected"==r.status)).map((r=>r.reason)));resolve({success:success,failed:failed})}))})).catch((error=>reject(error)))})).catch((error=>reject(error)))})).catch((error=>reject(error)))}))},tokenAPI.getAllTxs=function(floID,token=DEFAULT.currency){return new Promise(((resolve,reject)=>{fetch_api(`api/v1.0/getFloAddressTransactions?token=${token}&floAddress=${floID}`).then((result=>resolve(result))).catch((error=>reject(error)))}))};(tokenAPI.util={}).parseTxData=function(txData){let parsedData={};for(let p in txData.parsedFloData)parsedData[p]=txData.parsedFloData[p];parsedData.sender=txData.transactionDetails.vin[0].addr;for(let vout of txData.transactionDetails.vout)vout.scriptPubKey.addresses[0]!==parsedData.sender&&(parsedData.receiver=vout.scriptPubKey.addresses[0]);return parsedData.time=txData.transactionDetails.time,parsedData}}(); \ No newline at end of file +!function(EXPORTS){"use strict";const tokenAPI="object"===typeof module?module.exports:window.floTokenAPI={},DEFAULT={apiURL:[floGlobals.tokenURL||"https://ranchimallflo.ranchimall.net/"],currency:floGlobals.currency||"rupee"},checkIfTor=tokenAPI.checkIfTor=()=>fetch("https://check.torproject.org/api/ip",{mode:"no-cors"}).then((response=>response.json())).then((result=>result.IsTor)).catch((error=>!1));let isTor=!1;checkIfTor().then((result=>{isTor=result,isTor&&(DEFAULT.apiURL=["http://omwkzk6bd6zuragdqsrhdyzgxzre7yx4vzrou4vzftintzc2dmagp6qd.onion:5017/"])})),Object.defineProperties(tokenAPI,{URL:{get:()=>DEFAULT.apiURL[0]},currency:{get:()=>DEFAULT.currency,set:currency=>DEFAULT.currency=currency}}),floGlobals.currency&&(tokenAPI.currency=floGlobals.currency),Object.defineProperties(floGlobals,{currency:{get:()=>DEFAULT.currency,set:currency=>DEFAULT.currency=currency}});const fetch_api=tokenAPI.fetch=function(apicall,apiURLs=DEFAULT.apiURL){return new Promise(((resolve,reject)=>{if(0===apiURLs.length)return void reject("No API URLs available");const currentURL=apiURLs[0];console.debug(currentURL+apicall),fetch(currentURL+apicall).then((response=>{response.ok?response.json().then((data=>resolve(data))):reject(response)})).catch((error=>{console.error(`Failed to fetch from ${currentURL}: ${error}`),fetch_api(apicall,apiURLs.slice(1)).then(resolve).catch(reject)}))}))},getBalance=tokenAPI.getBalance=function(floID,token=DEFAULT.currency){return new Promise(((resolve,reject)=>{fetch_api(`api/v2/floAddressInfo/${floID}`).then((result=>resolve(result.floAddressBalances[token]?.balance||0))).catch((error=>reject(error)))}))};function sendTokens_raw(privKey,receiverID,token,amount,utxo,vout,scriptPubKey){return new Promise(((resolve,reject)=>{var trx=bitjs.transaction();trx.addinput(utxo,vout,scriptPubKey),trx.addoutput(receiverID,floBlockchainAPI.sendAmt),trx.addflodata(`send ${amount} ${token}#`);var signedTxHash=trx.sign(privKey,1);floBlockchainAPI.broadcastTx(signedTxHash).then((txid=>resolve([receiverID,txid]))).catch((error=>reject([receiverID,error])))}))}tokenAPI.getTx=function(txID){return new Promise(((resolve,reject)=>{fetch_api(`api/v2/transactionDetails/${txID}`).then((res=>{"error"===res.result?reject(res.description):res.parsedFloData?res.transactionDetails?resolve(res):reject("Data piece (transactionDetails) missing"):reject("Data piece (parsedFloData) missing")})).catch((error=>reject(error)))}))},tokenAPI.sendToken=function(privKey,amount,receiverID,message="",token=DEFAULT.currency,options={}){return new Promise(((resolve,reject)=>{let senderID=floCrypto.getFloID(privKey);if("number"!=typeof amount||isNaN(amount)||amount<=0)return reject("Invalid amount");getBalance(senderID,token).then((bal=>{if(amount>bal)return reject(`Insufficient ${token}# balance`);floBlockchainAPI.writeData(senderID,`send ${amount} ${token}# ${message}`,privKey,receiverID,options).then((txid=>resolve(txid))).catch((error=>reject(error)))})).catch((error=>reject(error)))}))},tokenAPI.bulkTransferTokens=function(sender,privKey,token,receivers){return new Promise(((resolve,reject)=>{if("object"!=typeof receivers)return reject("receivers must be object in format {receiver1: amount1, receiver2:amount2...}");let receiver_list=Object.keys(receivers),amount_list=Object.values(receivers),invalidReceivers=receiver_list.filter((id=>!floCrypto.validateFloID(id))),invalidAmount=amount_list.filter((val=>"number"!=typeof val||val<=0));if(invalidReceivers.length)return reject(`Invalid receivers: ${invalidReceivers}`);if(invalidAmount.length)return reject(`Invalid amounts: ${invalidAmount}`);if(0==receiver_list.length)return reject("Receivers cannot be empty");if(1==receiver_list.length){let receiver=receiver_list[0],amount=amount_list[0];floTokenAPI.sendToken(privKey,amount,receiver,"",token).then((txid=>resolve({success:{[receiver]:txid}}))).catch((error=>reject(error)))}else floTokenAPI.getBalance(sender,token).then((token_balance=>{if(amount_list.reduce(((a,e)=>a+e),0)>token_balance)return reject(`Insufficient ${token}# balance`);floBlockchainAPI.splitUTXOs(sender,privKey,receiver_list.length).then((split_txid=>{floBlockchainAPI.waitForConfirmation(split_txid).then((split_tx=>{var scriptPubKey=split_tx.vout[0].scriptPubKey.hex;let promises=[];for(let i in receiver_list)promises.push(sendTokens_raw(privKey,receiver_list[i],token,amount_list[i],split_txid,i,scriptPubKey));Promise.allSettled(promises).then((results=>{let success=Object.fromEntries(results.filter((r=>"fulfilled"==r.status)).map((r=>r.value))),failed=Object.fromEntries(results.filter((r=>"rejected"==r.status)).map((r=>r.reason)));resolve({success:success,failed:failed})}))})).catch((error=>reject(error)))})).catch((error=>reject(error)))})).catch((error=>reject(error)))}))},tokenAPI.getAllTxs=function(floID,token=DEFAULT.currency){return new Promise(((resolve,reject)=>{fetch_api(`api/v2/floAddressTransactions/${floID}${token?`?token=${token}`:""}`).then((result=>resolve(result))).catch((error=>reject(error)))}))};(tokenAPI.util={}).parseTxData=function(txData){let parsedData={};for(let p in txData.parsedFloData)parsedData[p]=txData.parsedFloData[p];parsedData.sender=txData.transactionDetails.vin[0].addr;for(let vout of txData.transactionDetails.vout)vout.scriptPubKey.addresses[0]!==parsedData.sender&&(parsedData.receiver=vout.scriptPubKey.addresses[0]);return parsedData.time=txData.transactionDetails.time,parsedData}}(); \ No newline at end of file