@daimo/pay 1.1.1 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.d.ts CHANGED
@@ -345,6 +345,9 @@ type ContextValue = {
345
345
  paymentState: PaymentState;
346
346
  /** TRPC API client. Internal use only. */
347
347
  trpc: any;
348
+ /** Custom message to display on confirmation page. */
349
+ confirmationMessage?: string;
350
+ setConfirmationMessage: React$1.Dispatch<React$1.SetStateAction<string | undefined>>;
348
351
  } & useConnectCallbackProps;
349
352
  /** Meant for internal use. This will be non-exported in a future SDK version. */
350
353
  declare const Context: React$1.Context<ContextValue | null>;
@@ -448,6 +451,10 @@ type PayButtonCommonProps = PayButtonPaymentProps & {
448
451
  onPaymentBounced?: (event: PaymentBouncedEvent) => void;
449
452
  /** Automatically close the modal after a successful payment. */
450
453
  closeOnSuccess?: boolean;
454
+ /** Open the modal by default. */
455
+ defaultOpen?: boolean;
456
+ /** Custom message to display on confirmation page. */
457
+ confirmationMessage?: string;
451
458
  };
452
459
  type DaimoPayButtonProps = PayButtonCommonProps & {
453
460
  /** Light mode, dark mode, or auto. */
@@ -1,5 +1,5 @@
1
1
  var name = "@daimo/pay";
2
- var version = "1.1.1";
2
+ var version = "1.1.3";
3
3
  var author = "Daimo";
4
4
  var homepage = "https://pay.daimo.com";
5
5
  var license = "BSD-2-Clause license";
@@ -38,8 +38,8 @@ var keywords = [
38
38
  "crypto"
39
39
  ];
40
40
  var dependencies = {
41
- "@daimo/common": "0.3.17",
42
- "@daimo/contract": "0.3.17",
41
+ "@daimo/common": "0.3.18",
42
+ "@daimo/contract": "0.3.18",
43
43
  "@solana/wallet-adapter-base": "^0.9.23",
44
44
  "@solana/wallet-adapter-react": "^0.15.35",
45
45
  "@solana/web3.js": "^1.95.4",
@@ -69,7 +69,7 @@ const OptionItem = ({ option }) => {
69
69
  return (jsx(IconStackContainer, { children: hydratedIcons.map((icon, index) => (jsx(IconStackItem, { "$marginRight": index !== hydratedIcons.length - 1 ? -12 : 0, "$zIndex": hydratedIcons.length - index, children: icon }, index))) }));
70
70
  }
71
71
  })();
72
- return (jsxs(OptionButton, { type: "button", onClick: option.onClick, children: [iconContent, jsxs(OptionLabel, { children: [jsx(OptionTitle, { children: option.title }), option.subtitle && jsx(OptionSubtitle, { children: option.subtitle })] })] }));
72
+ return (jsxs(OptionButton, { type: "button", onClick: option.onClick, disabled: option.disabled, children: [iconContent, jsxs(OptionLabel, { children: [jsx(OptionTitle, { children: option.title }), option.subtitle && jsx(OptionSubtitle, { children: option.subtitle })] })] }));
73
73
  };
74
74
  const IconStackContainer = styled(motion.div) `
75
75
  position: absolute;
@@ -1,18 +1,34 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { motion } from 'framer-motion';
3
+ import { useState, useEffect } from 'react';
4
+ import { keyframes } from 'styled-components';
3
5
  import CrepeIcon from '../../../assets/crepe.js';
4
6
  import styled from '../../../styles/styled/index.js';
5
7
 
6
- const PoweredByFooter = () => {
8
+ const PoweredByFooter = ({ supportUrl } = {}) => {
9
+ const [supportVisible, setSupportVisible] = useState(false);
10
+ useEffect(() => {
11
+ if (supportUrl == null)
12
+ return;
13
+ // Show the support link after delay
14
+ const timer = setTimeout(() => {
15
+ setSupportVisible(true);
16
+ }, 2500);
17
+ return () => clearTimeout(timer);
18
+ }, []);
7
19
  return (jsx(Container, { children: jsxs(TextButton, { onClick: () => {
8
- window.open("https://pay.daimo.com?ref=paykit", "_blank");
9
- }, children: [jsx(CrepeIcon, {}), "Powered by Daimo Pay"] }) }));
20
+ window.open(supportVisible ? supportUrl : "https://pay.daimo.com?ref=paykit", "_blank");
21
+ }, className: supportVisible ? "support" : "", children: [!supportVisible && jsx(CrepeIcon, {}), jsx("span", { children: supportVisible ? (jsxs(Fragment, { children: ["Need help? ", jsx(Underline, { children: "Contact support" })] })) : (jsx(Fragment, { children: "Powered by Daimo Pay" })) })] }) }));
10
22
  };
11
23
  const Container = styled(motion.div) `
12
24
  text-align: center;
