diff --git a/web/cashtab-components/README.md b/web/cashtab-components/README.md index bc8302a66..22f29b16c 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 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 +- [ ] eToken invoices - [ ] OP Return text - [ ] successFn and failureFn props - [ ] Bip70-style invoices - [ ] Websocket monitoring of payment status # Build on eCash (XEC) 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://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 XEC */} - {/* Price in SLP tokens - NAKAMOTO in this example */} + {/* Price in eTokens - 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 XEC */} ); }; 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/src/components/CashtabBadge/CashtabBadge.stories.tsx b/web/cashtab-components/src/components/CashtabBadge/CashtabBadge.stories.tsx index 3abf2298c..ccc01c869 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: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm', }; export const MostProps = Template.bind({}); MostProps.args = { price: 0.0025, currency: 'GBP', 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: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm', showAmount: false, showQR: true, }; export const Fiat = Template.bind({}); Fiat.args = { price: 3.5, currency: 'CAD', text: 'Pay with Cashtab', to: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm', }; Fiat.storyName = 'price in fiat'; export const XEC = Template.bind({}); XEC.args = { coinType: Ticker.coinSymbol, amount: 0.33, to: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm', }; XEC.storyName = `price in ${Ticker.coinSymbol}`; -export const SLPA = Template.bind({}); -SLPA.args = { +export const eToken = Template.bind({}); +eToken.args = { coinType: Ticker.tokenTicker, tokenId: tokenIdOptions[0], amount: 100, to: 'etoken:qrcl220pxeec78vnchwyh6fsdyf60uv9tcnqnc3hmv', showQR: true, }; -SLPA.storyName = `price in ${Ticker.tokenTicker}`; +eToken.storyName = `price in ${Ticker.tokenTicker}`; export const StepControlled = Template.bind({}); StepControlled.args = { amount: 0.012, 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 558bdcac7..8bf7b06ae 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: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm', }; export const MostProps = Template.bind({}); MostProps.args = { price: 0.0025, currency: 'GBP', 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: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm', showAmount: false, showQR: true, }; export const Fiat = Template.bind({}); Fiat.args = { price: 3.5, currency: 'CAD', text: 'Pay with Cashtab', to: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm', }; Fiat.storyName = 'price in fiat'; export const XEC = Template.bind({}); XEC.args = { coinType: Ticker.coinSymbol, amount: 0.33, to: 'ecash:qrcl220pxeec78vnchwyh6fsdyf60uv9tca7668slm', }; XEC.storyName = `price in ${Ticker.coinSymbol}`; -export const SLPA = Template.bind({}); -SLPA.args = { +export const eToken = Template.bind({}); +eToken.args = { coinType: Ticker.tokenTicker, tokenId: tokenIdOptions[0], amount: 100, to: 'etoken:qrcl220pxeec78vnchwyh6fsdyf60uv9tcnqnc3hmv', showQR: true, }; -SLPA.storyName = `price in ${Ticker.tokenTicker}`; +eToken.storyName = `price in ${Ticker.tokenTicker}`; export const StepControlled = Template.bind({}); StepControlled.args = { amount: 0.012, 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/README.md b/web/cashtab-components/src/components/PriceDisplay/README.md index f0be03401..c0597a05a 100644 --- a/web/cashtab-components/src/components/PriceDisplay/README.md +++ b/web/cashtab-components/src/components/PriceDisplay/README.md @@ -1,7 +1,7 @@ # PriceDisplay -Show a price display item in fiat, XEC, or SLPA. +Show a price display item in fiat, XEC, or eToken. For open BIP70 invoices, get price and currency info from the invoice. Used in CashtabBadge and CashtabButton. Useful tool when building custom Cashtab integrations.