Changeset View
Changeset View
Standalone View
Standalone View
cashtab/src/validation/index.js
Show All 12 Lines | |||||
import tokenBlacklist from 'config/tokenBlacklist'; | import tokenBlacklist from 'config/tokenBlacklist'; | ||||
import { queryAliasServer } from 'alias'; | import { queryAliasServer } from 'alias'; | ||||
import appConfig from 'config/app'; | import appConfig from 'config/app'; | ||||
import { opReturn } from 'config/opreturn'; | import { opReturn } from 'config/opreturn'; | ||||
import { getStackArray } from 'ecash-script'; | import { getStackArray } from 'ecash-script'; | ||||
import aliasSettings from 'config/alias'; | import aliasSettings from 'config/alias'; | ||||
import { getAliasByteCount } from 'opreturn'; | import { getAliasByteCount } from 'opreturn'; | ||||
import { fiatToSatoshis } from 'wallet'; | import { fiatToSatoshis } from 'wallet'; | ||||
import { UNKNOWN_TOKEN_ID } from 'config/CashtabCache'; | |||||
/** | /** | ||||
* Checks whether the instantiated sideshift library object has loaded | * Checks whether the instantiated sideshift library object has loaded | ||||
* correctly with the expected API. | * correctly with the expected API. | ||||
* | * | ||||
* @param {Object} sideshiftObj the instantiated sideshift library object | * @param {Object} sideshiftObj the instantiated sideshift library object | ||||
* @returns {boolean} whether or not this sideshift object is valid | * @returns {boolean} whether or not this sideshift object is valid | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 314 Lines • ▼ Show 20 Lines | export const isValidCashtabCache = cashtabCache => { | ||||
if (existingKeys.length !== 1 || existingKeys[0] !== 'tokens') { | if (existingKeys.length !== 1 || existingKeys[0] !== 'tokens') { | ||||
return false; | return false; | ||||
} | } | ||||
// Validate that there is a map at the tokens key in case localforage saved the map without | // Validate that there is a map at the tokens key in case localforage saved the map without | ||||
// first converting it to a JSON at some point | // first converting it to a JSON at some point | ||||
if (!(cashtabCache.tokens instanceof Map)) { | if (!(cashtabCache.tokens instanceof Map)) { | ||||
return false; | return false; | ||||
} | } | ||||
// We do not validate all contents of the stored map, as these are from chronik | |||||
// We assume chronik unit tests handle this | if (typeof cashtabCache.tokens.get(UNKNOWN_TOKEN_ID) === 'undefined') { | ||||
return true; | // Cashtab Cache is invalid if it does not include UNKNOWN_TOKEN_ID | ||||
return false; | |||||
} | |||||
// Validate contents of map as shape may change | |||||
// Initialize flag because returning from a forEach does not do what you think it does | |||||
let isValidCachedInfo = true; | |||||
cashtabCache.tokens.forEach(cachedInfo => { | |||||
if ( | |||||
!('tokenType' in cachedInfo) || | |||||
!('genesisInfo' in cachedInfo) || | |||||
!('timeFirstSeen' in cachedInfo) || | |||||
!('genesisSupply' in cachedInfo) || | |||||
!('genesisOutputScripts' in cachedInfo) || | |||||
!('genesisMintBatons' in cachedInfo) | |||||
) { | |||||
isValidCachedInfo = false; | |||||
} | |||||
}); | |||||
return isValidCachedInfo; | |||||
}; | }; | ||||
export const isValidEtokenBurnAmount = (tokenBurnAmount, maxAmount) => { | export const isValidEtokenBurnAmount = (tokenBurnAmount, maxAmount) => { | ||||
// A valid eToken burn amount must be between 1 and the wallet's token balance | // A valid eToken burn amount must be between 1 and the wallet's token balance | ||||
return ( | return ( | ||||
tokenBurnAmount !== null && | tokenBurnAmount !== null && | ||||
maxAmount !== null && | maxAmount !== null && | ||||
typeof tokenBurnAmount !== 'undefined' && | typeof tokenBurnAmount !== 'undefined' && | ||||
▲ Show 20 Lines • Show All 337 Lines • ▼ Show 20 Lines | export const isValidCashtabWallet = wallet => { | ||||
} | } | ||||
if (typeof wallet !== 'object') { | if (typeof wallet !== 'object') { | ||||
// Wallet must be an object | // Wallet must be an object | ||||
return false; | return false; | ||||
} | } | ||||
if (!('paths' in wallet)) { | if (!('paths' in wallet)) { | ||||
return false; | return false; | ||||
} | } | ||||
if (wallet.paths.length < 1) { | if (Array.isArray(wallet.paths)) { | ||||
// wallet.paths should be a map | |||||
return false; | |||||
} | |||||
if (wallet.paths.size < 1) { | |||||
// Wallet must have at least one path info object | // Wallet must have at least one path info object | ||||
return false; | return false; | ||||
} | } | ||||
// Validate each path | // Validate each path | ||||
for (const path of wallet.paths) { | // We use pathsValid as a flag as `return false` from a forEach does not do what you think it does | ||||
if ( | let pathsValid = true; | ||||
!('path' in path) || | // Return false if we do not have Path1899 | ||||
!('hash' in path) || | // This also handles the case of a JSON-activated pre-2.9.0 wallet | ||||
!('address' in path) || | |||||
!('wif' in path) | if (typeof wallet.paths.get(1899) === 'undefined') { | ||||
) { | |||||
// If any given path does not have all of these keys, the wallet is invalid | |||||
return false; | return false; | ||||
} | } | ||||
wallet.paths.forEach((value, key) => { | |||||
if (typeof key !== 'number') { | |||||
// Wallet is invalid if key is not a number | |||||
pathsValid = false; | |||||
} | |||||
if (!('hash' in value) || !('address' in value) || !('wif' in value)) { | |||||
// If any given path does not have all of these keys, the wallet is invalid | |||||
pathsValid = false; | |||||
} | |||||
}); | |||||
if (!pathsValid) { | |||||
// Invalid path | |||||
return false; | |||||
} | } | ||||
return ( | return ( | ||||
typeof wallet === 'object' && | typeof wallet === 'object' && | ||||
'state' in wallet && | 'state' in wallet && | ||||
'mnemonic' in wallet && | 'mnemonic' in wallet && | ||||
'name' in wallet && | 'name' in wallet && | ||||
!('Path145' in wallet) && | !('Path145' in wallet) && | ||||
!('Path245' in wallet) && | !('Path245' in wallet) && | ||||
Show All 12 Lines |