13
25
  margin-top: 16px;
14
26
  margin-bottom: -4px;
15
27
  `;
28
+ const fadeIn = keyframes `
29
+ 0%{ opacity:0; }
30
+ 100%{ opacity:1; }
31
+ `;
16
32
  const TextButton = styled(motion.button) `
17
33
  appearance: none;
18
34
  user-select: none;
@@ -29,6 +45,7 @@ const TextButton = styled(motion.button) `
29
45
  font-size: 15px;
30
46
  line-height: 18px;
31
47
  font-weight: 500;
48
+
32
49
  transition:
33
50
  color 200ms ease,
34
51
  transform 100ms ease;
@@ -38,6 +55,18 @@ const TextButton = styled(motion.button) `
38
55
  &:active {
39
56
  transform: scale(0.96);
40
57
  }
58
+
59
+ span {
60
+ opacity: 1;
61
+ transition: opacity 300ms ease;
62
+ }
63
+
64
+ &.support span {
65
+ animation: ${fadeIn} 300ms ease both;
66
+ }
67
+ `;
68
+ const Underline = styled.span `
69
+ text-decoration: underline;
41
70
  `;
42
71
 
43
72
  export { PoweredByFooter as default };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -106,6 +106,7 @@ const DaimoPayProviderWithoutSolana = ({ children, theme = "auto", mode = "auto"
106
106
  const [solanaConnector, setSolanaConnector] = useState();
107
107
  const [route, setRoute] = useState(ROUTES.SELECT_METHOD);
108
108
  const [errorMessage, setErrorMessage] = useState("");
109
+ const [confirmationMessage, setConfirmationMessage] = useState(undefined);
109
110
  const [resize, onResize] = useState(0);
110
111
  // Include Google Font that is needed for a themes
111
112
  if (opts.embedGoogleFonts)
@@ -197,6 +198,8 @@ const DaimoPayProviderWithoutSolana = ({ children, theme = "auto", mode = "auto"
197
198
  // Other configuration
198
199
  options: opts,
199
200
  errorMessage,
201
+ confirmationMessage,
202
+ setConfirmationMessage,
200
203
  debugMode,
201
204
  log,
202
205
  displayError: (message, code) => {
@@ -1 +1 @@
1
- {"version":3,"file":"DaimoPay.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"DaimoPay.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -47,11 +47,26 @@ function DaimoPayButtonCustom(props) {
47
47
  paymentState.setPayParams(payParams);
48
48
  }
49
49
  }, [payId, ...Object.values(payParams || {})]);
50
+ const { setConfirmationMessage } = context;
51
+ useEffect(() => {
52
+ if (props.confirmationMessage) {
53
+ setConfirmationMessage(props.confirmationMessage);
54
+ }
55
+ }, [props.confirmationMessage, setConfirmationMessage]);
50
56
  // Payment events: call these three event handlers.
51
57
  const { onPaymentStarted, onPaymentCompleted, onPaymentBounced } = props;
52
58
  const order = paymentState.daimoPayOrder;
53
59
  const hydOrder = order?.mode === DaimoPayOrderMode.HYDRATED ? order : null;
54
60
  const isStarted = hydOrder?.sourceStatus !== DaimoPayOrderStatusSource.WAITING_PAYMENT;
61
+ // Functions to show and hide the modal
62
+ const { children, closeOnSuccess } = props;
63
+ const modalOptions = { closeOnSuccess };
64
+ const show = () => {
65
+ if (paymentState.daimoPayOrder == null)
66
+ return;
67
+ context.showPayment(modalOptions);
68
+ };
69
+ const hide = () => context.setOpen(false);
55
70
  useEffect(() => {
56
71
  if (hydOrder == null || !isStarted)
57
72
  return;
@@ -79,14 +94,15 @@ function DaimoPayButtonCustom(props) {
79
94
  onPaymentBounced?.({ type: "payment_bounced", ...commonFields });
80
95
  }
81
96
  }, [hydOrder?.intentStatus]);
97
+ useEffect(() => {
98
+ if (props.defaultOpen) {
99
+ show();
100
+ }
101
+ }, [order != null]);
82
102
  // Validation
83
103
  if ((payId == null) == (payParams == null)) {
84
104
  throw new Error("Must specify either payId or appId, not both");
85
105
  }
86
- const { children, closeOnSuccess } = props;
87
- const modalOptions = { closeOnSuccess };
88
- const show = () => context.showPayment(modalOptions);
89
- const hide = () => context.setOpen(false);
90
106
  return children({ show, hide });
91
107
  }
92
108
  DaimoPayButtonCustom.displayName = "DaimoPayButton.Custom";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,15 +1,16 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { usePayContext } from '../../DaimoPay.js';
3
- import { PageContent, ModalContent, ModalH1 } from '../../Common/Modal/styles.js';
3
+ import { PageContent, ModalContent, ModalH1, ModalBody } from '../../Common/Modal/styles.js';
4
4
  import { DaimoPayOrderMode, DaimoPayOrderStatusDest, assert } from '@daimo/common';
5
5
  import { getChainExplorerTxUrl } from '@daimo/contract';
6
6
  import { motion } from 'framer-motion';
7
7
  import { TickIcon, LoadingCircleIcon } from '../../../assets/icons.js';
8
8
  import styled from '../../../styles/styled/index.js';
9
+ import { getSupportUrl } from '../../../utils/supportUrl.js';
9
10
  import PoweredByFooter from '../../Common/PoweredByFooter/index.js';
10
11
 
11
12
  const Confirmation = () => {
12
- const { paymentState } = usePayContext();
13
+ const { paymentState, confirmationMessage } = usePayContext();
13
14
  const { daimoPayOrder } = paymentState;
14
15
  const { done, txURL } = (() => {
15
16
  if (daimoPayOrder && daimoPayOrder.mode === DaimoPayOrderMode.HYDRATED) {
@@ -43,7 +44,7 @@ const Confirmation = () => {
43
44
  justifyContent: "center",
44
45
  alignItems: "center",
45
46
  paddingBottom: 0,
46
- }, children: [jsx(AnimationContainer, { children: jsxs(InsetContainer, { children: [jsx(Spinner, { "$status": done }), jsx(SuccessIcon, { "$status": done })] }) }), !done ? (jsx(ModalH1, { children: "Confirming..." })) : (jsx(ModalH1, { children: jsx(Link, { href: txURL, target: "_blank", rel: "noopener noreferrer", children: "Payment completed" }) })), jsx(PoweredByFooter, {})] }) }));
47
+ }, children: [jsx(AnimationContainer, { children: jsxs(InsetContainer, { children: [jsx(Spinner, { "$status": done }), jsx(SuccessIcon, { "$status": done })] }) }), !done ? (jsx(ModalH1, { children: "Confirming..." })) : (jsxs(Fragment, { children: [jsx(ModalH1, { children: jsx(Link, { href: txURL, target: "_blank", rel: "noopener noreferrer", children: "Payment completed" }) }), confirmationMessage && (jsx(ModalBody, { children: confirmationMessage }))] })), jsx(PoweredByFooter, { supportUrl: getSupportUrl(daimoPayOrder, done ? "Confirmed" : "Confirming") })] }) }));
47
48
  };
48
49
  const AnimationContainer = styled(motion.div) `
