thirdweb 5.116.1 → 5.116.2-nightly-151127d66825365cb0ed949ae28b9906ee4dfc8d-20251214000442

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 (94) hide show
  1. package/dist/cjs/react/web/ui/Bridge/swap-widget/swap-ui.js +20 -0
  2. package/dist/cjs/react/web/ui/Bridge/swap-widget/swap-ui.js.map +1 -1
  3. package/dist/cjs/react/web/ui/Bridge/swap-widget/use-bridge-chains.js +15 -2
  4. package/dist/cjs/react/web/ui/Bridge/swap-widget/use-bridge-chains.js.map +1 -1
  5. package/dist/cjs/react/web/ui/ConnectWallet/WalletEntryButton.js +16 -2
  6. package/dist/cjs/react/web/ui/ConnectWallet/WalletEntryButton.js.map +1 -1
  7. package/dist/cjs/react/web/ui/ConnectWallet/icons/EmailIcon.js +1 -4
  8. package/dist/cjs/react/web/ui/ConnectWallet/icons/EmailIcon.js.map +1 -1
  9. package/dist/cjs/react/web/ui/ConnectWallet/icons/WalletDotIcon.js +1 -1
  10. package/dist/cjs/react/web/ui/ConnectWallet/icons/WalletDotIcon.js.map +1 -1
  11. package/dist/cjs/react/web/ui/ConnectWallet/in-app-wallet-icon.js +101 -0
  12. package/dist/cjs/react/web/ui/ConnectWallet/in-app-wallet-icon.js.map +1 -0
  13. package/dist/cjs/react/web/ui/components/Spinner.js +7 -7
  14. package/dist/cjs/react/web/ui/components/Spinner.js.map +1 -1
  15. package/dist/cjs/react/web/ui/design-system/elements.js +1 -2
  16. package/dist/cjs/react/web/ui/design-system/elements.js.map +1 -1
  17. package/dist/cjs/react/web/wallets/shared/ConnectWalletSocialOptions.js +4 -4
  18. package/dist/cjs/react/web/wallets/shared/ConnectWalletSocialOptions.js.map +1 -1
  19. package/dist/cjs/react/web/wallets/shared/OTPLoginUI.js +13 -7
  20. package/dist/cjs/react/web/wallets/shared/OTPLoginUI.js.map +1 -1
  21. package/dist/cjs/stories/ConnectEmbed.stories.js +34 -0
  22. package/dist/cjs/stories/ConnectEmbed.stories.js.map +1 -1
  23. package/dist/cjs/stories/in-app-wallet-icon.stories.js +59 -0
  24. package/dist/cjs/stories/in-app-wallet-icon.stories.js.map +1 -0
  25. package/dist/cjs/version.js +1 -1
  26. package/dist/cjs/version.js.map +1 -1
  27. package/dist/cjs/wallets/in-app/web/lib/auth/otp.js +12 -1
  28. package/dist/cjs/wallets/in-app/web/lib/auth/otp.js.map +1 -1
  29. package/dist/esm/react/web/ui/Bridge/swap-widget/swap-ui.js +20 -0
  30. package/dist/esm/react/web/ui/Bridge/swap-widget/swap-ui.js.map +1 -1
  31. package/dist/esm/react/web/ui/Bridge/swap-widget/use-bridge-chains.js +15 -2
  32. package/dist/esm/react/web/ui/Bridge/swap-widget/use-bridge-chains.js.map +1 -1
  33. package/dist/esm/react/web/ui/ConnectWallet/WalletEntryButton.js +16 -2
  34. package/dist/esm/react/web/ui/ConnectWallet/WalletEntryButton.js.map +1 -1
  35. package/dist/esm/react/web/ui/ConnectWallet/icons/EmailIcon.js +1 -4
  36. package/dist/esm/react/web/ui/ConnectWallet/icons/EmailIcon.js.map +1 -1
  37. package/dist/esm/react/web/ui/ConnectWallet/icons/WalletDotIcon.js +1 -1
  38. package/dist/esm/react/web/ui/ConnectWallet/icons/WalletDotIcon.js.map +1 -1
  39. package/dist/esm/react/web/ui/ConnectWallet/in-app-wallet-icon.js +98 -0
  40. package/dist/esm/react/web/ui/ConnectWallet/in-app-wallet-icon.js.map +1 -0
  41. package/dist/esm/react/web/ui/components/Spinner.js +9 -9
  42. package/dist/esm/react/web/ui/components/Spinner.js.map +1 -1
  43. package/dist/esm/react/web/ui/design-system/elements.js +0 -1
  44. package/dist/esm/react/web/ui/design-system/elements.js.map +1 -1
  45. package/dist/esm/react/web/wallets/shared/ConnectWalletSocialOptions.js +1 -1
  46. package/dist/esm/react/web/wallets/shared/ConnectWalletSocialOptions.js.map +1 -1
  47. package/dist/esm/react/web/wallets/shared/OTPLoginUI.js +13 -7
  48. package/dist/esm/react/web/wallets/shared/OTPLoginUI.js.map +1 -1
  49. package/dist/esm/stories/ConnectEmbed.stories.js +31 -0
  50. package/dist/esm/stories/ConnectEmbed.stories.js.map +1 -1
  51. package/dist/esm/stories/in-app-wallet-icon.stories.js +55 -0
  52. package/dist/esm/stories/in-app-wallet-icon.stories.js.map +1 -0
  53. package/dist/esm/version.js +1 -1
  54. package/dist/esm/version.js.map +1 -1
  55. package/dist/esm/wallets/in-app/web/lib/auth/otp.js +12 -1
  56. package/dist/esm/wallets/in-app/web/lib/auth/otp.js.map +1 -1
  57. package/dist/scripts/bridge-widget.js +113 -112
  58. package/dist/types/react/web/ui/Bridge/swap-widget/swap-ui.d.ts.map +1 -1
  59. package/dist/types/react/web/ui/Bridge/swap-widget/use-bridge-chains.d.ts +1 -2
  60. package/dist/types/react/web/ui/Bridge/swap-widget/use-bridge-chains.d.ts.map +1 -1
  61. package/dist/types/react/web/ui/ConnectWallet/WalletEntryButton.d.ts.map +1 -1
  62. package/dist/types/react/web/ui/ConnectWallet/icons/EmailIcon.d.ts +0 -3
  63. package/dist/types/react/web/ui/ConnectWallet/icons/EmailIcon.d.ts.map +1 -1
  64. package/dist/types/react/web/ui/ConnectWallet/icons/WalletDotIcon.d.ts.map +1 -1
  65. package/dist/types/react/web/ui/ConnectWallet/in-app-wallet-icon.d.ts +7 -0
  66. package/dist/types/react/web/ui/ConnectWallet/in-app-wallet-icon.d.ts.map +1 -0
  67. package/dist/types/react/web/ui/components/Spinner.d.ts.map +1 -1
  68. package/dist/types/react/web/ui/design-system/elements.d.ts +0 -4
  69. package/dist/types/react/web/ui/design-system/elements.d.ts.map +1 -1
  70. package/dist/types/react/web/wallets/shared/ConnectWalletSocialOptions.d.ts +2 -1
  71. package/dist/types/react/web/wallets/shared/ConnectWalletSocialOptions.d.ts.map +1 -1
  72. package/dist/types/react/web/wallets/shared/OTPLoginUI.d.ts.map +1 -1
  73. package/dist/types/stories/ConnectEmbed.stories.d.ts +3 -0
  74. package/dist/types/stories/ConnectEmbed.stories.d.ts.map +1 -1
  75. package/dist/types/stories/in-app-wallet-icon.stories.d.ts +10 -0
  76. package/dist/types/stories/in-app-wallet-icon.stories.d.ts.map +1 -0
  77. package/dist/types/version.d.ts +1 -1
  78. package/dist/types/version.d.ts.map +1 -1
  79. package/dist/types/wallets/in-app/web/lib/auth/otp.d.ts.map +1 -1
  80. package/package.json +1 -1
  81. package/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx +26 -0
  82. package/src/react/web/ui/Bridge/swap-widget/use-bridge-chains.ts +19 -2
  83. package/src/react/web/ui/ConnectWallet/WalletEntryButton.tsx +23 -2
  84. package/src/react/web/ui/ConnectWallet/icons/EmailIcon.tsx +12 -19
  85. package/src/react/web/ui/ConnectWallet/icons/WalletDotIcon.tsx +1 -0
  86. package/src/react/web/ui/ConnectWallet/in-app-wallet-icon.tsx +195 -0
  87. package/src/react/web/ui/components/Spinner.tsx +9 -9
  88. package/src/react/web/ui/design-system/elements.ts +0 -1
  89. package/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx +1 -1
  90. package/src/react/web/wallets/shared/OTPLoginUI.tsx +24 -11
  91. package/src/stories/ConnectEmbed.stories.tsx +55 -0
  92. package/src/stories/in-app-wallet-icon.stories.tsx +163 -0
  93. package/src/version.ts +1 -1
  94. package/src/wallets/in-app/web/lib/auth/otp.ts +11 -1
