diff --git a/web/cashtab/extension/public/manifest.json b/web/cashtab/extension/public/manifest.json --- a/web/cashtab/extension/public/manifest.json +++ b/web/cashtab/extension/public/manifest.json @@ -2,8 +2,8 @@ "manifest_version": 2, "name": "Cashtab", - "description": "A browser-integrated BCHA wallet from Bitcoin ABC", - "version": "0.0.9", + "description": "A browser-integrated eCash wallet from Bitcoin ABC", + "version": "1.0.0", "content_scripts": [ { "matches": ["file://*/*", "http://*/*", "https://*/*"], @@ -21,10 +21,10 @@ "default_title": "Cashtab" }, "icons": { - "16": "bch16.png", - "48": "bch48.png", - "128": "bch128.png", - "192": "bch192.png", - "512": "bch512.png" + "16": "ecash16.png", + "48": "ecash48.png", + "128": "ecash128.png", + "192": "ecash192.png", + "512": "ecash512.png" } } diff --git a/web/cashtab/extension/src/assets/popout.svg b/web/cashtab/extension/src/assets/popout.svg --- a/web/cashtab/extension/src/assets/popout.svg +++ b/web/cashtab/extension/src/assets/popout.svg @@ -13,9 +13,9 @@ - + - + \ No newline at end of file diff --git a/web/cashtab/extension/src/components/App.js b/web/cashtab/extension/src/components/App.js --- a/web/cashtab/extension/src/components/App.js +++ b/web/cashtab/extension/src/components/App.js @@ -15,7 +15,7 @@ import SendToken from '@components/Send/SendToken'; import Configure from '@components/Configure/Configure'; import NotFound from '@components/NotFound'; -import CashTab from '@assets/cashtab.png'; +import CashTab from '@assets/cashtab_xec.png'; import PopOut from '@assets/popout.svg'; import './App.css'; import { WalletContext } from '@utils/context'; @@ -56,6 +56,15 @@ color: ${props => props.theme.contrast} !important; background-color: ${props => props.theme.primary} !important; } + #addrSwitch { + .ant-switch-checked { + background-color: white !important; + } + } + #addrSwitch.ant-switch-checked { + background-image: ${props => + props.theme.buttons.primary.backgroundImage} !important; + } `; const CustomApp = styled.div` diff --git a/web/cashtab/package-lock.json b/web/cashtab/package-lock.json --- a/web/cashtab/package-lock.json +++ b/web/cashtab/package-lock.json @@ -1,11 +1,11 @@ { "name": "cashtab", - "version": "0.1.8", + "version": "1.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "0.1.8", + "version": "1.0.0", "dependencies": { "@ant-design/icons": "^4.3.0", "@fortawesome/fontawesome-free": "^5.15.1", @@ -15,6 +15,7 @@ "cashaddrjs": "^0.3.12", "dotenv": "^8.2.0", "dotenv-expand": "^5.1.0", + "ecashaddrjs": "^1.0.1", "ethereum-blockies-base64": "^1.0.2", "fbt": "^0.16.4", "localforage": "^1.9.0", @@ -8211,6 +8212,14 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/ecashaddrjs": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ecashaddrjs/-/ecashaddrjs-1.0.1.tgz", + "integrity": "sha512-yozijdSLtuzi0vBj1BJ7MfAy/l7HQSGBfog9Ad+8M5sKT2gkSg5fTx0Rwh1z9heJJunagHXJ8DGsziPH8BKpeQ==", + "dependencies": { + "big-integer": "1.6.36" + } + }, "node_modules/ecc-jsbn": { "version": "0.1.2", "dev": true, @@ -34666,6 +34675,14 @@ } } }, + "ecashaddrjs": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ecashaddrjs/-/ecashaddrjs-1.0.1.tgz", + "integrity": "sha512-yozijdSLtuzi0vBj1BJ7MfAy/l7HQSGBfog9Ad+8M5sKT2gkSg5fTx0Rwh1z9heJJunagHXJ8DGsziPH8BKpeQ==", + "requires": { + "big-integer": "1.6.36" + } + }, "ecc-jsbn": { "version": "0.1.2", "dev": true, diff --git a/web/cashtab/package.json b/web/cashtab/package.json --- a/web/cashtab/package.json +++ b/web/cashtab/package.json @@ -1,6 +1,6 @@ { "name": "cashtab", - "version": "0.1.8", + "version": "1.0.0", "private": true, "homepage": "https://cashtabapp.com/", "dependencies": { @@ -12,6 +12,7 @@ "cashaddrjs": "^0.3.12", "dotenv": "^8.2.0", "dotenv-expand": "^5.1.0", + "ecashaddrjs": "^1.0.1", "ethereum-blockies-base64": "^1.0.2", "fbt": "^0.16.4", "localforage": "^1.9.0", diff --git a/web/cashtab/public/bch128.png b/web/cashtab/public/bch128.png deleted file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@ - + @@ -30,15 +27,16 @@ --> - + Cashtab +
diff --git a/web/cashtab/public/manifest.json b/web/cashtab/public/manifest.json --- a/web/cashtab/public/manifest.json +++ b/web/cashtab/public/manifest.json @@ -8,28 +8,28 @@ "type": "image/x-icon" }, { - "src": "bch48.png", + "src": "ecash48.png", "type": "image/png", "sizes": "48x48" }, { - "src": "bch128.png", + "src": "ecash128.png", "type": "image/png", "sizes": "128x128" }, { - "src": "bch192.png", + "src": "ecash192.png", "type": "image/png", "sizes": "192x192" }, { - "src": "bch512.png", + "src": "ecash512.png", "type": "image/png", "sizes": "512x512" } ], "start_url": ".", "display": "standalone", - "theme_color": "#000000", + "theme_color": "#273498", "background_color": "#ffffff" } diff --git a/web/cashtab/src/assets/12-bitcoin-cash-square-crop.svg b/web/cashtab/src/assets/12-bitcoin-cash-square-crop.svg deleted file mode 100644 --- a/web/cashtab/src/assets/12-bitcoin-cash-square-crop.svg +++ /dev/null @@ -1 +0,0 @@ -12-bitcoin-cash-square-crop \ No newline at end of file diff --git a/web/cashtab/src/assets/4-bitcoin-cash-logo-flag.svg b/web/cashtab/src/assets/4-bitcoin-cash-logo-flag.svg deleted file mode 100644 --- a/web/cashtab/src/assets/4-bitcoin-cash-logo-flag.svg +++ /dev/null @@ -1 +0,0 @@ -4-bitcoin-cash-logo-flag \ No newline at end of file diff --git a/web/cashtab/src/assets/bitcoinabclogo.png b/web/cashtab/src/assets/bitcoinabclogo.png deleted file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@ props.theme.contrast} !important; background-color: ${props => props.theme.primary} !important; } + #addrSwitch { + .ant-switch-checked { + background-color: white !important; + } + } + #addrSwitch.ant-switch-checked { + background-image: ${props => + props.theme.buttons.primary.backgroundImage} !important; + } `; const CustomApp = styled.div` @@ -121,7 +130,8 @@ justify-content: center; width: 100%; min-height: 100vh; - background: ${props => props.theme.app.sidebars}; + background-image: ${props => props.theme.app.sidebars}; + background-attachment: fixed; `; export const WalletCtn = styled.div` @@ -216,7 +226,7 @@ )} diff --git a/web/cashtab/src/components/Common/EnhancedInputs.js b/web/cashtab/src/components/Common/EnhancedInputs.js --- a/web/cashtab/src/components/Common/EnhancedInputs.js +++ b/web/cashtab/src/components/Common/EnhancedInputs.js @@ -23,7 +23,7 @@ box-shadow: none !important; border-radius: 4px; font-weight: bold; - color: ${props => props.theme.wallet.text.secondary}; + color: ${props => props.theme.forms.text}; opacity: 1; height: 50px; } @@ -64,9 +64,16 @@ .ant-select-single .ant-select-selector .ant-select-selection-placeholder { line-height: 60px; text-align: left; - color: ${props => props.theme.wallet.text.secondary}; + color: ${props => props.theme.forms.text}; font-weight: bold; } + .ant-form-item-has-error .ant-input-group-addon { + color: ${props => props.theme.forms.error} !important; + border-color: ${props => props.theme.forms.error} !important; + } + .ant-form-item-explain.ant-form-item-explain-error { + color: ${props => props.theme.forms.error} !important; + } `; export const AntdFormWrapper = styled.div` diff --git a/web/cashtab/src/components/Common/QRCode.js b/web/cashtab/src/components/Common/QRCode.js --- a/web/cashtab/src/components/Common/QRCode.js +++ b/web/cashtab/src/components/Common/QRCode.js @@ -1,9 +1,14 @@ import React, { useState } from 'react'; import styled from 'styled-components'; import RawQRCode from 'qrcode.react'; -import { currency } from '@components/Common/Ticker.js'; +import { + currency, + isValidCashPrefix, + isValidTokenPrefix, +} from '@components/Common/Ticker.js'; import { CopyToClipboard } from 'react-copy-to-clipboard'; import { Event } from '@utils/GoogleAnalytics'; +import { convertToEcashPrefix } from '@utils/cashMethods'; export const StyledRawQRCode = styled(RawQRCode)` cursor: pointer; @@ -34,6 +39,11 @@ background-color: ${({ bch = 0, ...props }) => bch === 1 ? props.theme.primary : props.theme.qr.token}; + border: 1px solid; + border-color: ${({ bch = 0, ...props }) => + bch === 1 + ? props.theme.qr.copyBorderCash + : props.theme.qr.copyBorderToken}; color: ${props => props.theme.contrast}; position: absolute; top: 65px; @@ -49,8 +59,8 @@ color: ${props => props.theme.wallet.text.secondary}; text-align: center; cursor: pointer; - margin-bottom: 15px; - padding: 10px 0; + margin-bottom: 0px; + padding: 6px 0; font-family: 'Roboto Mono', monospace; border-radius: 5px; @@ -105,12 +115,24 @@ export const QRCode = ({ address, + legacy, size = 210, onClick = () => null, ...otherProps }) => { const [visible, setVisible] = useState(false); - const trimAmount = 6; + const trimAmount = 8; + // Set address format to legacy or not + + if (!legacy) { + address = address ? convertToEcashPrefix(address) : ''; + } + // get the prefix + const addressSplit = address ? address.split(':') : ['']; + const addressPrefix = addressSplit[0]; + const prefixLength = addressPrefix.length + 1; + + const isCash = isValidCashPrefix(address); const address_trim = address ? address.length - trimAmount : ''; @@ -129,7 +151,7 @@ // BCH or slp? let eventLabel = currency.ticker; if (address) { - const isToken = address.includes(currency.tokenPrefix); + const isToken = isValidTokenPrefix(address); if (isToken) { eventLabel = currency.tokenTicker; } @@ -155,28 +177,29 @@ >
- Copied + Copied
+ {address}
@@ -192,20 +215,11 @@ /> {address.slice( - address.includes('bitcoin') ? 12 : 13, - address.includes('bitcoin') - ? 12 + trimAmount - : 13 + trimAmount, + prefixLength, + prefixLength + trimAmount, )} - {address.slice( - address.includes('bitcoin') - ? 12 + trimAmount - : 13 + trimAmount, - address.includes('bitcoin') - ? address_trim - : address_trim, - )} + {address.slice(prefixLength + trimAmount, address_trim)} {address.slice(-trimAmount)} )} diff --git a/web/cashtab/src/components/Common/Ticker.js b/web/cashtab/src/components/Common/Ticker.js --- a/web/cashtab/src/components/Common/Ticker.js +++ b/web/cashtab/src/components/Common/Ticker.js @@ -1,23 +1,23 @@ -import mainLogo from '@assets/12-bitcoin-cash-square-crop.svg'; -import tokenLogo from '@assets/simple-ledger-protocol-logo.png'; +import mainLogo from '@assets/logo_primary.png'; +import tokenLogo from '@assets/logo_secondary.png'; import cashaddr from 'cashaddrjs'; import BigNumber from 'bignumber.js'; export const currency = { - name: 'Bitcoin ABC', - ticker: 'BCHA', + name: 'eCash', + ticker: 'XEC', logo: mainLogo, legacyPrefix: 'bitcoincash', prefixes: ['bitcoincash', 'ecash'], coingeckoId: 'bitcoin-cash-abc-2', defaultFee: 2.01, dustSats: 546, - cashDecimals: 8, + cashDecimals: 2, blockExplorerUrl: 'https://explorer.bitcoinabc.org', tokenExplorerUrl: 'https://explorer.be.cash', blockExplorerUrlTestnet: 'https://texplorer.bitcoinabc.org', - tokenName: 'Bitcoin ABC SLP', - tokenTicker: 'SLPA', + tokenName: 'eToken', + tokenTicker: 'eToken', tokenLogo: tokenLogo, tokenPrefixes: ['simpleledger', 'etoken'], tokenIconsUrl: '', //https://tokens.bitcoin.com/32 for BCH SLP diff --git a/web/cashtab/src/components/Common/__tests__/QRCode.test.js b/web/cashtab/src/components/Common/__tests__/QRCode.test.js --- a/web/cashtab/src/components/Common/__tests__/QRCode.test.js +++ b/web/cashtab/src/components/Common/__tests__/QRCode.test.js @@ -15,6 +15,7 @@ pixelRatio={25} onClick={OnClick} address="bitcoincash:qqyumjtrftl5yfdwuglhq6l9af2ner39jq6z6ja5zp" + legacy={true} /> , ); @@ -37,6 +38,7 @@ pixelRatio={25} onClick={OnClick} address="simpleledger:qqyumjtrftl5yfdwuglhq6l9af2ner39jq6z6ja5zp" + legacy={true} /> , ); diff --git a/web/cashtab/src/components/Configure/Configure.js b/web/cashtab/src/components/Configure/Configure.js --- a/web/cashtab/src/components/Configure/Configure.js +++ b/web/cashtab/src/components/Configure/Configure.js @@ -34,6 +34,9 @@ text-decoration: underline; color: ${props => props.theme.primary}; } + :hover { + color: ${props => props.theme.brandSecondary}; + } `; const SWRow = styled.div` @@ -143,7 +146,7 @@ const StyledConfigure = styled.div` h2 { - color: ${props => props.theme.wallet.text.secondary}; + color: ${props => props.theme.wallet.text.primary}; font-size: 25px; } p { diff --git a/web/cashtab/src/components/Configure/__tests__/__snapshots__/Configure.test.js.snap b/web/cashtab/src/components/Configure/__tests__/__snapshots__/Configure.test.js.snap --- a/web/cashtab/src/components/Configure/__tests__/__snapshots__/Configure.test.js.snap +++ b/web/cashtab/src/components/Configure/__tests__/__snapshots__/Configure.test.js.snap @@ -33,12 +33,12 @@ className="ant-spin-container ant-spin-blur" >

[

[ - = {fiatPriceString} + {priceApiError && ( + + Error fetching fiat price. Setting send by + USD disabled + + )} + + {fiatPriceString !== '' && '='}{' '} + {fiatPriceString} +
{ const { wallet, tokens, slpBalancesAndUtxos, apiError } = React.useContext( @@ -109,6 +113,9 @@ // Clear params from address let cleanAddress = address.split('?')[0]; + // Convert to simpleledger prefix if etoken + cleanAddress = convertEtokenToSimpleledger(cleanAddress); + try { const link = await sendToken(BCH, wallet, slpBalancesAndUtxos, { tokenId: tokenId, diff --git a/web/cashtab/src/components/Send/__tests__/__snapshots__/Send.test.js.snap b/web/cashtab/src/components/Send/__tests__/__snapshots__/Send.test.js.snap --- a/web/cashtab/src/components/Send/__tests__/__snapshots__/Send.test.js.snap +++ b/web/cashtab/src/components/Send/__tests__/__snapshots__/Send.test.js.snap @@ -3,14 +3,14 @@ exports[`Wallet with BCH balances 1`] = ` Array [
0.06047469 - BCHA + XEC
,
$ NaN @@ -43,7 +43,7 @@ } >
@@ -204,7 +204,7 @@ onKeyDown={[Function]} placeholder="Amount" required={true} - step={1e-8} + step={0.01} style={null} type="number" value="" @@ -261,9 +261,9 @@ - BCHA + XEC
- = + = + $ NaN USD
+
, +
- BCHA + XEC
- SLPA + eToken
, ] @@ -103,14 +140,14 @@ exports[`Wallet with BCH balances and tokens 1`] = ` Array [
0.06047469 - BCHA + XEC
,
$ NaN @@ -128,73 +165,110 @@ } >
- Copied + Copied +
+ + ecash:qzagy47mvh6qxkvcn3acjnz73rkhkc6y7ccxkrr6zd +
- qzagy4 + qzagy47m - 7mvh6qxkvcn3acjnz73rkhkc6y7cpt + vh6qxkvcn3acjnz73rkhkc6y7c - zgcqy6 + cxkrr6zd
,
+ + Address Format: + + +
, +
- BCHA + XEC
- SLPA + eToken
, ] @@ -203,14 +277,14 @@ exports[`Wallet with BCH balances and tokens and state field 1`] = ` Array [
0.06047469 - BCHA + XEC
,
$ NaN @@ -228,73 +302,110 @@ } >
- Copied + Copied +
+ + ecash:qzagy47mvh6qxkvcn3acjnz73rkhkc6y7ccxkrr6zd +
- qzagy4 + qzagy47m - 7mvh6qxkvcn3acjnz73rkhkc6y7cpt + vh6qxkvcn3acjnz73rkhkc6y7c - zgcqy6 + cxkrr6zd
,
+ + Address Format: + + +
, +
- BCHA + XEC
- SLPA + eToken
, ] @@ -303,14 +414,14 @@ exports[`Wallet with BCH balances and tokens and state field, but no params in state 1`] = ` Array [
0.06047469 - BCHA + XEC
,
$ NaN @@ -328,73 +439,110 @@ } >
- Copied + Copied +
+ + ecash:qzagy47mvh6qxkvcn3acjnz73rkhkc6y7ccxkrr6zd +
- qzagy4 + qzagy47m - 7mvh6qxkvcn3acjnz73rkhkc6y7cpt + vh6qxkvcn3acjnz73rkhkc6y7c - zgcqy6 + cxkrr6zd
,
+ + Address Format: + + +
, +
- BCHA + XEC
- SLPA + eToken
, ] @@ -403,7 +551,7 @@ exports[`Wallet without BCH balance 1`] = ` Array [
Start using the wallet immediately to receive - BCHA + XEC payments, or load it up with - BCHA + XEC to send to others
,
0 - BCHA + XEC
,
- Copied + Copied +
+ + ecash:qzagy47mvh6qxkvcn3acjnz73rkhkc6y7ccxkrr6zd +
- qzagy4 + qzagy47m - 7mvh6qxkvcn3acjnz73rkhkc6y7cpt + vh6qxkvcn3acjnz73rkhkc6y7c - zgcqy6 + cxkrr6zd
,
+ + Address Format: + + +
, +
- BCHA + XEC
- SLPA + eToken
, ] @@ -523,12 +708,12 @@ Welcome to Cashtab!

,

Cashtab is an non-custodial web wallet for - Bitcoin ABC + eCash .

Want to learn more?

,