49
50
  position: relative;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -103,6 +103,8 @@ const SelectMethod = () => {
103
103
  setSelectedExternalOption(option);
104
104
  setRoute(ROUTES.WAITING_OTHER);
105
105
  },
106
+ disabled: option.disabled,
107
+ subtitle: option.message,
106
108
  })),
107
109
  ...(depositAddressOption ? [depositAddressOption] : []),
108
110
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,19 @@
1
+ import { writeDaimoPayOrderID } from '@daimo/common';
2
+
3
+ function getSupportUrl(daimoPayOrder, screen) {
4
+ const encodedOrderId = daimoPayOrder == null ? null : writeDaimoPayOrderID(daimoPayOrder.id);
5
+ const email = "support@daimo.com";
6
+ const subject = `Support with Daimo Pay Id ${encodedOrderId}`;
7
+ let body = "";
8
+ if (daimoPayOrder != null) {
9
+ body += `Id: ${encodedOrderId}\n`;
10
+ body += `Org Id: ${daimoPayOrder.orgId}\n`;
11
+ }
12
+ body += `Support requested on ${screen} screen at ${new Date().toISOString()}\n\n`;
13
+ body += "Please explain the issue you are experiencing:\n\n";
14
+ const mailtoUrl = `mailto:${email}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
15
+ return mailtoUrl;
16
+ }
17
+
18
+ export { getSupportUrl };
19
+ //# sourceMappingURL=supportUrl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supportUrl.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@daimo/pay",
3
3
  "private": false,
4
- "version": "1.1.1",
4
+ "version": "1.1.3",
5
5
  "author": "Daimo",
6
6
  "homepage": "https://pay.daimo.com",
7
7
  "license": "BSD-2-Clause license",
@@ -40,8 +40,8 @@
40
40
  "crypto"
41
41
  ],
42
42
  "dependencies": {
43
- "@daimo/common": "0.3.17",
44
- "@daimo/contract": "0.3.17",
43
+ "@daimo/common": "0.3.18",
44
+ "@daimo/contract": "0.3.18",
45
45
  "@solana/wallet-adapter-base": "^0.9.23",
46
46
  "@solana/wallet-adapter-react": "^0.15.35",
47
47
  "@solana/web3.js": "^1.95.4",
@@ -80,4 +80,4 @@
80
80
  "rollup-plugin-visualizer": "^5.5.4",
81
81
  "typescript-plugin-styled-components": "^3.0.0"
82
82
  }
83
- }
83
+ }