@@ -29,7 +29,10 @@ type VerificationStatus =
29
29
  | "valid"
30
30
  | "idle"
31
31
  | "payment_required";
32
- type AccountStatus = "sending" | "sent" | "error";
32
+ type AccountStatus =
33
+ | { type: "sending" }
34
+ | { type: "sent" }
35
+ | { type: "error"; message: string | undefined };
33
36
  type ScreenToShow = "base" | "enter-password-or-recovery-code";
34
37
 
35
38
  /**
@@ -52,7 +55,9 @@ export function OTPLoginUI(props: {
52
55
  const [otpInput, setOtpInput] = useState("");
53
56
  const [verifyStatus, setVerifyStatus] = useState<VerificationStatus>("idle");
54
57
  const [error, setError] = useState<string | undefined>();
55
- const [accountStatus, setAccountStatus] = useState<AccountStatus>("sending");
58
+ const [accountStatus, setAccountStatus] = useState<AccountStatus>({
59
+ type: "sending",
60
+ });
56
61
  const [countdown, setCountdown] = useState(0);
57
62
  const ecosystem = isEcosystemWallet(wallet)
58
63
  ? {
@@ -66,7 +71,7 @@ export function OTPLoginUI(props: {
66
71
  const sendEmailOrSms = useCallback(async () => {
67
72
  setOtpInput("");
68
73
  setVerifyStatus("idle");
69
- setAccountStatus("sending");
74
+ setAccountStatus({ type: "sending" });
70
75
 
71
76
  try {
72
77
  if ("email" in userInfo) {
@@ -76,7 +81,7 @@ export function OTPLoginUI(props: {
76
81
  email: userInfo.email,
77
82
  strategy: "email",
78
83
  });
79
- setAccountStatus("sent");
84
+ setAccountStatus({ type: "sent" });
80
85
  setCountdown(60); // Start 60-second countdown
81
86
  } else if ("phone" in userInfo) {
82
87
  await preAuthenticate({
@@ -85,7 +90,7 @@ export function OTPLoginUI(props: {
85
90
  phoneNumber: userInfo.phone,
86
91
  strategy: "phone",
87
92
  });
88
- setAccountStatus("sent");
93
+ setAccountStatus({ type: "sent" });
89
94
  setCountdown(60); // Start 60-second countdown
90
95
  } else {
91
96
  throw new Error("Invalid userInfo");
@@ -93,7 +98,10 @@ export function OTPLoginUI(props: {
93
98
  } catch (e) {
94
99
  console.error(e);
95
100
  setVerifyStatus("idle");
96
- setAccountStatus("error");
101
+ setAccountStatus({
102
+ type: "error",
103
+ message: e instanceof Error ? e.message : undefined,
104
+ });
97
105
  }
98
106
  }, [props.client, userInfo, ecosystem]);
99
107
 
@@ -317,19 +325,24 @@ export function OTPLoginUI(props: {
317
325
 
318
326
  {!isWideModal && <Line />}
319
327
 
320
- <Container gap="xs" p={isWideModal ? undefined : "lg"}>
321
- {accountStatus === "error" && (
328
+ <Container
329
+ gap="sm"
330
+ p={isWideModal ? undefined : "lg"}
331
+ flex="column"
332
+ >
333
+ {accountStatus.type === "error" && (
322
334
  <Text
323
335
  center
324
336
  color="danger"
325
337
  size="sm"
326
338
  className="tw-screen-error"
327
339
  >
328
- {locale.emailLoginScreen.failedToSendCode}
340
+ {accountStatus.message ||
341
+ locale.emailLoginScreen.failedToSendCode}
329
342
  </Text>
330
343
  )}
331
344
 
332
- {accountStatus === "sending" && (
345
+ {accountStatus.type === "sending" && (
333
346
  <Container
334
347
  center="both"
335
348
  flex="row"
@@ -343,7 +356,7 @@ export function OTPLoginUI(props: {
343
356
  </Container>
344
357
  )}
345
358
 
346
- {accountStatus !== "sending" && (
359
+ {accountStatus.type !== "sending" && (
347
360
  <LinkButton
348
361
  onClick={countdown === 0 ? sendEmailOrSms : undefined}
349
362
  style={{
@@ -1,6 +1,7 @@
1
1
  import type { Meta } from "@storybook/react";
2
2
  import { ConnectButton } from "../react/web/ui/ConnectWallet/ConnectButton.js";
3
3
  import { ConnectEmbed } from "../react/web/ui/ConnectWallet/Modal/ConnectEmbed.js";
4
+ import { createWallet } from "../wallets/create-wallet.js";
4
5
  import { ecosystemWallet } from "../wallets/in-app/web/ecosystem.js";
5
6
  import { inAppWallet } from "../wallets/in-app/web/in-app.js";
6
7
  import { storyClient } from "./utils.js";
@@ -110,6 +111,60 @@ export function AllInAppWalletAuthMethods() {
110
111
  );
111
112
  }
112
113
 
114
+ export function ConfiguredInAppWalletWideModal() {
115
+ return (
116
+ <ConnectEmbed
117
+ client={storyClient}
118
+ className="foo-bar"
119
+ modalSize="wide"
120
+ wallets={[
121
+ createWallet("io.metamask"),
122
+ inAppWallet({
123
+ auth: {
124
+ options: ["google", "github", "email"],
125
+ },
126
+ }),
127
+ ]}
128
+ />
129
+ );
130
+ }
131
+
132
+ export function GoogleLoginWideModal() {
133
+ return (
134
+ <ConnectEmbed
135
+ client={storyClient}
136
+ className="foo-bar"
137
+ modalSize="wide"
138
+ wallets={[
139
+ createWallet("io.metamask"),
140
+ inAppWallet({
141
+ auth: {
142
+ options: ["google"],
143
+ },
144
+ }),
145
+ ]}
146
+ />
147
+ );
148
+ }
149
+
150
+ export function GithubLoginWideModal() {
151
+ return (
152
+ <ConnectEmbed
153
+ client={storyClient}
154
+ className="foo-bar"
155
+ modalSize="wide"
156
+ wallets={[
157
+ createWallet("io.metamask"),
158
+ inAppWallet({
159
+ auth: {
160
+ options: ["github"],
161
+ },
162
+ }),
163
+ ]}
164
+ />
165
+ );
166
+ }
167
+
113
168
  export function EcosystemWallet() {
114
169
  return (
115
170
  <ConnectEmbed
@@ -0,0 +1,163 @@
1
+ import type { Meta } from "@storybook/react";
2
+ import {
3
+ CustomThemeProvider,
4
+ useCustomTheme,
5
+ } from "../react/core/design-system/CustomThemeProvider.js";
6
+ import { InAppWalletIcon } from "../react/web/ui/ConnectWallet/in-app-wallet-icon.js";
7
+ import { defaultAuthOptions } from "../react/web/wallets/shared/ConnectWalletSocialOptions.js";
8
+ import { inAppWallet } from "../wallets/in-app/web/in-app.js";
9
+ import type { AuthOption } from "../wallets/types.js";
10
+ import { storyClient } from "./utils.js";
11
+
12
+ const meta: Meta<typeof Variant> = {
13
+ title: "Components/in-app-wallet-icon",
14
+ decorators: [
15
+ (Story) => {
16
+ return (
17
+ <CustomThemeProvider theme="dark">
18
+ <Story />
19
+ </CustomThemeProvider>
20
+ );
21
+ },
22
+ ],
23
+ };
24
+ export default meta;
25
+
26
+ function Variants() {
27
+ const theme = useCustomTheme();
28
+ return (
29
+ <div
30
+ style={{
31
+ backgroundColor: theme.colors.modalBg,
32
+ padding: "14px",
33
+ borderRadius: "10px",
34
+ display: "flex",
35
+ flexDirection: "column",
36
+ gap: "12px",
37
+ }}
38
+ >
39
+ <div>
40
+ <SectionTitle title="Default" />
41
+ <Variant authOptions={defaultAuthOptions} />
42
+ </div>
43
+
44
+ <div>
45
+ <SectionTitle title="Single method enabled" />
46
+ <div style={{ display: "flex", gap: "10px", flexWrap: "wrap" }}>
47
+ <Variant authOptions={["email"]} />
48
+ <Variant authOptions={["phone"]} />
49
+ <Variant authOptions={["passkey"]} />
50
+ <Variant authOptions={["guest"]} />
51
+ <Variant authOptions={["google"]} />
52
+ <Variant authOptions={["apple"]} />
53
+ <Variant authOptions={["facebook"]} />
54
+ <Variant authOptions={["discord"]} />
55
+ <Variant authOptions={["github"]} />
56
+ <Variant authOptions={["twitch"]} />
57
+ <Variant authOptions={["x"]} />
58
+ <Variant authOptions={["telegram"]} />
59
+ <Variant authOptions={["line"]} />
60
+ <Variant authOptions={["coinbase"]} />
61
+ <Variant authOptions={["epic"]} />
62
+ <Variant authOptions={["farcaster"]} />
63
+ <Variant authOptions={["tiktok"]} />
64
+ <Variant authOptions={["steam"]} />
65
+ </div>
66
+ </div>
67
+
68
+ <div>
69
+ <SectionTitle title="Two methods enabled" />
70
+ <div style={{ display: "flex", gap: "10px", flexWrap: "wrap" }}>
71
+ <Variant authOptions={["email", "phone"]} />
72
+ <Variant authOptions={["email", "passkey"]} />
73
+ <Variant authOptions={["email", "guest"]} />
74
+ <Variant authOptions={["email", "google"]} />
75
+ <Variant authOptions={["email", "apple"]} />
76
+ <Variant authOptions={["email", "facebook"]} />
77
+ <Variant authOptions={["google", "discord"]} />
78
+ <Variant authOptions={["google", "github"]} />
79
+ <Variant authOptions={["google", "twitch"]} />
80
+ <Variant authOptions={["google", "x"]} />
81
+ <Variant authOptions={["google", "telegram"]} />
82
+ <Variant authOptions={["google", "line"]} />
83
+ <Variant authOptions={["google", "coinbase"]} />
84
+ <Variant authOptions={["google", "epic"]} />
85
+ </div>
86
+ </div>
87
+
88
+ <div>
89
+ <SectionTitle title="Three methods enabled" />
90
+ <div style={{ display: "flex", gap: "10px", flexWrap: "wrap" }}>
91
+ <Variant authOptions={["google", "apple", "github"]} />
92
+ <Variant authOptions={["email", "phone", "guest"]} />
93
+ <Variant authOptions={["email", "phone", "google"]} />
94
+ <Variant authOptions={["email", "phone", "apple"]} />
95
+ <Variant authOptions={["email", "phone", "facebook"]} />
96
+ </div>
97
+ </div>
98
+
99
+ <div>
100
+ <SectionTitle title="Four or more methods enabled" />
101
+ <div style={{ display: "flex", gap: "10px", flexWrap: "wrap" }}>
102
+ <Variant
103
+ authOptions={["email", "phone", "google", "apple", "facebook"]}
104
+ />
105
+ <Variant authOptions={["epic", "tiktok", "github", "email"]} />
106
+ <Variant
107
+ authOptions={["twitch", "tiktok", "epic", "email", "phone"]}
108
+ />
109
+ <Variant authOptions={["email", "phone", "passkey", "guest"]} />
110
+ <Variant
111
+ authOptions={[
112
+ "google",
113
+ "apple",
114
+ "facebook",
115
+ "github",
116
+ "discord",
117
+ "twitch",
118
+ "x",
119
+ ]}
120
+ />
121
+ </div>
122
+ </div>
123
+ </div>
124
+ );
125
+ }
126
+
127
+ export function LightTheme() {
128
+ return <ThemeSetup theme="light" />;
129
+ }
130
+
131
+ export function DarkTheme() {
132
+ return <ThemeSetup theme="dark" />;
133
+ }
134
+
135
+ function ThemeSetup(props: { theme: "light" | "dark" }) {
136
+ return (
137
+ <CustomThemeProvider theme={props.theme}>
138
+ <Variants />
139
+ </CustomThemeProvider>
140
+ );
141
+ }
142
+
143
+ function Variant(props: { authOptions: AuthOption[] }) {
144
+ return (
145
+ <InAppWalletIcon
146
+ client={storyClient}
147
+ wallet={inAppWallet({
148
+ auth: {
149
+ options: props.authOptions,
150
+ },
151
+ })}
152
+ />
153
+ );
154
+ }
155
+
156
+ function SectionTitle(props: { title: string }) {
157
+ const theme = useCustomTheme();
158
+ return (
159
+ <p style={{ color: theme.colors.secondaryText, fontSize: "14px" }}>
160
+ {props.title}
161
+ </p>
162
+ );
163
+ }
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "5.116.1";
1
+ export const version = "5.116.2-nightly-151127d66825365cb0ed949ae28b9906ee4dfc8d-20251214000442";
@@ -51,7 +51,17 @@ export const sendOtp = async (args: PreAuthArgsType): Promise<void> => {
51
51
  });
52
52
 
53
53
  if (!response.ok) {
54
- throw new Error("Failed to send verification code");
54
+ const raw = await response.text();
55
+ let message: string | undefined;
56
+ try {
57
+ const parsed = JSON.parse(raw);
58
+ if (parsed && typeof parsed.message === "string") {
59
+ message = parsed.message;
60
+ }
61
+ } catch {
62
+ // ignore parse errors
63
+ }
64
+ throw new Error(message || "Failed to send verification code");
55
65
  }
56
66
 
57
67
  return await response.json();