@crossmint/client-sdk-react-ui 1.7.0 → 1.8.0

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.
Files changed (227) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.d.cts +122 -15
  3. package/dist/index.d.ts +122 -15
  4. package/dist/index.js +1 -1
  5. package/package.json +12 -6
  6. package/src/components/auth/AuthModal.tsx +2 -2
  7. package/src/components/dynamic-xyz/DynamicContextProviderWrapper.tsx +21 -0
  8. package/src/components/embed/v3/CrossmintEmbeddedCheckoutV3.tsx +7 -0
  9. package/src/components/embed/v3/EmbeddedCheckoutV3IFrame.tsx +69 -0
  10. package/src/components/embed/v3/crypto/CryptoWalletConnectionHandler.tsx +130 -0
  11. package/src/components/embed/v3/crypto/utils/handleEvmTransaction.ts +65 -0
  12. package/src/components/embed/v3/crypto/utils/handleSendTransaction.ts +31 -0
  13. package/src/components/embed/v3/crypto/utils/handleSolanaTransaction.ts +51 -0
  14. package/src/components/embed/v3/index.ts +1 -0
  15. package/src/components/index.ts +2 -0
  16. package/src/hooks/index.ts +1 -0
  17. package/src/hooks/useCrossmintCheckout.tsx +54 -0
  18. package/src/hooks/useRefreshToken.test.ts +21 -8
  19. package/src/hooks/useRefreshToken.ts +5 -4
  20. package/src/providers/CrossmintAuthProvider.test.tsx +4 -3
  21. package/src/providers/CrossmintAuthProvider.tsx +11 -6
  22. package/src/utils/authCookies.ts +0 -3
  23. package/src/utils/createCrossmintApiClient.ts +17 -0
  24. package/dist/chunk-2GKCAJHH.cjs +0 -1
  25. package/dist/chunk-2POV64LQ.js +0 -1
  26. package/dist/chunk-2WSEHVNP.cjs +0 -1
  27. package/dist/chunk-3JU4ZK3P.cjs +0 -1
  28. package/dist/chunk-3KOG25LO.js +0 -1
  29. package/dist/chunk-3SOJNFPL.js +0 -1
  30. package/dist/chunk-4IHRWQWT.js +0 -1
  31. package/dist/chunk-4JRNSO77.js +0 -1
  32. package/dist/chunk-4P7W56CY.cjs +0 -1
  33. package/dist/chunk-5IFQJPBE.cjs +0 -1
  34. package/dist/chunk-72P3JMXX.js +0 -1
  35. package/dist/chunk-77PBG2JJ.js +0 -1
  36. package/dist/chunk-7LDD5W53.cjs +0 -1
  37. package/dist/chunk-A4BJYIF5.js +0 -1
  38. package/dist/chunk-AC4SM3GW.cjs +0 -1
  39. package/dist/chunk-AZYHTJE6.cjs +0 -1
  40. package/dist/chunk-B2XYCMBI.js +0 -1
  41. package/dist/chunk-BOD2OKYA.js +0 -1
  42. package/dist/chunk-BX5T4LI2.cjs +0 -1
  43. package/dist/chunk-DGZQUCSD.js +0 -1
  44. package/dist/chunk-EUXGP4IN.cjs +0 -1
  45. package/dist/chunk-EVADF7QA.js +0 -1
  46. package/dist/chunk-IAJBYU5C.js +0 -1
  47. package/dist/chunk-IMV35JZB.cjs +0 -1
  48. package/dist/chunk-JDYEU555.cjs +0 -1
  49. package/dist/chunk-JGM3G5E2.js +0 -1
  50. package/dist/chunk-KKDAGPHA.js +0 -1
  51. package/dist/chunk-LHTD23W4.js +0 -1
  52. package/dist/chunk-LZ5XEFKY.cjs +0 -1
  53. package/dist/chunk-MAAWYMXE.cjs +0 -1
  54. package/dist/chunk-N3HOGZN4.js +0 -0
  55. package/dist/chunk-NBJIJZGO.js +0 -1
  56. package/dist/chunk-NFLGT52C.cjs +0 -1
  57. package/dist/chunk-NZQIZ4ZY.cjs +0 -1
  58. package/dist/chunk-O5J2ZIJ6.cjs +0 -1
  59. package/dist/chunk-OOLXYAO7.js +0 -1
  60. package/dist/chunk-OPV6W7NY.js +0 -1
  61. package/dist/chunk-ORB6HDGX.cjs +0 -1
  62. package/dist/chunk-P4TABCC7.cjs +0 -1
  63. package/dist/chunk-PHNKWD7H.cjs +0 -1
  64. package/dist/chunk-PXDN3KFO.js +0 -1
  65. package/dist/chunk-QASKWI5Y.js +0 -1
  66. package/dist/chunk-QYQERFYL.cjs +0 -1
  67. package/dist/chunk-RJGOALQ6.cjs +0 -1
  68. package/dist/chunk-RYQRCUKB.js +0 -1
  69. package/dist/chunk-U6FTIAJO.js +0 -1
  70. package/dist/chunk-VGTN2OW5.js +0 -1
  71. package/dist/chunk-VI6TW7JT.cjs +0 -1
  72. package/dist/chunk-VL5XDIXZ.js +0 -1
  73. package/dist/chunk-VWBAHXIO.cjs +0 -1
  74. package/dist/chunk-W4UPIFFS.cjs +0 -1
  75. package/dist/chunk-W7CLE3ZW.cjs +0 -1
  76. package/dist/chunk-WABJHG6B.cjs +0 -1
  77. package/dist/chunk-WDT4N453.js +0 -1
  78. package/dist/chunk-X5BBXO27.cjs +0 -1
  79. package/dist/chunk-XJUALSXH.cjs +0 -1
  80. package/dist/chunk-YIKXFG7V.js +0 -1
  81. package/dist/chunk-YLAJFXWZ.js +0 -0
  82. package/dist/chunk-ZNIJXDW4.cjs +0 -1
  83. package/dist/chunk-ZUZEZZX7.js +0 -1
  84. package/dist/components/CrossmintNFTCollectionView.cjs +0 -1
  85. package/dist/components/CrossmintNFTCollectionView.d.cts +0 -6
  86. package/dist/components/CrossmintNFTCollectionView.d.ts +0 -6
  87. package/dist/components/CrossmintNFTCollectionView.js +0 -1
  88. package/dist/components/CrossmintNFTDetail.cjs +0 -1
  89. package/dist/components/CrossmintNFTDetail.d.cts +0 -6
  90. package/dist/components/CrossmintNFTDetail.d.ts +0 -6
  91. package/dist/components/CrossmintNFTDetail.js +0 -1
  92. package/dist/components/auth/AuthModal.cjs +0 -1
  93. package/dist/components/auth/AuthModal.d.cts +0 -18
  94. package/dist/components/auth/AuthModal.d.ts +0 -18
  95. package/dist/components/auth/AuthModal.js +0 -1
  96. package/dist/components/auth/PasskeyPrompt.cjs +0 -1
  97. package/dist/components/auth/PasskeyPrompt.d.cts +0 -15
  98. package/dist/components/auth/PasskeyPrompt.d.ts +0 -15
  99. package/dist/components/auth/PasskeyPrompt.js +0 -1
  100. package/dist/components/common/PoweredByCrossmint.cjs +0 -1
  101. package/dist/components/common/PoweredByCrossmint.d.cts +0 -7
  102. package/dist/components/common/PoweredByCrossmint.d.ts +0 -7
  103. package/dist/components/common/PoweredByCrossmint.js +0 -1
  104. package/dist/components/embed/EmbeddedCheckoutIFrame.cjs +0 -1
  105. package/dist/components/embed/EmbeddedCheckoutIFrame.d.cts +0 -9
  106. package/dist/components/embed/EmbeddedCheckoutIFrame.d.ts +0 -9
  107. package/dist/components/embed/EmbeddedCheckoutIFrame.js +0 -1
  108. package/dist/components/embed/crypto/CryptoEmbeddedCheckout.cjs +0 -1
  109. package/dist/components/embed/crypto/CryptoEmbeddedCheckout.d.cts +0 -6
  110. package/dist/components/embed/crypto/CryptoEmbeddedCheckout.d.ts +0 -6
  111. package/dist/components/embed/crypto/CryptoEmbeddedCheckout.js +0 -1
  112. package/dist/components/embed/crypto/CryptoEmbeddedCheckoutIFrame.cjs +0 -1
  113. package/dist/components/embed/crypto/CryptoEmbeddedCheckoutIFrame.d.cts +0 -6
  114. package/dist/components/embed/crypto/CryptoEmbeddedCheckoutIFrame.d.ts +0 -6
  115. package/dist/components/embed/crypto/CryptoEmbeddedCheckoutIFrame.js +0 -1
  116. package/dist/components/embed/fiat/FiatEmbeddedCheckout.cjs +0 -1
  117. package/dist/components/embed/fiat/FiatEmbeddedCheckout.d.cts +0 -6
  118. package/dist/components/embed/fiat/FiatEmbeddedCheckout.d.ts +0 -6
  119. package/dist/components/embed/fiat/FiatEmbeddedCheckout.js +0 -1
  120. package/dist/components/embed/fiat/FiatEmbeddedCheckoutIFrame.cjs +0 -1
  121. package/dist/components/embed/fiat/FiatEmbeddedCheckoutIFrame.d.cts +0 -6
  122. package/dist/components/embed/fiat/FiatEmbeddedCheckoutIFrame.d.ts +0 -6
  123. package/dist/components/embed/fiat/FiatEmbeddedCheckoutIFrame.js +0 -1
  124. package/dist/components/embed/fiat/FiatPaymentElement_OLD.cjs +0 -1
  125. package/dist/components/embed/fiat/FiatPaymentElement_OLD.d.cts +0 -6
  126. package/dist/components/embed/fiat/FiatPaymentElement_OLD.d.ts +0 -6
  127. package/dist/components/embed/fiat/FiatPaymentElement_OLD.js +0 -1
  128. package/dist/components/embed/index.cjs +0 -1
  129. package/dist/components/embed/index.d.cts +0 -6
  130. package/dist/components/embed/index.d.ts +0 -6
  131. package/dist/components/embed/index.js +0 -1
  132. package/dist/components/hosted/CrossmintPayButton.cjs +0 -1
  133. package/dist/components/hosted/CrossmintPayButton.d.cts +0 -11
  134. package/dist/components/hosted/CrossmintPayButton.d.ts +0 -11
  135. package/dist/components/hosted/CrossmintPayButton.js +0 -1
  136. package/dist/components/hosted/index.cjs +0 -1
  137. package/dist/components/hosted/index.d.cts +0 -4
  138. package/dist/components/hosted/index.d.ts +0 -4
  139. package/dist/components/hosted/index.js +0 -1
  140. package/dist/components/hosted/styles.cjs +0 -1
  141. package/dist/components/hosted/styles.d.cts +0 -11
  142. package/dist/components/hosted/styles.d.ts +0 -11
  143. package/dist/components/hosted/styles.js +0 -1
  144. package/dist/components/index.cjs +0 -1
  145. package/dist/components/index.d.cts +0 -8
  146. package/dist/components/index.d.ts +0 -8
  147. package/dist/components/index.js +0 -1
  148. package/dist/consts/version.cjs +0 -1
  149. package/dist/consts/version.d.cts +0 -3
  150. package/dist/consts/version.d.ts +0 -3
  151. package/dist/consts/version.js +0 -1
  152. package/dist/hooks/index.cjs +0 -1
  153. package/dist/hooks/index.d.cts +0 -11
  154. package/dist/hooks/index.d.ts +0 -11
  155. package/dist/hooks/index.js +0 -1
  156. package/dist/hooks/useAuth.cjs +0 -1
  157. package/dist/hooks/useAuth.d.cts +0 -13
  158. package/dist/hooks/useAuth.d.ts +0 -13
  159. package/dist/hooks/useAuth.js +0 -1
  160. package/dist/hooks/useCrossmint.cjs +0 -1
  161. package/dist/hooks/useCrossmint.d.cts +0 -15
  162. package/dist/hooks/useCrossmint.d.ts +0 -15
  163. package/dist/hooks/useCrossmint.js +0 -1
  164. package/dist/hooks/useDeepEffect.cjs +0 -1
  165. package/dist/hooks/useDeepEffect.d.cts +0 -5
  166. package/dist/hooks/useDeepEffect.d.ts +0 -5
  167. package/dist/hooks/useDeepEffect.js +0 -1
  168. package/dist/hooks/useEnvironment.cjs +0 -1
  169. package/dist/hooks/useEnvironment.d.cts +0 -5
  170. package/dist/hooks/useEnvironment.d.ts +0 -5
  171. package/dist/hooks/useEnvironment.js +0 -1
  172. package/dist/hooks/useRefreshToken.cjs +0 -1
  173. package/dist/hooks/useRefreshToken.d.cts +0 -11
  174. package/dist/hooks/useRefreshToken.d.ts +0 -11
  175. package/dist/hooks/useRefreshToken.js +0 -1
  176. package/dist/hooks/useWallet.cjs +0 -1
  177. package/dist/hooks/useWallet.d.cts +0 -18
  178. package/dist/hooks/useWallet.d.ts +0 -18
  179. package/dist/hooks/useWallet.js +0 -1
  180. package/dist/icons/fingerprint.cjs +0 -1
  181. package/dist/icons/fingerprint.d.cts +0 -5
  182. package/dist/icons/fingerprint.d.ts +0 -5
  183. package/dist/icons/fingerprint.js +0 -1
  184. package/dist/icons/passkey.cjs +0 -1
  185. package/dist/icons/passkey.d.cts +0 -5
  186. package/dist/icons/passkey.d.ts +0 -5
  187. package/dist/icons/passkey.js +0 -1
  188. package/dist/icons/passkeyPromptLogo.cjs +0 -1
  189. package/dist/icons/passkeyPromptLogo.d.cts +0 -8
  190. package/dist/icons/passkeyPromptLogo.d.ts +0 -8
  191. package/dist/icons/passkeyPromptLogo.js +0 -1
  192. package/dist/icons/poweredByLeaf.cjs +0 -1
  193. package/dist/icons/poweredByLeaf.d.cts +0 -8
  194. package/dist/icons/poweredByLeaf.d.ts +0 -8
  195. package/dist/icons/poweredByLeaf.js +0 -1
  196. package/dist/icons/x.cjs +0 -1
  197. package/dist/icons/x.d.cts +0 -7
  198. package/dist/icons/x.d.ts +0 -7
  199. package/dist/icons/x.js +0 -1
  200. package/dist/providers/CrossmintAuthProvider.cjs +0 -1
  201. package/dist/providers/CrossmintAuthProvider.d.cts +0 -34
  202. package/dist/providers/CrossmintAuthProvider.d.ts +0 -34
  203. package/dist/providers/CrossmintAuthProvider.js +0 -1
  204. package/dist/providers/CrossmintWalletProvider.cjs +0 -1
  205. package/dist/providers/CrossmintWalletProvider.d.cts +0 -30
  206. package/dist/providers/CrossmintWalletProvider.d.ts +0 -30
  207. package/dist/providers/CrossmintWalletProvider.js +0 -1
  208. package/dist/providers/index.cjs +0 -1
  209. package/dist/providers/index.d.cts +0 -7
  210. package/dist/providers/index.d.ts +0 -7
  211. package/dist/providers/index.js +0 -1
  212. package/dist/testUtils.cjs +0 -1
  213. package/dist/testUtils.d.cts +0 -4
  214. package/dist/testUtils.d.ts +0 -4
  215. package/dist/testUtils.js +0 -1
  216. package/dist/twind.config.cjs +0 -1
  217. package/dist/twind.config.d.cts +0 -9
  218. package/dist/twind.config.d.ts +0 -9
  219. package/dist/twind.config.js +0 -1
  220. package/dist/utils/authCookies.cjs +0 -1
  221. package/dist/utils/authCookies.d.cts +0 -7
  222. package/dist/utils/authCookies.d.ts +0 -7
  223. package/dist/utils/authCookies.js +0 -1
  224. package/dist/utils/classNames.cjs +0 -1
  225. package/dist/utils/classNames.d.cts +0 -11
  226. package/dist/utils/classNames.d.ts +0 -11
  227. package/dist/utils/classNames.js +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crossmint/client-sdk-react-ui",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "repository": "https://github.com/Crossmint/crossmint-sdk",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Paella Labs Inc",
