diff --git a/README.md b/README.md index 536a71a..da60c69 100644 --- a/README.md +++ b/README.md @@ -216,9 +216,17 @@ In addition, we have these system variables outside FLO Globals but used globall 3. isfloID - boolean value (true: compare as flo ID, false: compare as public key) (optional, default is true) * Returns : boolen (true or false) +#### Validate Address + floCrypto.validateAddr(address, *std, *bech) +`validateAddr` check if the given Address (any blockchain) is valid or not +1. address - address to validate +2. std - checks for legacy version (optional, default=true) (true: allow any, array: list of versions, value: one version only, false: allow none) +3. bech - checks for bech version (optional, default=false) (true: allow any, array: list of versions, value: one version only, false: allow none) [requires additional library: [btc_api](https://ranchimall.github.io/btc-webwallet/lib_btc.js)] +* Returns : boolen (true or false) + #### Validate FLO ID - floCrypto.validateAddr(floID) -`validateAddr` check if the given Address is valid or not + floCrypto.validateFloID(floID) +`validateFloID` check if the given floID is valid or not 1. floID - flo ID to validate * Returns : boolen (true or false) diff --git a/floBlockchainAPI.js b/floBlockchainAPI.js index fcc73b9..8cf3a79 100644 --- a/floBlockchainAPI.js +++ b/floBlockchainAPI.js @@ -1,4 +1,4 @@ -(function(EXPORTS) { //floBlockchainAPI v2.3.3 +(function(EXPORTS) { //floBlockchainAPI v2.3.3a /* FLO Blockchain Operator to send/receive data from blockchain using API calls*/ 'use strict'; const floBlockchainAPI = EXPORTS; @@ -125,9 +125,9 @@ return new Promise((resolve, reject) => { if (!floCrypto.validateASCII(floData)) return reject("Invalid FLO_Data: only printable ASCII characters are allowed"); - else if (!floCrypto.validateAddr(senderAddr)) + else if (!floCrypto.validateFloID(senderAddr)) return reject(`Invalid address : ${senderAddr}`); - else if (!floCrypto.validateAddr(receiverAddr)) + else if (!floCrypto.validateFloID(receiverAddr)) return reject(`Invalid address : ${receiverAddr}`); else if (privKey.length < 1 || !floCrypto.verifyPrivKey(privKey, senderAddr)) return reject("Invalid Private key!"); @@ -202,7 +202,7 @@ //merge all UTXOs of a given floID into a single UTXO floBlockchainAPI.mergeUTXOs = function(floID, privKey, floData = '') { return new Promise((resolve, reject) => { - if (!floCrypto.validateAddr(floID)) + if (!floCrypto.validateFloID(floID)) return reject(`Invalid floID`); if (!floCrypto.verifyPrivKey(privKey, floID)) return reject("Invalid Private Key"); @@ -326,7 +326,7 @@ } //Validate the receiver IDs and receive amount for (let floID in receivers) { - if (!floCrypto.validateAddr(floID)) + if (!floCrypto.validateFloID(floID)) invalids.InvalidReceiverIDs.push(floID); if (typeof receivers[floID] !== 'number' || receivers[floID] <= 0) invalids.InvalidReceiveAmountFor.push(floID); diff --git a/floCrypto.js b/floCrypto.js index 7be6c5a..1c47628 100644 --- a/floCrypto.js +++ b/floCrypto.js @@ -1,4 +1,4 @@ -(function(EXPORTS) { //floCrypto v2.3.1 +(function(EXPORTS) { //floCrypto v2.3.2 /* FLO Crypto Operators */ 'use strict'; const floCrypto = EXPORTS; @@ -196,18 +196,54 @@ } } - //Check if the given Address is valid or not - floCrypto.validateFloID = floCrypto.validateAddr = function(inpAddr) { - if (!inpAddr) + //Check if the given flo-id is valid or not + floCrypto.validateFloID = function(floID) { + if (!floID) return false; try { - let addr = new Bitcoin.Address(inpAddr); + let addr = new Bitcoin.Address(floID); return true; } catch { return false; } } + //Check if the given address (any blockchain) is valid or not + floCrypto.validateAddr = function(address, std = true, bech = false) { + if (address.length == 34) { //legacy or segwit encoding + if (std === false) + return false; + let decode = bitjs.Base58.decode(address); + var raw = decode.slice(0, decode.length - 4), + checksum = decode.slice(decode.length - 4); + var hash = Crypto.SHA256(Crypto.SHA256(raw, { + asBytes: true + }), { + asBytes: true + }); + if (hash[0] != checksum[0] || hash[1] != checksum[1] || hash[2] != checksum[2] || hash[3] != checksum[3]) + return false; + else if (std === true || (!Array.isArray(std) && std === raw[0]) || (Array.isArray(std) && std.includes(raw[0]))) + return true; + else + return false; + } else if (address.length == 42 || address.length == 62) { //bech encoding + if (bech === false) + return false; + else if (typeof btc_api !== "object") + throw "btc_api library missing (lib_btc.js)"; + let decode = coinjs.bech32_decode(address); + if (!decode) + return false; + var raw = decode.data; + if (bech === true || (!Array.isArray(bech) && bech === raw[0]) || (Array.isArray(bech) && bech.includes(raw[0]))) + return true; + else + return false; + } else //unknown length + return false; + } + //Split the str using shamir's Secret and Returns the shares floCrypto.createShamirsSecretShares = function(str, total_shares, threshold_limit) { try { diff --git a/floDapps.js b/floDapps.js index 157b37d..e25ecf0 100644 --- a/floDapps.js +++ b/floDapps.js @@ -1,4 +1,4 @@ -(function(EXPORTS) { //floDapps v2.3.1 +(function(EXPORTS) { //floDapps v2.3.1a /* General functions for FLO Dapps*/ 'use strict'; const floDapps = EXPORTS; @@ -284,7 +284,7 @@ if (!result) return reject("Empty Private Key") var floID = floCrypto.getFloID(result) - if (!floID || !floCrypto.validateAddr(floID)) + if (!floID || !floCrypto.validateFloID(floID)) return reject("Invalid Private Key") privKey = result; }).catch(error => { @@ -426,7 +426,7 @@ floDapps.storeContact = function(floID, name) { return new Promise((resolve, reject) => { - if (!floCrypto.validateAddr(floID)) + if (!floCrypto.validateFloID(floID)) return reject("Invalid floID!") compactIDB.writeData("contacts", name, floID, user.db_name).then(result => { user.contacts[floID] = name; @@ -439,7 +439,7 @@ return new Promise((resolve, reject) => { if (floID in user.pubKeys) return resolve("pubKey already stored") - if (!floCrypto.validateAddr(floID)) + if (!floCrypto.validateFloID(floID)) return reject("Invalid floID!") if (floCrypto.getFloID(pubKey) != floID) return reject("Incorrect pubKey")