thirdweb 5.58.0-nightly-3229e1f03c3cbb62ddc8dccf22ad8a8feb0a95f0-20240920000335 → 5.58.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 (67) hide show
  1. package/dist/cjs/react/web/ui/ConnectWallet/Details.js +27 -2
  2. package/dist/cjs/react/web/ui/ConnectWallet/Details.js.map +1 -1
  3. package/dist/cjs/react/web/wallets/shared/ConnectWalletSocialOptions.js +41 -21
  4. package/dist/cjs/react/web/wallets/shared/ConnectWalletSocialOptions.js.map +1 -1
  5. package/dist/cjs/version.js +1 -1
  6. package/dist/cjs/version.js.map +1 -1
  7. package/dist/cjs/wallets/in-app/core/wallet/in-app-core.js +2 -2
  8. package/dist/cjs/wallets/in-app/core/wallet/in-app-core.js.map +1 -1
  9. package/dist/cjs/wallets/in-app/web/lib/actions/get-enclave-user-status.js +2 -2
  10. package/dist/cjs/wallets/in-app/web/lib/actions/get-enclave-user-status.js.map +1 -1
  11. package/dist/cjs/wallets/in-app/web/lib/auth/iframe-auth.js +1 -1
  12. package/dist/cjs/wallets/in-app/web/lib/auth/iframe-auth.js.map +1 -1
  13. package/dist/cjs/wallets/in-app/web/lib/auth/index.js +2 -2
  14. package/dist/cjs/wallets/in-app/web/lib/auth/index.js.map +1 -1
  15. package/dist/cjs/wallets/in-app/web/lib/enclave-wallet.js +3 -3
  16. package/dist/cjs/wallets/in-app/web/lib/enclave-wallet.js.map +1 -1
  17. package/dist/cjs/wallets/in-app/web/lib/iframe-wallet.js +0 -17
  18. package/dist/cjs/wallets/in-app/web/lib/iframe-wallet.js.map +1 -1
  19. package/dist/cjs/wallets/in-app/web/lib/web-connector.js +14 -1
  20. package/dist/cjs/wallets/in-app/web/lib/web-connector.js.map +1 -1
  21. package/dist/esm/react/web/ui/ConnectWallet/Details.js +27 -2
  22. package/dist/esm/react/web/ui/ConnectWallet/Details.js.map +1 -1
  23. package/dist/esm/react/web/wallets/shared/ConnectWalletSocialOptions.js +41 -21
  24. package/dist/esm/react/web/wallets/shared/ConnectWalletSocialOptions.js.map +1 -1
  25. package/dist/esm/version.js +1 -1
  26. package/dist/esm/version.js.map +1 -1
  27. package/dist/esm/wallets/in-app/core/wallet/in-app-core.js +2 -2
  28. package/dist/esm/wallets/in-app/core/wallet/in-app-core.js.map +1 -1
  29. package/dist/esm/wallets/in-app/web/lib/actions/get-enclave-user-status.js +1 -1
  30. package/dist/esm/wallets/in-app/web/lib/actions/get-enclave-user-status.js.map +1 -1
  31. package/dist/esm/wallets/in-app/web/lib/auth/iframe-auth.js +2 -2
  32. package/dist/esm/wallets/in-app/web/lib/auth/iframe-auth.js.map +1 -1
  33. package/dist/esm/wallets/in-app/web/lib/auth/index.js +2 -2
  34. package/dist/esm/wallets/in-app/web/lib/auth/index.js.map +1 -1
  35. package/dist/esm/wallets/in-app/web/lib/enclave-wallet.js +4 -4
  36. package/dist/esm/wallets/in-app/web/lib/enclave-wallet.js.map +1 -1
  37. package/dist/esm/wallets/in-app/web/lib/iframe-wallet.js +0 -17
  38. package/dist/esm/wallets/in-app/web/lib/iframe-wallet.js.map +1 -1
  39. package/dist/esm/wallets/in-app/web/lib/web-connector.js +15 -2
  40. package/dist/esm/wallets/in-app/web/lib/web-connector.js.map +1 -1
  41. package/dist/types/react/web/ui/ConnectWallet/Details.d.ts +1 -1
  42. package/dist/types/react/web/ui/ConnectWallet/Details.d.ts.map +1 -1
  43. package/dist/types/react/web/wallets/shared/ConnectWalletSocialOptions.d.ts.map +1 -1
  44. package/dist/types/version.d.ts +1 -1
  45. package/dist/types/version.d.ts.map +1 -1
  46. package/dist/types/wallets/in-app/core/authentication/types.d.ts +1 -0
  47. package/dist/types/wallets/in-app/core/authentication/types.d.ts.map +1 -1
  48. package/dist/types/wallets/in-app/core/wallet/in-app-core.d.ts.map +1 -1
  49. package/dist/types/wallets/in-app/web/lib/actions/get-enclave-user-status.d.ts +1 -1
  50. package/dist/types/wallets/in-app/web/lib/actions/get-enclave-user-status.d.ts.map +1 -1
  51. package/dist/types/wallets/in-app/web/lib/auth/iframe-auth.d.ts +3 -0
  52. package/dist/types/wallets/in-app/web/lib/auth/iframe-auth.d.ts.map +1 -1
  53. package/dist/types/wallets/in-app/web/lib/enclave-wallet.d.ts.map +1 -1
  54. package/dist/types/wallets/in-app/web/lib/iframe-wallet.d.ts.map +1 -1
  55. package/dist/types/wallets/in-app/web/lib/web-connector.d.ts.map +1 -1
  56. package/package.json +1 -1
  57. package/src/react/web/ui/ConnectWallet/Details.tsx +44 -4
  58. package/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx +81 -48
  59. package/src/version.ts +1 -1
  60. package/src/wallets/in-app/core/authentication/types.ts +1 -0
  61. package/src/wallets/in-app/core/wallet/in-app-core.ts +2 -5
  62. package/src/wallets/in-app/web/lib/actions/get-enclave-user-status.ts +1 -1
  63. package/src/wallets/in-app/web/lib/auth/iframe-auth.ts +5 -2
  64. package/src/wallets/in-app/web/lib/auth/index.ts +2 -2
  65. package/src/wallets/in-app/web/lib/enclave-wallet.ts +5 -4
  66. package/src/wallets/in-app/web/lib/iframe-wallet.ts +0 -21
  67. package/src/wallets/in-app/web/lib/web-connector.ts +20 -2
