Changeset View
Standalone View
web/cashtab/src/components/Common/Ticker.js
import mainLogo from '@assets/12-bitcoin-cash-square-crop.svg'; | import mainLogo from '@assets/12-bitcoin-cash-square-crop.svg'; | ||||
import tokenLogo from '@assets/simple-ledger-protocol-logo.png'; | import tokenLogo from '@assets/simple-ledger-protocol-logo.png'; | ||||
import cashaddr from 'cashaddrjs'; | |||||
import BigNumber from 'bignumber.js'; | |||||
export const currency = { | export const currency = { | ||||
name: 'Bitcoin ABC', | name: 'Bitcoin ABC', | ||||
ticker: 'BCHA', | ticker: 'BCHA', | ||||
logo: mainLogo, | logo: mainLogo, | ||||
prefix: 'bitcoincash:', | prefixes: ['bitcoincash:', 'ecash:'], | ||||
coingeckoId: 'bitcoin-cash-abc-2', | coingeckoId: 'bitcoin-cash-abc-2', | ||||
defaultFee: 5.01, | defaultFee: 5.01, | ||||
blockExplorerUrl: 'https://explorer.bitcoinabc.org', | blockExplorerUrl: 'https://explorer.bitcoinabc.org', | ||||
blockExplorerUrlTestnet: 'https://texplorer.bitcoinabc.org', | blockExplorerUrlTestnet: 'https://texplorer.bitcoinabc.org', | ||||
tokenName: 'Bitcoin ABC SLP', | tokenName: 'Bitcoin ABC SLP', | ||||
tokenTicker: 'SLPA', | tokenTicker: 'SLPA', | ||||
tokenLogo: tokenLogo, | tokenLogo: tokenLogo, | ||||
tokenPrefix: 'simpleledger:', | tokenPrefixes: ['simpleledger:', 'etoken:'], | ||||
Fabien: Is that a thing yet ? | |||||
bytesofmanAuthorUnsubmitted Done Inline ActionsNo. However, we know that simpleledger: will not be the standard on BCHA, so I think it's a good opportunity to support an array of possible prefixes. I think this PR is the appropriate place since it uses the same approach as the base layer prefix expansion. bytesofman: No. However, we know that `simpleledger:` will not be the standard on BCHA, so I think it's a… | |||||
tokenIconsUrl: '', //https://tokens.bitcoin.com/32 for BCH SLP | tokenIconsUrl: '', //https://tokens.bitcoin.com/32 for BCH SLP | ||||
useBlockchainWs: false, | useBlockchainWs: false, | ||||
}; | }; | ||||
export function isCash(addressString) { | |||||
// Note that this function validates prefix only | |||||
// Check for prefix included in currency.prefixes array | |||||
// For now, validation is handled by converting to bitcoincash: prefix and checksum | |||||
// and relying on legacy validation methods of bitcoincash: prefix addresses | |||||
let validCashAddress = false; | |||||
for (let i = 0; i < currency.prefixes.length; i += 1) { | |||||
if (addressString.split(currency.prefixes[i]).length > 1) { | |||||
validCashAddress = true; | |||||
} | |||||
} | |||||
return validCashAddress; | |||||
} | |||||
export function isToken(addressString) { | |||||
// Check for prefix included in currency.tokenPrefixes array | |||||
// For now, validation is handled by converting to simpleledger: prefix and checksum | |||||
// and relying on legacy validation methods of simpleledger: prefix addresses | |||||
let validTokenAddress = false; | |||||
for (let i = 0; i < currency.tokenPrefixes.length; i += 1) { | |||||
if (addressString.split(currency.tokenPrefixes[i]).length > 1) { | |||||
validTokenAddress = true; | |||||
} | |||||
} | |||||
return validTokenAddress; | |||||
FabienUnsubmitted Not Done Inline ActionsThere is an opportunity to factorize the code a bit here. Fabien: There is an opportunity to factorize the code a bit here. | |||||
} | |||||
export function ecashToCashAddr(ecashPrefixedAddress) { | |||||
// Convert an address with prefix and checksum for ecash: | |||||
// To an address in legacy bitcoincash: format | |||||
// Backend and validators currently support only legacy format | |||||
const { prefix, type, hash } = cashaddr.decode(ecashPrefixedAddress); | |||||
// If prefix is `ecash:`, change to `bitcoincash:` | |||||
let newPrefix = prefix; | |||||
if (prefix === 'ecash') { | |||||
newPrefix = 'bitcoincash'; | |||||
} | |||||
FabienUnsubmitted Not Done Inline ActionsI don't think this makes a lot of sense, what about: export function toLegacy(address) if (isCash(address)) { const { _, type, hash } = cashaddr.decode(address); return cashaddr.encode('bitcoincash', type, hash); } // Maybe return an error instead ? return address; This will let you update the prefixes as you will. Fabien: I don't think this makes a lot of sense, what about:
```lang=js
export function toLegacy… | |||||
bytesofmanAuthorUnsubmitted Done Inline ActionsExcellent point, thanks! bytesofman: Excellent point, thanks! | |||||
const reformattedAddr = cashaddr.encode(newPrefix, type, hash); | |||||
return reformattedAddr; | |||||
} | |||||
export function parseAddress(BCH, addressString) { | |||||
// Build return obj | |||||
const addressInfo = { | |||||
address: '', | |||||
isValid: false, | |||||
queryString: null, | |||||
amount: null, | |||||
}; | |||||
// Parse address string for parameters | |||||
const paramCheck = addressString.split('?'); | |||||
let cleanAddress = paramCheck[0]; | |||||
addressInfo.address = cleanAddress; | |||||
// Validate address | |||||
let isValidAddress; | |||||
try { | |||||
isValidAddress = BCH.Address.isCashAddress(cleanAddress); | |||||
} catch (err) { | |||||
isValidAddress = false; | |||||
} | |||||
addressInfo.isValid = isValidAddress; | |||||
// Check for parameters | |||||
// only the amount param is currently supported | |||||
let queryString = null; | |||||
let amount = null; | |||||
if (paramCheck.length > 1) { | |||||
queryString = paramCheck[1]; | |||||
FabienUnsubmitted Not Done Inline ActionsThis is a very limited used as is, because it only handles the amount param if it is the only param in the URI. Fabien: This is a very limited used as is, because it only handles the amount param if it is the only… | |||||
bytesofmanAuthorUnsubmitted Done Inline ActionsThe .has() method of the URLSearchParams(queryString) object in JavaScript will recognize the amount param regardless of its order. bytesofman: The `.has()` method of the `URLSearchParams(queryString)` object in JavaScript will recognize… | |||||
FabienUnsubmitted Not Done Inline ActionsRight, I missed the paramCheck variable was the result of the separation on ? and not & Fabien: Right, I missed the `paramCheck` variable was the result of the separation on `?` and not `&` | |||||
addressInfo.queryString = queryString; | |||||
const addrParams = new URLSearchParams(queryString); | |||||
if (addrParams.has('amount')) { | |||||
// Amount in satoshis | |||||
try { | |||||
amount = new BigNumber(parseInt(addrParams.get('amount'))) | |||||
.div(1e8) | |||||
.toString(); | |||||
} catch (err) { | |||||
amount = null; | |||||
} | |||||
} | |||||
} | |||||
addressInfo.amount = amount; | |||||
return addressInfo; | |||||
} |
Is that a thing yet ?