@@ -19,6 +19,11 @@
19
19
  "LICENSE"
20
20
  ],
21
21
  "dependencies": {
22
+ "@dynamic-labs/ethereum": "3.3.0",
23
+ "@dynamic-labs/ethereum-core": "3.3.0",
24
+ "@dynamic-labs/sdk-react-core": "3.3.0",
25
+ "@dynamic-labs/solana": "3.3.0",
26
+ "@dynamic-labs/solana-core": "3.3.0",
22
27
  "@ethersproject/transactions": "5.7.0",
23
28
  "@headlessui/react": "2.1.5",
24
29
  "@solana/web3.js": "1.95.1",
@@ -30,13 +35,14 @@
30
35
  "react-jss": "10.10.0",
31
36
  "tailwind-merge": "2.4.0",
32
37
  "tailwindcss": "3.4.10",
38
+ "viem": "2.17.5",
33
39
  "zod": "3.22.4",
34
- "@crossmint/client-sdk-auth": "0.2.0",
35
- "@crossmint/client-sdk-base": "1.2.8",
36
- "@crossmint/client-sdk-smart-wallet": "0.1.19",
37
- "@crossmint/client-sdk-window": "0.0.10",
40
+ "@crossmint/client-sdk-auth": "0.2.1",
41
+ "@crossmint/client-sdk-base": "1.3.0",
42
+ "@crossmint/client-sdk-smart-wallet": "0.1.20",
43
+ "@crossmint/client-sdk-window": "0.1.0",
38
44
  "@crossmint/common-sdk-base": "0.2.0",
39
- "@crossmint/common-sdk-auth": "0.2.0"
45
+ "@crossmint/common-sdk-auth": "0.2.1"
40
46
  },