@@ -135,6 +135,27 @@ export const ConnectWalletSocialOptions = (
135
135
  const isEmailEnabled = emailIndex !== -1;
136
136
  const phoneIndex = authOptions.indexOf("phone");
137
137
  const isPhoneEnabled = phoneIndex !== -1;
138
+ const socialLogins: SocialAuthOption[] = authOptions.filter((o) =>
139
+ socialAuthOptions.includes(o as SocialAuthOption),
140
+ ) as SocialAuthOption[];
141
+
142
+ const columnCount = useMemo(() => {
143
+ switch (socialLogins.length) {
144
+ case 7:
145
+ return 4;
146
+ case 6:
147
+ return 4;
148
+ default:
149
+ return 5;
150
+ }
151
+ }, [socialLogins.length]);
152
+
153
+ const socialLoginColumns: SocialAuthOption[][] = useMemo(() => {
154
+ return Array.from(
155
+ { length: Math.ceil(socialLogins.length / columnCount) },
156
+ (_, i) => socialLogins.slice(i * columnCount, (i + 1) * columnCount),
157
+ );
158
+ }, [socialLogins, columnCount]);
138
159
 
139
160
  const [manualInputMode, setManualInputMode] = useState<
140
161
  "email" | "phone" | "none" | null
@@ -175,10 +196,6 @@ export const ConnectWalletSocialOptions = (
175
196
  type = "tel";
176
197
  }
177
198
 
178
- const socialLogins = authOptions.filter((o) =>
179
- socialAuthOptions.includes(o as SocialAuthOption),
180
- );
181
-
182
199
  const hasSocialLogins = socialLogins.length > 0;
183
200
  const ecosystemInfo = isEcosystemWallet(wallet)
184
201
  ? {
@@ -315,49 +332,46 @@ export const ConnectWalletSocialOptions = (
315
332
  )}
316
333
  {/* Social Login */}
317
334
  {hasSocialLogins && (
318
- <Container
319
- flex="row"
320
- center="x"
321
- gap={socialLogins.length > 4 ? "xs" : "sm"}
322
- style={{
323
- justifyContent: "space-between",
324
- display: "grid",
325
- gridTemplateColumns: `repeat(${socialLogins.length}, 1fr)`,
326
- }}
327
- >
328
- {socialLogins.map((loginMethod) => {
329
- const imgIconSize = (() => {
330
- if (!showOnlyIcons) {
331
- return iconSize.md;
332
- }
333
- if (socialLogins.length > 4) {
334
- return iconSize.md;
335
- }
336
- return iconSize.lg;
337
- })();
338
-
339
- return (
340
- <SocialButton
341
- aria-label={`Login with ${loginMethod}`}
342
- data-variant={showOnlyIcons ? "icon" : "full"}
343
- key={loginMethod}
344
- variant={"outline"}
345
- disabled={props.disabled}
346
- onClick={() => {
347
- handleSocialLogin(loginMethod as SocialAuthOption);
348
- }}
349
- >
350
- <Img
351
- src={socialIcons[loginMethod as SocialAuthOption]}
352
- width={imgIconSize}
353
- height={imgIconSize}
354
- client={props.client}
355
- />
356
- {!showOnlyIcons &&
357
- `${socialLogins.length === 1 ? "Continue with " : ""}${loginMethodsLabel[loginMethod as SocialAuthOption]}`}
358
- </SocialButton>
359
- );
360
- })}
335
+ <Container flex="column" gap={socialLogins.length > 4 ? "xs" : "sm"}>
336
+ {socialLoginColumns.map((column) => (
337
+ <SocialButtonRow key={column[0]}>
338
+ {column.map((loginMethod) => {
339
+ const imgIconSize = (() => {
340
+ if (!showOnlyIcons) {
341
+ return iconSize.md;
342
+ }
343
+ if (socialLogins.length > 4) {
344
+ return iconSize.md;
345
+ }
346
+ return iconSize.lg;
347
+ })();
348
+ return (
349
+ <SocialButton
350
+ aria-label={`Login with ${loginMethod}`}
351
+ data-variant={showOnlyIcons ? "icon" : "full"}
352
+ key={loginMethod}
353
+ variant={"outline"}
354
+ disabled={props.disabled}
355
+ onClick={() => {
356
+ handleSocialLogin(loginMethod as SocialAuthOption);
357
+ }}
358
+ style={{
359
+ flexGrow: socialLogins.length < 7 ? 1 : 0,
360
+ }}
361
+ >
362
+ <Img
363
+ src={socialIcons[loginMethod as SocialAuthOption]}
364
+ width={imgIconSize}
365
+ height={imgIconSize}
366
+ client={props.client}
367
+ />
368
+ {!showOnlyIcons &&
369
+ `${socialLogins.length === 1 ? "Continue with " : ""}${loginMethodsLabel[loginMethod as SocialAuthOption]}`}
370
+ </SocialButton>
371
+ );
372
+ })}
373
+ </SocialButtonRow>
374
+ ))}
361
375
  </Container>
362
376
  )}
363
377
 
@@ -476,8 +490,27 @@ export const ConnectWalletSocialOptions = (
476
490
  );
477
491
  };
