diff --git a/web/cashtab-components/README.md b/web/cashtab-components/README.md
index 8620f372a..f0a5690ae 100644
--- a/web/cashtab-components/README.md
+++ b/web/cashtab-components/README.md
@@ -1,206 +1,206 @@
# Cashtab React Components
-Interact with the Cashtab wallet to support BCHA payments in web apps. Download the Cashtab extension [here](https://chrome.google.com/webstore/detail/cashtab/obldfcmebhllhjlhjbnghaipekcppeag)
+Interact with the Cashtab wallet to support eCash payments in web apps. Download the Cashtab extension [here](https://chrome.google.com/webstore/detail/cashtab/obldfcmebhllhjlhjbnghaipekcppeag)
This project is based on [badger-components-react](https://github.com/Bitcoin-com/badger-components-react)
## Notes
Some features from `badger-components-react` are not yet fully supported. Upcoming features:
- [ ] SLPA transactions
- [ ] OP Return text
- [ ] successFn and failureFn props
- [ ] Bip70-style invoices
- [ ] Websocket monitoring of payment status
-# Build on Bitcoin ABC (BCHA)
+# Build on eCash (XEC)
-A set of React components and helpers to integrate Bitcoin ABC (BCHA) and tokens into your app with ease. Integrates with the Cashtab wallet.
+A set of React components and helpers to integrate eCash (XEC) and tokens into your app with ease. Integrates with the Cashtab wallet.
## Get Started
-- [Homepage](https://bitcoinabc.org)
+- [Homepage](https://e.cash/)
- [Component Showcase](https://laughing-villani-8cfcaf.netlify.app/)
- [Cashtab Extension](https://chrome.google.com/webstore/detail/cashtab/obldfcmebhllhjlhjbnghaipekcppeag)
- [NPM page](https://www.npmjs.com/package/cashtab-components)
### Install Component
```bash
$ npm install --save cashtab-components
```
### Install Peer Dependencies
This library depends on the following three peer dependencies
- `styled-components` ^4.4.1
```bash
$ npm install --save styled-components@4.4.1
```
### Add to React Project
```js
import { CashtabButton, CashtabBadge } from 'cashtab-components';
const Example = props => {
// eatBCH bitcoin cash address
const toAddress = 'bitcoincash:pp8skudq3x5hzw8ew7vzsw8tn4k8wxsqsv0lt0mf3g';
// Random SLP address
const toSLPAddress =
'simpleledger:qq6qcjt6xlkeqzdwkhdvfyl2q2d2wafkgg8phzcqez';
// tokenId
const nakamotoID =
'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb';
return (
<>
{/* Minimal Examples */}
{/* Price in bcha */}
{/* Price in SLP tokens - NAKAMOTO in this example */}
{/* More Complex Examples, pricing in fiat */}
console.log('Payment success callback')}
failFn={() =>
console.warn('Payment failed or cancelled callback')
}
/>
console.log('success example function called')}
failFn={() => console.log('fail example function called')}
/>
{/* Pricing in BCHA */}
>
);
};
export default Example;
```
### Create a Custom Cashtab Button / Integration
```js
import React from 'react'
import { CashtabBase, formatAmount } from 'cashtab-components'
import styled from 'styled-components'
const CoolButton = styled.button`
background-color: rebeccapurple;
color: lime;
border-radius: 24px;
`
const MyButton extends React.Component {
render() {
// Props from higher order component
const {
handleClick,
to,
step,
price,
currency,
coinType,
coinDecimals,
coinSymbol,
amount,
showQR,
isRepeatable,
repeatTimeout,
watchAddress,
} = this.props;
return (
Donate {price}{currency} to {to}
Satoshis: {formatAmount(amount, coinDecimals)}
Custom looking button with render
)
}
}
// Wrap with CashtabBase higher order component
export default CashtabBase(MyButton);
```
### Control Step from app
When accepting payments, the state of the payment should be handled by the backend of your application. As such, you can pass in `stepControlled` with the values of `fresh`, `pending` or `complete` to indicate which part of the payment the user is on.
## Development with Storybook
To develop additions to this project, run the local storybook development server with
### Setup
```bash
$ npm i
$ npm run storybook
```
Navigate to [http://localhost:9001](http://localhost:9001) to view your stories. They automatically update as you develop ✨.
Storybook will pick up stories from the `*stories.tsx` file in each components folder.
To build a static version of storybook for deployment
```bash
$ npm run build-storybook
Deploy contents of `/storybook-static`
```
diff --git a/web/cashtab-components/package.json b/web/cashtab-components/package.json
index daebd3078..fca0637db 100644
--- a/web/cashtab-components/package.json
+++ b/web/cashtab-components/package.json
@@ -1,123 +1,125 @@
{
"name": "cashtab-components",
- "version": "0.0.4",
+ "version": "1.0.0",
"description": "Integrate the Cashtab Wallet into your React app with ease.",
"main": "dist/index",
"typings": "dist/index",
"peerDependencies": {
"react": "^17.0.1",
"react-dom": "^17.0.1"
},
"dependencies": {
"@babel/preset-typescript": "^7.12.7",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@types/node": "^12.0.0",
"@types/react": "^16.9.53",
"@types/react-dom": "^16.9.8",
"bignumber.js": "^9.0.1",
"qrcode.react": "^1.0.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-scripts": "4.0.1",
"styled-components": "4.4.1",
"typescript": "^4.0.3",
"web-vitals": "^0.2.4",
"webpack": "^4.44.2",
"webpack-bundle-analyzer": "^4.3.0",
"webpack-cli": "^4.3.0"
},
"scripts": {
"start": "npm run storybook",
"build": "rm -rf dist/ && webpack --mode=production",
"prepublish": "npm run build",
"test": "jest",
"eject": "react-scripts eject",
"storybook": "start-storybook -p 6006 -s public",
"build-storybook": "build-storybook -s public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/josephroyking/cashtab-components.git"
},
"keywords": [
"cashtab",
"bitcoin abc",
+ "ecash",
+ "XEC",
+ "etoken",
"web payments",
"react component",
- "BCHA",
"cashtab button",
"crypto payments",
"crypto"
],
"author": "Joey King ",
"bugs": {
"url": "https://github.com/josephroyking/cashtab-components/issues"
},
"homepage": "https://github.com/josephroyking/cashtab-components#readme",
"license": "MIT",
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@babel/core": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"@storybook/addon-actions": "^6.1.11",
"@storybook/addon-essentials": "^6.1.11",
"@storybook/addon-knobs": "^6.1.11",
"@storybook/addon-links": "^6.1.11",
"@storybook/addons": "^6.1.11",
"@storybook/node-logger": "^6.1.11",
"@storybook/preset-create-react-app": "^3.1.5",
"@storybook/react": "^6.1.11",
"@storybook/theming": "^6.1.11",
"@types/jest": "^26.0.19",
"@types/lodash": "^4.14.165",
"@types/qrcode.react": "^1.0.1",
"@types/styled-components": "^5.1.7",
"babel-jest": "^26.6.3",
"jest": "^26.6.0",
"jest-environment-jsdom-fifteen": "^1.0.2",
"jest-junit": "^12.0.0",
"ts-loader": "^8.0.12"
},
"jest": {
"roots": [
"/src"
],
"setupFiles": [
"react-app-polyfill/jsdom"
],
"testMatch": [
"/src/**/__tests__/**/*.{js,jsx,ts,tsx}",
"/src/**/*.{spec,test}.{js,jsx,ts,tsx}"
],
"testEnvironment": "jest-environment-jsdom-fifteen",
"transform": {
"^.+\\.(js|jsx|ts|tsx)$": "/node_modules/babel-jest"
},
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$",
"^.+\\.module\\.(css|sass|scss)$"
],
"moduleNameMapper": {
".+\\.(css|styl|less|sass|scss|png|jpg|svg|ttf|woff|woff2)$": "identity-obj-proxy"
}
}
}
diff --git a/web/cashtab-components/public/cashtab-components.png b/web/cashtab-components/public/cashtab-components.png
index 25fe08269..e9f8023ac 100644
Binary files a/web/cashtab-components/public/cashtab-components.png and b/web/cashtab-components/public/cashtab-components.png differ
diff --git a/web/cashtab-components/public/favicon.ico b/web/cashtab-components/public/favicon.ico
index db48048f6..a4f74e528 100644
Binary files a/web/cashtab-components/public/favicon.ico and b/web/cashtab-components/public/favicon.ico differ
diff --git a/web/cashtab-components/src/atoms/Ticker/Ticker.tsx b/web/cashtab-components/src/atoms/Ticker/Ticker.tsx
index 0e2ae843e..48005593f 100644
--- a/web/cashtab-components/src/atoms/Ticker/Ticker.tsx
+++ b/web/cashtab-components/src/atoms/Ticker/Ticker.tsx
@@ -1,24 +1,24 @@
-import mainLogo from '../../images/12-bitcoin-cash-square-crop.svg';
-import tokenLogo from '../../images/simple-ledger-protocol-logo.png';
+import mainLogo from '../../images/logo_primary.png';
+import tokenLogo from '../../images/logo_secondary.png';
const Ticker = {
installLink:
'https://chrome.google.com/webstore/detail/cashtab/obldfcmebhllhjlhjbnghaipekcppeag',
- coinName: 'Bitcoin ABC',
- coinDecimals: 8,
- coinSymbol: 'BCHA',
+ coinName: 'eCash',
+ coinDecimals: 2,
+ coinSymbol: 'XEC',
logo: mainLogo,
- prefix: 'bitcoincash:',
+ prefix: 'ecash:',
coingeckoId: 'bitcoin-cash-abc-2',
defaultFee: 5.01,
blockExplorerUrl: 'https://explorer.bitcoinabc.org',
blockExplorerUrlTestnet: 'https://texplorer.bitcoinabc.org',
- tokenName: 'Bitcoin ABC SLP',
- tokenTicker: 'SLPA',
+ tokenName: 'eToken',
+ tokenTicker: 'eToken',
tokenLogo: tokenLogo,
- tokenPrefix: 'simpleledger:',
+ tokenPrefix: 'etoken:',
tokenIconsUrl: '', //https://tokens.bitcoin.com/32 for BCH SLP
useBlockchainWs: false,
};
export default Ticker;
diff --git a/web/cashtab-components/src/components/CashtabBadge/CashtabBadge.stories.tsx b/web/cashtab-components/src/components/CashtabBadge/CashtabBadge.stories.tsx
index 6053afba2..a31985cc3 100644
--- a/web/cashtab-components/src/components/CashtabBadge/CashtabBadge.stories.tsx
+++ b/web/cashtab-components/src/components/CashtabBadge/CashtabBadge.stories.tsx
@@ -1,109 +1,109 @@
import { Meta, Story } from '@storybook/react/types-6-0';
import CashtabBadge from './CashtabBadge';
import type { CashtabBadgeProps } from './CashtabBadge';
import { currencyOptions } from '../../utils/currency-helpers';
import Ticker from '../../atoms/Ticker';
// [ SPICE, NAKAMOTO, DOGECASH, BROC ]
const tokenIdOptions = [
'4de69e374a8ed21cbddd47f2338cc0f479dc58daa2bbe11cd604ca488eca0ddf',
'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb',
'3916a24a051f8b3833a7fd128be51dd93015555ed9142d6106ec03267f5cdc4c',
'259908ae44f46ef585edef4bcc1e50dc06e4c391ac4be929fae27235b8158cf1',
];
const Template: Story = (args: CashtabBadgeProps) => (
);
export const Standard = Template.bind({});
Standard.args = {
price: 0.05,
currency: 'USD',
- to: 'bitcoincash:qrcl220pxeec78vnchwyh6fsdyf60uv9tcynw3u2ev',
+ to: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm',
};
export const MostProps = Template.bind({});
MostProps.args = {
price: 0.0025,
currency: 'GBP',
- to: 'bitcoincash:qrcl220pxeec78vnchwyh6fsdyf60uv9tcynw3u2ev',
+ to: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm',
isRepeatable: true,
repeatTimeout: 4000,
text: 'My Cash Button',
showAmount: true,
showBorder: true,
showQR: false,
};
export const Minimal = Template.bind({});
Minimal.args = {
amount: 0.01,
- to: 'bitcoincash:qrcl220pxeec78vnchwyh6fsdyf60uv9tcynw3u2ev',
+ to: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm',
showAmount: false,
showQR: true,
};
export const Fiat = Template.bind({});
Fiat.args = {
price: 3.5,
currency: 'CAD',
text: 'Pay with Cashtab',
- to: 'bitcoincash:qrcl220pxeec78vnchwyh6fsdyf60uv9tcynw3u2ev',
+ to: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm',
};
Fiat.storyName = 'price in fiat';
export const BCHA = Template.bind({});
BCHA.args = {
coinType: Ticker.coinSymbol,
amount: 0.33,
- to: 'bitcoincash:qrcl220pxeec78vnchwyh6fsdyf60uv9tcynw3u2ev',
+ to: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm',
};
BCHA.storyName = `price in ${Ticker.coinSymbol}`;
export const SLPA = Template.bind({});
SLPA.args = {
coinType: Ticker.tokenTicker,
tokenId: tokenIdOptions[0],
amount: 100,
- to: 'simpleledger:qqvcsnz9x9nu7vq35vmrkjc7hkfxhhs9nuqw7ew08n',
+ to: 'etoken:qrcl220pxeec78vnchwyh6fsdyf60uv9tcnqnc3hmv',
showQR: true,
};
SLPA.storyName = `price in ${Ticker.tokenTicker}`;
export const StepControlled = Template.bind({});
StepControlled.args = {
amount: 0.012,
- to: 'bitcoincash:qrcl220pxeec78vnchwyh6fsdyf60uv9tcynw3u2ev',
+ to: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm',
stepControlled: 'fresh',
};
StepControlled.storyName = `Controlled Step`;
export default {
title: 'CashtabBadge',
component: CashtabBadge,
argTypes: {
currency: {
control: {
type: 'select',
options: currencyOptions,
},
},
tokenId: {
control: {
type: 'select',
options: tokenIdOptions,
},
},
stepControlled: {
control: {
type: 'select',
options: ['fresh', 'pending', 'complete'],
},
},
},
} as Meta;
diff --git a/web/cashtab-components/src/components/CashtabButton/CashtabButton.stories.tsx b/web/cashtab-components/src/components/CashtabButton/CashtabButton.stories.tsx
index 11bc50534..4f4e53887 100644
--- a/web/cashtab-components/src/components/CashtabButton/CashtabButton.stories.tsx
+++ b/web/cashtab-components/src/components/CashtabButton/CashtabButton.stories.tsx
@@ -1,109 +1,109 @@
import { Meta, Story } from '@storybook/react/types-6-0';
import CashtabButton from './CashtabButton';
import type { CashtabButtonProps } from './CashtabButton';
import { currencyOptions } from '../../utils/currency-helpers';
import Ticker from '../../atoms/Ticker';
// [ SPICE, NAKAMOTO, DOGECASH, BROC ]
const tokenIdOptions = [
'4de69e374a8ed21cbddd47f2338cc0f479dc58daa2bbe11cd604ca488eca0ddf',
'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb',
'3916a24a051f8b3833a7fd128be51dd93015555ed9142d6106ec03267f5cdc4c',
'259908ae44f46ef585edef4bcc1e50dc06e4c391ac4be929fae27235b8158cf1',
];
const Template: Story = (args: CashtabButtonProps) => (
);
export const Standard = Template.bind({});
Standard.args = {
price: 0.05,
currency: 'USD',
- to: 'bitcoincash:qrcl220pxeec78vnchwyh6fsdyf60uv9tcynw3u2ev',
+ to: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm',
};
export const MostProps = Template.bind({});
MostProps.args = {
price: 0.0025,
currency: 'GBP',
- to: 'bitcoincash:qrcl220pxeec78vnchwyh6fsdyf60uv9tcynw3u2ev',
+ to: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm',
isRepeatable: true,
repeatTimeout: 4000,
text: 'My Cash Button',
showAmount: true,
showBorder: true,
showQR: false,
};
export const Minimal = Template.bind({});
Minimal.args = {
amount: 0.01,
- to: 'bitcoincash:qrcl220pxeec78vnchwyh6fsdyf60uv9tcynw3u2ev',
+ to: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm',
showAmount: false,
showQR: true,
};
export const Fiat = Template.bind({});
Fiat.args = {
price: 3.5,
currency: 'CAD',
text: 'Pay with Cashtab',
- to: 'bitcoincash:qrcl220pxeec78vnchwyh6fsdyf60uv9tcynw3u2ev',
+ to: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm',
};
Fiat.storyName = 'price in fiat';
export const BCHA = Template.bind({});
BCHA.args = {
coinType: Ticker.coinSymbol,
amount: 0.33,
- to: 'bitcoincash:qrcl220pxeec78vnchwyh6fsdyf60uv9tcynw3u2ev',
+ to: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm',
};
BCHA.storyName = `price in ${Ticker.coinSymbol}`;
export const SLPA = Template.bind({});
SLPA.args = {
coinType: Ticker.tokenTicker,
tokenId: tokenIdOptions[0],
amount: 100,
- to: 'simpleledger:qqvcsnz9x9nu7vq35vmrkjc7hkfxhhs9nuqw7ew08n',
+ to: 'etoken:qrcl220pxeec78vnchwyh6fsdyf60uv9tcnqnc3hmv',
showQR: true,
};
SLPA.storyName = `price in ${Ticker.tokenTicker}`;
export const StepControlled = Template.bind({});
StepControlled.args = {
amount: 0.012,
- to: 'bitcoincash:qrcl220pxeec78vnchwyh6fsdyf60uv9tcynw3u2ev',
+ to: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm',
stepControlled: 'fresh',
};
StepControlled.storyName = `Controlled Step`;
export default {
title: 'CashtabButton',
component: CashtabButton,
argTypes: {
currency: {
control: {
type: 'select',
options: currencyOptions,
},
},
tokenId: {
control: {
type: 'select',
options: tokenIdOptions,
},
},
stepControlled: {
control: {
type: 'select',
options: ['fresh', 'pending', 'complete'],
},
},
},
} as Meta;
diff --git a/web/cashtab-components/src/components/PriceDisplay/PriceDisplay.stories.tsx b/web/cashtab-components/src/components/PriceDisplay/PriceDisplay.stories.tsx
index 8a6429ef6..621998a38 100644
--- a/web/cashtab-components/src/components/PriceDisplay/PriceDisplay.stories.tsx
+++ b/web/cashtab-components/src/components/PriceDisplay/PriceDisplay.stories.tsx
@@ -1,75 +1,75 @@
import React from 'react';
import Ticker from '../../atoms/Ticker';
import { storiesOf } from '@storybook/react/dist/client/preview';
import { select, number } from '@storybook/addon-knobs';
import PriceDisplay from './PriceDisplay';
import { currencyOptions } from '../../utils/currency-helpers';
import {
getCurrencyPreSymbol,
formatPriceDisplay,
formatAmount,
} from '../../utils/cashtab-helpers';
storiesOf('Price Display', module)
.addDecorator(story => (