41
47
  "devDependencies": {
42
48
  "@types/lodash.isequal": "4.5.6",
@@ -5,7 +5,7 @@ import { z } from "zod";
5
5
  import { IFrameWindow } from "@crossmint/client-sdk-window";
6
6
  import type { UIConfig } from "@crossmint/common-sdk-base";
7
7
  import { CrossmintInternalEvents } from "@crossmint/client-sdk-base";
8
- import type { AuthMaterial } from "@crossmint/common-sdk-auth";
8
+ import type { AuthMaterialWithUser } from "@crossmint/common-sdk-auth";
9
9
  import type { LoginMethod } from "@/providers";
10
10
 
11
11
  import X from "../../icons/x";
@@ -25,7 +25,7 @@ type IncomingModalIframeEventsType = {
25
25
  type AuthModalProps = {
26
26
  setModalOpen: (open: boolean) => void;
27
27
  apiKey: string;
28
- fetchAuthMaterial: (refreshToken: string) => Promise<AuthMaterial>;
28
+ fetchAuthMaterial: (refreshToken: string) => Promise<AuthMaterialWithUser>;
29
29
  baseUrl: string;
30
30
  appearance?: UIConfig;
31
31
  loginMethods?: LoginMethod[];
@@ -0,0 +1,21 @@
1
+ import { type DynamicContextProps, DynamicContextProvider } from "@dynamic-labs/sdk-react-core";
2
+ import type { ReactNode } from "react";
3
+
4
+ export interface DynamicContextProviderWrapperProps {
5
+ children?: ReactNode;
6
+ settings: Omit<DynamicContextProps["settings"], "initialAuthenticationMode" | "environmentId">;
7
+ }
8
+
9
+ export default function DynamicContextProviderWrapper({ children, settings }: DynamicContextProviderWrapperProps) {
10
+ return (
11
+ <DynamicContextProvider
12
+ settings={{
13
+ initialAuthenticationMode: "connect-only",
14
+ environmentId: "cd53135a-b32b-4704-bfca-324b665e9329", // TODO: Key per env
15
+ ...settings,
16
+ }}
17
+ >
18
+ {children}
19
+ </DynamicContextProvider>
20
+ );
21
+ }
@@ -0,0 +1,7 @@
1
+ import type { CrossmintEmbeddedCheckoutV3Props } from "@crossmint/client-sdk-base";
2
+
3
+ import { EmbeddedCheckoutV3IFrame } from "./EmbeddedCheckoutV3IFrame";
4
+
5
+ export function CrossmintEmbeddedCheckout_Alpha(props: CrossmintEmbeddedCheckoutV3Props) {
6
+ return <EmbeddedCheckoutV3IFrame {...props} />;
7
+ }
@@ -0,0 +1,69 @@
1
+ import { useCrossmint } from "@/hooks";
2
+ import { useEffect, useRef, useState } from "react";
3
+
4
+ import {
5
+ type CrossmintEmbeddedCheckoutV3Props,
6
+ type EmbeddedCheckoutV3IFrameEmitter,
7
+ crossmintEmbeddedCheckoutV3Service,
8
+ } from "@crossmint/client-sdk-base";
9
+
10
+ import { CryptoWalletConnectionHandler } from "./crypto/CryptoWalletConnectionHandler";
11
+ import { createCrossmintApiClient } from "@/utils/createCrossmintApiClient";
12
+
13
+ export function EmbeddedCheckoutV3IFrame(props: CrossmintEmbeddedCheckoutV3Props) {
14
+ const [iframeClient, setIframeClient] = useState<EmbeddedCheckoutV3IFrameEmitter | null>(null);
15
+ const [height, setHeight] = useState(0);
16
+
17
+ const { crossmint } = useCrossmint();
18
+ const apiClient = createCrossmintApiClient(crossmint);
19
+ const embedV3Service = crossmintEmbeddedCheckoutV3Service({ apiClient });
20
+
21
+ const ref = useRef<HTMLIFrameElement>(null);
22
+
23
+ useEffect(() => {
24
+ const iframe = ref.current;
25
+ if (!iframe || iframeClient) {
26
+ return;
27
+ }
28
+ setIframeClient(embedV3Service.iframe.createClient(iframe));
29
+ }, [ref.current, iframeClient]);
30
+
31
+ useEffect(() => {
32
+ if (iframeClient == null) {
33
+ return;
34
+ }
35
+ iframeClient.on("ui:height.changed", (data) => setHeight(data.height));
36
+
37
+ return () => {
38
+ iframeClient.off("ui:height.changed");
39
+ };
40
+ }, [iframeClient]);
41
+
42
+ return (
43
+ <>
44
+ <iframe
45
+ ref={ref}
46
+ src={embedV3Service.iframe.getUrl(props)}
47
+ id="crossmint-embedded-checkout.iframe"
48
+ role="crossmint-embedded-checkout.iframe"
49
+ allow="payment *"
50
+ style={{
51
+ boxShadow: "none",
52
+ border: "none",
53
+ padding: "0px",
54
+ width: "100%",
55
+ minWidth: "100%",
56
+ overflow: "hidden",
57
+ display: "block",
58
+ userSelect: "none",
59
+ transform: "translate(0px)",
60
+ opacity: "1",
61
+ transition: "ease 0s, opacity 0.4s ease 0.1s",
62
+ height: `${height}px`,
63
+ backgroundColor: "transparent",
64
+ }}
65
+ />
66
+ {props.payment.crypto.enabled ? <CryptoWalletConnectionHandler iframeClient={iframeClient} /> : null}
67
+ </>
68
+ );
69
+ }
@@ -0,0 +1,130 @@
1
+ import DynamicContextProviderWrapper from "@/components/dynamic-xyz/DynamicContextProviderWrapper";
2
+ import type { EmbeddedCheckoutV3IFrameEmitter } from "@crossmint/client-sdk-base";
3
+ import { type BlockchainIncludingTestnet, chainIdToBlockchain } from "@crossmint/common-sdk-base";
4
+ import { EthereumWalletConnectors } from "@dynamic-labs/ethereum";
5
+ import { type HandleConnectedWallet, useDynamicContext } from "@dynamic-labs/sdk-react-core";
6
+ import { SolanaWalletConnectors } from "@dynamic-labs/solana";
7
+ import { useEffect } from "react";
8
+ import { handleSendTransaction } from "./utils/handleSendTransaction";
9
+
10
+ export function CryptoWalletConnectionHandler(props: { iframeClient: EmbeddedCheckoutV3IFrameEmitter | null }) {
11
+ const { iframeClient } = props;
12
+
13
+ return (
14
+ <DynamicContextProviderWrapper
15
+ settings={{
16
+ walletConnectors: [EthereumWalletConnectors, SolanaWalletConnectors],
17
+ events: {
18
+ onAuthFlowCancel() {
19
+ console.log("[CryptoWalletConnectionHandler] onAuthFlowCancel");
20
+ iframeClient?.send("crypto:connect-wallet.failed", {
21
+ error: "cancelled",
22
+ });
23
+ },
24
+ onAuthFlowClose() {
25
+ console.log("[CryptoWalletConnectionHandler] onAuthFlowClose");
26
+ },
27
+ onAuthFailure(data, reason) {
28
+ console.error("[CryptoWalletConnectionHandler] onAuthFailure", data, reason);
29
+ },
30
+ onAuthSuccess(data) {
31
+ console.log("[CryptoWalletConnectionHandler] onAuthSuccess", data);
32
+ },
33
+ },
34
+ handlers: {
35
+ handleConnectedWallet: async (wallet) => {
36
+ console.log("[CryptoWalletConnectionHandler] handleConnectedWallet", wallet);
37
+
38
+ const address = wallet.address;
39
+ if (!address) {
40
+ console.error("[CryptoWalletConnectionHandler] handleConnectedWallet: address is missing");
41
+ iframeClient?.send("crypto:connect-wallet.failed", {
42
+ error: "address is missing",
43
+ });
44
+ return false;
45
+ }
46
+
47
+ const chain = await dynamicChainToCrossmintChain(wallet);
48
+
49
+ iframeClient?.send("crypto:connect-wallet.success", {
50
+ address,
51
+ chain,
52
+ walletProviderKey: wallet.connector?.key,
53
+ });
54
+
55
+ return true;
56
+ },
57
+ },
58
+ }}
59
+ >
60
+ <_CryptoWalletConnectionHandler {...props} />
61
+ </DynamicContextProviderWrapper>
62
+ );
63
+ }
64
+
65
+ function _CryptoWalletConnectionHandler({ iframeClient }: Parameters<typeof CryptoWalletConnectionHandler>[0]) {
66
+ const { setShowAuthFlow, primaryWallet, handleLogOut } = useDynamicContext();
67
+
68
+ useEffect(() => {
69
+ if (iframeClient == null) {
70
+ return;
71
+ }
72
+ const showAuthFlowListener = iframeClient.on("crypto:connect-wallet.show", async ({ show }) => {
73
+ await handleLogOut();
74
+ setShowAuthFlow(show);
75
+ });
76
+
77
+ return () => {
78
+ iframeClient.off(showAuthFlowListener);
79
+ };
80
+ }, [iframeClient, handleLogOut, setShowAuthFlow]);
81
+
82
+ useEffect(() => {
83
+ if (iframeClient == null) {
84
+ return;
85
+ }
86
+ const signTransactionListener = iframeClient.on(
87
+ "crypto:send-transaction",
88
+ async ({ chain, serializedTransaction }) => {
89
+ if (primaryWallet == null) {
90
+ console.error("[CryptoWalletConnectionHandler] signTransaction: primaryWallet is missing");
91
+ iframeClient.send("crypto:send-transaction:failed", {
92
+ error: "primaryWallet is missing",
93
+ });
94
+ return;
95
+ }
96
+
97
+ await handleSendTransaction(
98
+ primaryWallet,
99
+ chain as BlockchainIncludingTestnet,
100
+ serializedTransaction,
101
+ iframeClient
102
+ );
103
+ }
104
+ );
105
+
106
+ return () => {
107
+ iframeClient.off(signTransactionListener);
108
+ };
109
+ }, [iframeClient, primaryWallet]);
110
+
111
+ return null;
112
+ }
113
+
114
+ async function dynamicChainToCrossmintChain(
115
+ wallet: Parameters<HandleConnectedWallet>[0]
116
+ ): Promise<BlockchainIncludingTestnet> {
117
+ const chain = wallet.chain;
118
+ if (chain === "SOL") {
119
+ return "solana";
120
+ }
121
+ const chainId = await wallet.connector?.getNetwork();
122
+ if (typeof chainId !== "number") {
123
+ throw new Error("chainId is not a number");
124
+ }
125
+ const chainFromChainId = chainIdToBlockchain(chainId);
126
+ if (!chainFromChainId) {
127
+ throw new Error(`ChainId ${chainId} is not supported`);
128
+ }
129
+ return chainFromChainId as BlockchainIncludingTestnet;
130
+ }
@@ -0,0 +1,65 @@
1
+ import type { EmbeddedCheckoutV3IFrameEmitter } from "@crossmint/client-sdk-base";
2
+ import {
3
+ type BlockchainIncludingTestnet,
4
+ blockchainToChainId,
5
+ type EVMBlockchainIncludingTestnet,
6
+ } from "@crossmint/common-sdk-base";
7
+ import type { EthereumWallet } from "@dynamic-labs/ethereum-core";
8
+ import { parseTransaction, type TransactionSerializableEIP1559 } from "viem";
9
+
10
+ export async function handleEvmTransaction({
11
+ primaryWallet,
12
+ chain,
13
+ serializedTransaction,
14
+ iframeClient,
15
+ }: {
16
+ primaryWallet: EthereumWallet;
17
+ chain: BlockchainIncludingTestnet;
18
+ serializedTransaction: string;
19
+ iframeClient: EmbeddedCheckoutV3IFrameEmitter;
20
+ }) {
21
+ try {
22
+ await primaryWallet.switchNetwork(blockchainToChainId(chain as EVMBlockchainIncludingTestnet));
23
+ } catch (error) {
24
+ console.error("[CryptoWalletConnectionHandler] failed to switch network", error);
25
+ iframeClient.send("crypto:send-transaction:failed", {
26
+ error: (error as Error).message,
27
+ });
28
+ return;
29
+ }
30
+
31
+ let walletClient: Awaited<ReturnType<typeof primaryWallet.getWalletClient>>;
32
+ try {
33
+ walletClient = await primaryWallet.getWalletClient();
34
+ } catch (error) {
35
+ console.error("[CryptoWalletConnectionHandler] failed to get wallet client", error);
36
+ iframeClient.send("crypto:send-transaction:failed", {
37
+ error: (error as Error).message,
38
+ });
39
+ return;
40
+ }
41
+
42
+ let parsedTransaction: TransactionSerializableEIP1559;
43
+ try {
44
+ parsedTransaction = parseTransaction(serializedTransaction as `0x${string}`) as TransactionSerializableEIP1559;
45
+ } catch (error) {
46
+ console.error("[CryptoWalletConnectionHandler] failed to parse transaction", error);
47
+ iframeClient.send("crypto:send-transaction:failed", {
48
+ error: (error as Error).message,
49
+ });
50
+ return;
51
+ }
52
+
53
+ try {
54
+ const txId = await walletClient.sendTransaction(parsedTransaction);
55
+ console.log("[CryptoWalletConnectionHandler] txId", txId);
56
+ iframeClient.send("crypto:send-transaction:success", {
57
+ txId,
58
+ });
59
+ } catch (error) {
60
+ console.error("[CryptoWalletConnectionHandler] failed to send transaction", error);
61
+ iframeClient.send("crypto:send-transaction:failed", {
62
+ error: (error as Error).message,
63
+ });
64
+ }
65
+ }
@@ -0,0 +1,31 @@
1
+ import type { Wallet } from "@dynamic-labs/sdk-react-core";
2
+
3
+ import type { BlockchainIncludingTestnet } from "@crossmint/common-sdk-base";
4
+
5
+ import { handleEvmTransaction } from "./handleEvmTransaction";
6
+
7
+ import { isSolanaWallet } from "@dynamic-labs/solana";
8
+ import { handleSolanaTransaction } from "./handleSolanaTransaction";
9
+ import { isEthereumWallet } from "@dynamic-labs/ethereum";
10
+ import type { EmbeddedCheckoutV3IFrameEmitter } from "@crossmint/client-sdk-base";
11
+
12
+ export async function handleSendTransaction(
13
+ primaryWallet: Wallet,
14
+ chain: BlockchainIncludingTestnet,
15
+ serializedTransaction: string,
16
+ iframeClient: EmbeddedCheckoutV3IFrameEmitter
17
+ ) {
18
+ const commonParams = {
19
+ chain,
20
+ serializedTransaction,
21
+ iframeClient,
22
+ };
23
+ if (isSolanaWallet(primaryWallet)) {
24
+ return await handleSolanaTransaction({
25
+ ...commonParams,
26
+ primaryWallet,
27
+ });
28
+ } else if (isEthereumWallet(primaryWallet)) {
29
+ return await handleEvmTransaction({ ...commonParams, primaryWallet });
30
+ }
31
+ }
@@ -0,0 +1,51 @@
1
+ import type { EmbeddedCheckoutV3IFrameEmitter } from "@crossmint/client-sdk-base";
2
+ import type { SolanaWallet } from "@dynamic-labs/solana-core";
3
+ import { Transaction } from "@solana/web3.js";
4
+ import base58 from "bs58";
5
+
6
+ export async function handleSolanaTransaction({
7
+ primaryWallet,
8
+ serializedTransaction,
9
+ iframeClient,
10
+ }: {
11
+ primaryWallet: SolanaWallet;
12
+ serializedTransaction: string;
13
+ iframeClient: EmbeddedCheckoutV3IFrameEmitter;
14
+ }) {
15
+ // TODO: Handle switch network
16
+
17
+ let signer: Awaited<ReturnType<typeof primaryWallet.getSigner>>;
18
+ try {
19
+ signer = await primaryWallet.getSigner();
20
+ } catch (error) {
21
+ console.error("[CryptoWalletConnectionHandler] failed to get signer", error);
22
+ iframeClient.send("crypto:send-transaction:failed", {
23
+ error: "Failed to get signer",
24
+ });
25
+ return;
26
+ }
27
+
28
+ let deserializedTransaction: Transaction;
29
+ try {
30
+ deserializedTransaction = Transaction.from(base58.decode(serializedTransaction));
31
+ } catch (error) {
32
+ console.error("[CryptoWalletConnectionHandler] failed to deserialize transaction", error);
33
+ iframeClient.send("crypto:send-transaction:failed", {
34
+ error: "Failed to deserialize transaction",
35
+ });
36
+ return;
37
+ }
38
+
39
+ try {
40
+ const { signature: txId } = await signer.signAndSendTransaction(deserializedTransaction);
41
+ console.log("[CryptoWalletConnectionHandler] txId", txId);
42
+ iframeClient.send("crypto:send-transaction:success", {
43
+ txId,
44
+ });
45
+ } catch (error) {
46
+ console.error("[CryptoWalletConnectionHandler] failed to send transaction", error);
47
+ iframeClient.send("crypto:send-transaction:failed", {
48
+ error: (error as Error).message,
49
+ });
50
+ }
51
+ }
@@ -0,0 +1 @@
1
+ export * from "./CrossmintEmbeddedCheckoutV3";
@@ -3,3 +3,5 @@ export * from "./CrossmintNFTDetail";
3
3
 
4
4
  export * from "./embed";
5
5
  export * from "./hosted";
6
+
7
+ export * from "./embed/v3";
@@ -1,4 +1,5 @@
1
1
  export * from "./useCrossmint";
2
+ export * from "./useCrossmintCheckout";
2
3
  export * from "./useWallet";
3
4
  export * from "./useAuth";
4
5
  export * from "./useRefreshToken";
@@ -0,0 +1,54 @@
1
+ import { createContext, type ReactNode, useContext, useEffect, useState } from "react";
2
+ import type { embeddedCheckoutV3IncomingEvents } from "@crossmint/client-sdk-base";
3
+ import type { z } from "zod";
4
+ import { useCrossmint } from "./useCrossmint";
5
+ import { createCrossmintApiClient } from "@/utils/createCrossmintApiClient";
6
+
7
+ export interface CrossmintCheckoutContext {
8
+ order?: any;
9
+ orderClientSecret?: string;
10
+ }
11
+
12
+ const CrossmintCheckoutContext = createContext<CrossmintCheckoutContext | undefined>(undefined);
13
+
14
+ export function CrossmintCheckoutProvider({ children }: { children: ReactNode }) {
15
+ const [order, setOrder] = useState<any>();
16
+ const [orderClientSecret, setOrderClientSecret] = useState<string>();
17
+
18
+ const { crossmint } = useCrossmint();
19
+ const apiClient = createCrossmintApiClient(crossmint);
20
+
21
+ useEffect(() => {
22
+ const listener = (event: MessageEvent) => {
23
+ if (event.origin !== new URL(apiClient.baseUrl).origin) {
24
+ return;
25
+ }
26
+ if (event.data.event !== "order:updated") {
27
+ return;
28
+ }
29
+ const { order, orderClientSecret } = event.data.data as z.infer<
30
+ (typeof embeddedCheckoutV3IncomingEvents)["order:updated"]
31
+ >;
32
+ setOrder(order);
33
+ setOrderClientSecret(orderClientSecret);
34
+ };
35
+ window.addEventListener("message", listener);
36
+ return () => {
37
+ window.removeEventListener("message", listener);
38
+ };
39
+ }, [order]);
40
+
41
+ return (
42
+ <CrossmintCheckoutContext.Provider value={{ order, orderClientSecret }}>
43
+ {children}
44
+ </CrossmintCheckoutContext.Provider>
45
+ );
46
+ }
47
+
48
+ export function useCrossmintCheckout() {
49
+ const context = useContext(CrossmintCheckoutContext);
50
+ if (!context) {
51
+ throw new Error("useCrossmintCheckout must be used within a CrossmintCheckoutProvider");
52
+ }
53
+ return context;
54
+ }
@@ -1,11 +1,12 @@
1
1
  import { act, renderHook } from "@testing-library/react";
2
2
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
3
 
4
+ import type { AuthMaterialWithUser } from "@crossmint/common-sdk-auth";
4
5
  import { type CrossmintAuthService, getJWTExpiration } from "@crossmint/client-sdk-auth";
5
6
  import { queueTask } from "@crossmint/client-sdk-base";
6
7
 
7
8
  import * as authCookies from "../utils/authCookies";
8
- import { type AuthMaterial, useRefreshToken } from "./useRefreshToken";
9
+ import { useRefreshToken } from "./useRefreshToken";
9
10
 
10
11
  vi.mock("@crossmint/client-sdk-auth", () => ({
11
12
  CrossmintAuthService: vi.fn(),
@@ -17,9 +18,13 @@ vi.mock("../utils/authCookies", () => ({
17
18
  REFRESH_TOKEN_PREFIX: "crossmint-refresh-token",
18
19
  }));
19
20
 
20
- vi.mock("@crossmint/client-sdk-base", () => ({
21
- queueTask: vi.fn(),
22
- }));
21
+ vi.mock("@crossmint/client-sdk-base", async () => {
22
+ const actual = await vi.importActual("@crossmint/client-sdk-base");
23
+ return {
24
+ ...actual,
25
+ queueTask: vi.fn(),
26
+ };
27
+ });
23
28
 
24
29
  describe("useRefreshToken", () => {
25
30
  const mockCrossmintAuthService = {
@@ -59,12 +64,16 @@ describe("useRefreshToken", () => {
59
64
 
60
65
  it("should refresh token if refresh token is present", async () => {
61
66
  const mockRefreshToken = "mock-refresh-token";
62
- const mockAuthMaterial: AuthMaterial = {
63
- jwtToken: "mock-jwt-token",
67
+ const mockAuthMaterial: AuthMaterialWithUser = {
68
+ jwt: "mock-jwt-token",
64
69
  refreshToken: {
65
70
  secret: "mock-secret",
66
71
  expiresAt: "2023-04-01T00:00:00Z",
67
72
  },
73
+ user: {
74
+ id: "123",
75
+ email: "test@test.com",
76
+ },
68
77
  };
69
78
 
70
79
  vi.mocked(authCookies.getCookie).mockReturnValue(mockRefreshToken);
@@ -89,12 +98,16 @@ describe("useRefreshToken", () => {
89
98
 
90
99
  it("should schedule next refresh before token expiration", async () => {
91
100
  const mockRefreshToken = "mock-refresh-token";
92
- const mockAuthMaterial: AuthMaterial = {
93
- jwtToken: "mock-jwt-token",
101
+ const mockAuthMaterial: AuthMaterialWithUser = {
102
+ jwt: "mock-jwt-token",
94
103
  refreshToken: {
95
104
  secret: "mock-secret",
96
105
  expiresAt: "2023-04-01T00:00:00Z",
97
106
  },
107
+ user: {
108
+ id: "123",
109
+ email: "test@test.com",
110
+ },
98
111
  };
99
112
 
100
113
  vi.mocked(authCookies.getCookie).mockReturnValue(mockRefreshToken);
@@ -1,18 +1,19 @@
1
1
  import { useCallback, useEffect, useRef } from "react";
2
2
 
3
- import type { AuthMaterial } from "@crossmint/common-sdk-auth";
3
+ import type { AuthMaterialWithUser } from "@crossmint/common-sdk-auth";
4
4
  import type { CrossmintAuthService } from "@crossmint/client-sdk-auth";
5
5
  import { getJWTExpiration } from "@crossmint/client-sdk-auth";
6
6
  import { queueTask, type CancellableTask } from "@crossmint/client-sdk-base";
7
+ import { REFRESH_TOKEN_PREFIX } from "@crossmint/common-sdk-auth";
7
8
 
8
- import { REFRESH_TOKEN_PREFIX, getCookie } from "../utils/authCookies";
9
+ import { getCookie } from "../utils/authCookies";
9
10
 
10
11
  // 2 minutes before jwt expiration
11
12
  const TIME_BEFORE_EXPIRING_JWT_IN_SECONDS = 120;
12
13
 
13
14
  type UseAuthTokenRefreshProps = {
14
15
  crossmintAuthService: CrossmintAuthService;
15
- setAuthMaterial: (authMaterial: AuthMaterial) => void;
16
+ setAuthMaterial: (authMaterial: AuthMaterialWithUser) => void;
16
17
  logout: () => void;
17
18
  };
18
19
 
@@ -34,7 +35,7 @@ export function useRefreshToken({ crossmintAuthService, setAuthMaterial, logout
34
35
  try {
35
36
  const result = await crossmintAuthService.refreshAuthMaterial(refreshToken);
36
37
  setAuthMaterial(result);
37
- const jwtExpiration = getJWTExpiration(result.jwtToken);
38
+ const jwtExpiration = getJWTExpiration(result.jwt);
38
39
 
39
40
  if (jwtExpiration == null) {
40
41
  throw new Error("Invalid JWT");
@@ -1,4 +1,5 @@
1
- import { deleteCookie, REFRESH_TOKEN_PREFIX, SESSION_PREFIX } from "@/utils/authCookies";
1
+ import { deleteCookie } from "@/utils/authCookies";
2
+ import { SESSION_PREFIX, REFRESH_TOKEN_PREFIX } from "@crossmint/common-sdk-auth";
2
3
  import { fireEvent, render } from "@testing-library/react";
3
4
  import { type ReactNode, act } from "react";
4
5
  import { beforeEach, describe, expect, vi } from "vitest";
@@ -39,7 +40,7 @@ vi.mock("@crossmint/client-sdk-auth", async () => {
39
40
  getJWTExpiration: vi.fn(),
40
41
  CrossmintAuthService: vi.fn().mockImplementation(() => ({
41
42
  refreshAuthMaterial: vi.fn().mockResolvedValue({
42
- jwtToken: "new-mock-jwt",
43
+ jwt: "new-mock-jwt",
43
44
  refreshToken: {
44
45
  secret: "new-mock-refresh-token",
45
46
  expiresAt: new Date(Date.now() + 1000 * 60 * 60).toISOString(),
@@ -123,7 +124,7 @@ describe("CrossmintAuthProvider", () => {
123
124
 
124
125
  mockCrossmintAuthService = {
125
126
  refreshAuthMaterial: vi.fn().mockResolvedValue({
126
- jwtToken: "new-mock-jwt",
127
+ jwt: "new-mock-jwt",
127
128
  refreshToken: {
128
129
  secret: "new-mock-refresh-token",
129
130
  expiresAt: new Date(Date.now() + 1000 * 60 * 60).toISOString(),