478
492
 
493
+ const SocialButtonRow = (props: { children: React.ReactNode[] }) => (
494
+ <Container
495
+ flex="row"
496
+ center="x"
497
+ gap={props.children.length > 4 ? "xs" : "sm"}
498
+ style={{
499
+ justifyContent: "center",
500
+ display: "flex",
501
+ ...{
502
+ "& > *": {
503
+ flexBasis: `${100 / props.children.length}%`,
504
+ maxWidth: `${100 / props.children.length}%`,
505
+ },
506
+ },
507
+ }}
508
+ >
509
+ {props.children}
510
+ </Container>
511
+ );
512
+
479
513
  const SocialButton = /* @__PURE__ */ styled(Button)({
480
- flexGrow: 1,
481
514
  "&[data-variant='full']": {
482
515
  display: "flex",
483
516
  justifyContent: "flex-start",
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "5.58.0-nightly-3229e1f03c3cbb62ddc8dccf22ad8a8feb0a95f0-20240920000335";
1
+ export const version = "5.58.0";
@@ -243,4 +243,5 @@ export type GetUser =
243
243
 
244
244
  export type GetAuthenticatedUserParams = {
245
245
  client: ThirdwebClient;
246
+ ecosystem?: Ecosystem;
246
247
  };
@@ -17,10 +17,7 @@ import type {
17
17
  } from "../authentication/types.js";
18
18
  import type { InAppConnector } from "../interfaces/connector.js";
19
19
 
20
- const connectorCache = new WeakMap<
21
- { client: ThirdwebClient; ecosystem?: Ecosystem },
22
- InAppConnector
23
- >();
20
+ const connectorCache = new Map<string, InAppConnector>();
24
21
 
25
22
  /**
26
23
  * @internal
@@ -30,7 +27,7 @@ export async function getOrCreateInAppWalletConnector(
30
27
  connectorFactory: (client: ThirdwebClient) => Promise<InAppConnector>,
31
28
  ecosystem?: Ecosystem,
32
29
  ) {
33
- const key = { client, ecosystem };
30
+ const key = JSON.stringify({ clientId: client.clientId, ecosystem });
34
31
  if (connectorCache.has(key)) {
35
32
  return connectorCache.get(key) as InAppConnector;
36
33
  }
@@ -9,7 +9,7 @@ import type { Ecosystem } from "../../types.js";
9
9
  *
10
10
  * @internal
11
11
  */
12
- export async function getEnclaveUserStatus({
12
+ export async function getUserStatus({
13
13
  authToken,
14
14
  client,
15
15
  ecosystem,
@@ -11,7 +11,7 @@ import type {
11
11
  import type { ClientIdWithQuerierType, Ecosystem } from "../../types.js";
12
12
  import type { InAppWalletIframeCommunicator } from "../../utils/iFrameCommunication/InAppWalletIframeCommunicator.js";
13
13
  import { generateWallet } from "../actions/generate-wallet.enclave.js";
14
- import { getEnclaveUserStatus } from "../actions/get-enclave-user-status.js";
14
+ import { getUserStatus } from "../actions/get-enclave-user-status.js";
15
15
  import { BaseLogin } from "./base-login.js";
16
16
 
17
17
  export type AuthQuerierTypes = {
@@ -28,6 +28,9 @@ export type AuthQuerierTypes = {
28
28
  storedToken: AuthStoredTokenWithCookieReturnType["storedToken"];
29
29
  recoveryCode?: string;
30
30
  };
31
+ migrateFromShardToEnclave: {
32
+ storedToken: AuthStoredTokenWithCookieReturnType["storedToken"];
33
+ };
31
34
  };
32
35
 
33
36
  /**
@@ -108,7 +111,7 @@ export class Auth {
108
111
  ): Promise<AuthLoginReturnType> {
109
112
  await this.preLogin();
110
113
 
111
- const user = await getEnclaveUserStatus({
114
+ const user = await getUserStatus({
112
115
  authToken: authToken.storedToken.cookieString,
113
116
  client: this.client,
114
117
  ecosystem: this.ecosystem,
@@ -51,8 +51,8 @@ async function getInAppWalletConnector(
51
51
  export async function getAuthenticatedUser(
52
52
  options: GetAuthenticatedUserParams,
53
53
  ) {
54
- const { client } = options;
55
- const connector = await getInAppWalletConnector(client);
54
+ const { client, ecosystem } = options;
55
+ const connector = await getInAppWalletConnector(client, ecosystem);
56
56
  const user = await connector.getUser();
57
57
  switch (user.status) {
58
58
  case UserWalletStatus.LOGGED_IN_WALLET_INITIALIZED: {
@@ -20,7 +20,7 @@ import {
20
20
  type WalletAddressObjectType,
21
21
  } from "../../core/authentication/types.js";
22
22
  import type { Ecosystem } from "../types.js";
23
- import { getEnclaveUserStatus } from "./actions/get-enclave-user-status.js";
23
+ import { getUserStatus } from "./actions/get-enclave-user-status.js";
24
24
  import { signMessage as signEnclaveMessage } from "./actions/sign-message.enclave.js";
25
25
  import { signTransaction as signEnclaveTransaction } from "./actions/sign-transaction.enclave.js";
26
26
  import { signTypedData as signEnclaveTypedData } from "./actions/sign-typed-data.enclave.js";
@@ -96,11 +96,12 @@ export class EnclaveWallet implements IWebWallet {
96
96
  return { status: UserWalletStatus.LOGGED_OUT };
97
97
  }
98
98
 
99
- const userStatus = await getEnclaveUserStatus({
99
+ const userStatus = await getUserStatus({
100
100
  authToken: token,
101
101
  client: this.client,
102
102
  ecosystem: this.ecosystem,
103
103
  });
104
+
104
105
  if (!userStatus) {
105
106
  return { status: UserWalletStatus.LOGGED_OUT };
106
107
  }
@@ -108,10 +109,10 @@ export class EnclaveWallet implements IWebWallet {
108
109
 
109
110
  const authDetails = {
110
111
  email: userStatus.linkedAccounts.find(
111
- (account) => account.type === "email",
112
+ (account) => account.details.email !== undefined,
112
113
  )?.details.email,
113
114
  phoneNumber: userStatus.linkedAccounts.find(
114
- (account) => account.type === "phone",
115
+ (account) => account.details.phone !== undefined,
115
116
  )?.details.phone,
116
117
  userWalletId: userStatus.id || "",
117
118
  recoveryShareManagement: RecoveryShareManagement.ENCLAVE,
@@ -10,7 +10,6 @@ import { type Hex, hexToString } from "../../../../utils/encoding/hex.js";
10
10
  import { parseTypedData } from "../../../../utils/signatures/helpers/parseTypedData.js";
11
11
  import { webLocalStorage } from "../../../../utils/storage/webStorage.js";
12
12
  import type { Prettify } from "../../../../utils/type-utils.js";
13
- import { getEcosystemPartnerPermissions } from "../../../ecosystem/get-ecosystem-partner-permissions.js";
14
13
  import type {
15
14
  Account,
16
15
  SendTransactionOption,
@@ -199,14 +198,6 @@ export class IFrameWallet implements IWebWallet {
199
198
  .walletManagerQuerier as unknown as InAppWalletIframeCommunicator<SignerProcedureTypes>;
200
199
  const client = this.client;
201
200
  const partnerId = this.ecosystem?.partnerId;
202
- const isEcosystem = !!this.ecosystem;
203
-
204
- const permissions = this.ecosystem?.partnerId
205
- ? await getEcosystemPartnerPermissions(
206
- this.ecosystem.id,
207
- this.ecosystem?.partnerId,
208
- )
209
- : undefined;
210
201
 
211
202
  const { address } = await querier.call<GetAddressReturnType>({
212
203
  procedureName: "getAddress",
@@ -244,10 +235,6 @@ export class IFrameWallet implements IWebWallet {
244
235
  partnerId,
245
236
  rpcEndpoint: `https://${tx.chainId}.${RPC_URL}`, // TODO (ew) shouldnt be needed
246
237
  },
247
- // Can hide the iframe if the partner has full control (no user approvals)
248
- showIframe: permissions?.permissions.includes("FULL_CONTROL_V1")
249
- ? false
250
- : isEcosystem,
251
238
  });
252
239
  return signedTransaction as Hex;
253
240
  };
@@ -296,10 +283,6 @@ export class IFrameWallet implements IWebWallet {
296
283
  partnerId,
297
284
  chainId: 1, // TODO check if we need this
298
285
  },
299
- // Can hide the iframe if the partner has full control (no user approvals)
300
- showIframe: permissions?.permissions.includes("FULL_CONTROL_V1")
301
- ? false
302
- : isEcosystem,
303
286
  });
304
287
  return signedMessage as Hex;
305
288
  },
@@ -339,10 +322,6 @@ export class IFrameWallet implements IWebWallet {
339
322
  partnerId,
340
323
  rpcEndpoint: `https://${chainId}.${RPC_URL}`, // TODO (ew) shouldnt be needed
341
324
  },
342
- // Can hide the iframe if the partner has full control (no user approvals)
343
- showIframe: permissions?.permissions.includes("FULL_CONTROL_V1")
344
- ? false
345
- : isEcosystem,
346
325
  });
347
326
  return signedTypedData as Hex;
348
327
  },
@@ -20,7 +20,7 @@ import {
20
20
  UserWalletStatus,
21
21
  } from "../../core/authentication/types.js";
22
22
  import type { InAppConnector } from "../../core/interfaces/connector.js";
23
- import { getEnclaveUserStatus } from "../lib/actions/get-enclave-user-status.js";
23
+ import { getUserStatus } from "../lib/actions/get-enclave-user-status.js";
24
24
  import type { Ecosystem, InAppWalletConstructorType } from "../types.js";
25
25
  import { InAppWalletIframeCommunicator } from "../utils/iFrameCommunication/InAppWalletIframeCommunicator.js";
26
26
  import { Auth, type AuthQuerierTypes } from "./auth/iframe-auth.js";
@@ -85,6 +85,23 @@ export class InAppWebConnector implements InAppConnector {
85
85
  ecosystem,
86
86
  onAuthSuccess: async (authResult) => {
87
87
  onAuthSuccess?.(authResult);
88
+
89
+ if (
90
+ this.ecosystem &&
91
+ authResult.storedToken.authDetails.walletType === "sharded"
92
+ ) {
93
+ // If this is an existing sharded ecosystem wallet, we'll need to migrate
94
+ const result = await this.querier.call<boolean>({
95
+ procedureName: "migrateFromShardToEnclave",
96
+ params: {
97
+ storedToken: authResult.storedToken,
98
+ },
99
+ });
100
+ if (!result) {
101
+ throw new Error("Failed to migrate from sharded to enclave wallet");
102
+ }
103
+ }
104
+
88
105
  await this.initializeWallet(authResult.storedToken.cookieString);
89
106
 
90
107
  if (!this.wallet) {
@@ -135,7 +152,7 @@ export class InAppWebConnector implements InAppConnector {
135
152
  );
136
153
  }
137
154
 
138
- const user = await getEnclaveUserStatus({
155
+ const user = await getUserStatus({
139
156
  authToken: authToken || (storedAuthToken as string),
140
157
  client: this.client,
141
158
  ecosystem: this.ecosystem,
@@ -148,6 +165,7 @@ export class InAppWebConnector implements InAppConnector {
148
165
  "Cannot initialize wallet, this user does not have a wallet generated yet",
149
166
  );
150
167
  }
168
+
151
169
  if (user.wallets[0].type === "enclave") {
152
170
  this.wallet = new EnclaveWallet({
153
171
  client: this.client,