thirdweb 5.77.0 → 5.79.0-nightly-f91f6310e9396918d0ffc5217eeb4a44cef0b8c8-20241215000412

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 (207) hide show
  1. package/dist/cjs/exports/react.js +11 -2
  2. package/dist/cjs/exports/react.js.map +1 -1
  3. package/dist/cjs/exports/react.native.js +4 -1
  4. package/dist/cjs/exports/react.native.js.map +1 -1
  5. package/dist/cjs/exports/wallets/in-app.js +2 -1
  6. package/dist/cjs/exports/wallets/in-app.js.map +1 -1
  7. package/dist/cjs/exports/wallets/in-app.native.js +2 -1
  8. package/dist/cjs/exports/wallets/in-app.native.js.map +1 -1
  9. package/dist/cjs/exports/wallets.js +2 -1
  10. package/dist/cjs/exports/wallets.js.map +1 -1
  11. package/dist/cjs/exports/wallets.native.js +2 -1
  12. package/dist/cjs/exports/wallets.native.js.map +1 -1
  13. package/dist/cjs/extensions/prebuilts/deploy-published.js +22 -16
  14. package/dist/cjs/extensions/prebuilts/deploy-published.js.map +1 -1
  15. package/dist/cjs/react/native/hooks/wallets/useUnlinkProfile.js +58 -0
  16. package/dist/cjs/react/native/hooks/wallets/useUnlinkProfile.js.map +1 -0
  17. package/dist/cjs/react/web/hooks/wallets/useUnlinkProfile.js +58 -0
  18. package/dist/cjs/react/web/hooks/wallets/useUnlinkProfile.js.map +1 -0
  19. package/dist/cjs/react/web/ui/ConnectWallet/screens/LinkedProfilesScreen.js +22 -6
  20. package/dist/cjs/react/web/ui/ConnectWallet/screens/LinkedProfilesScreen.js.map +1 -1
  21. package/dist/cjs/react/web/ui/MediaRenderer/useResolvedMediaType.js +1 -1
  22. package/dist/cjs/react/web/ui/MediaRenderer/useResolvedMediaType.js.map +1 -1
  23. package/dist/cjs/react/web/ui/prebuilt/Chain/icon.js +1 -1
  24. package/dist/cjs/react/web/ui/prebuilt/Chain/icon.js.map +1 -1
  25. package/dist/cjs/react/web/ui/prebuilt/Chain/name.js +15 -11
  26. package/dist/cjs/react/web/ui/prebuilt/Chain/name.js.map +1 -1
  27. package/dist/cjs/react/web/ui/prebuilt/Chain/provider.js +1 -0
  28. package/dist/cjs/react/web/ui/prebuilt/Chain/provider.js.map +1 -1
  29. package/dist/cjs/react/web/ui/prebuilt/Wallet/icon.js +79 -0
  30. package/dist/cjs/react/web/ui/prebuilt/Wallet/icon.js.map +1 -0
  31. package/dist/cjs/react/web/ui/prebuilt/Wallet/name.js +105 -0
  32. package/dist/cjs/react/web/ui/prebuilt/Wallet/name.js.map +1 -0
  33. package/dist/cjs/react/web/ui/prebuilt/Wallet/provider.js +47 -0
  34. package/dist/cjs/react/web/ui/prebuilt/Wallet/provider.js.map +1 -0
  35. package/dist/cjs/react/web/wallets/in-app/CountrySelector.js +11 -10
  36. package/dist/cjs/react/web/wallets/in-app/CountrySelector.js.map +1 -1
  37. package/dist/cjs/react/web/wallets/in-app/InputSelectionUI.js +3 -1
  38. package/dist/cjs/react/web/wallets/in-app/InputSelectionUI.js.map +1 -1
  39. package/dist/cjs/react/web/wallets/in-app/supported-sms-countries.js.map +1 -1
  40. package/dist/cjs/react/web/wallets/shared/ConnectWalletSocialOptions.js +1 -1
  41. package/dist/cjs/react/web/wallets/shared/ConnectWalletSocialOptions.js.map +1 -1
  42. package/dist/cjs/version.js +1 -1
  43. package/dist/cjs/version.js.map +1 -1
  44. package/dist/cjs/wallets/in-app/core/authentication/linkAccount.js +31 -0
  45. package/dist/cjs/wallets/in-app/core/authentication/linkAccount.js.map +1 -1
  46. package/dist/cjs/wallets/in-app/native/auth/index.js +30 -3
  47. package/dist/cjs/wallets/in-app/native/auth/index.js.map +1 -1
  48. package/dist/cjs/wallets/in-app/native/native-connector.js +8 -0
  49. package/dist/cjs/wallets/in-app/native/native-connector.js.map +1 -1
  50. package/dist/cjs/wallets/in-app/web/lib/auth/index.js +30 -0
  51. package/dist/cjs/wallets/in-app/web/lib/auth/index.js.map +1 -1
  52. package/dist/cjs/wallets/in-app/web/lib/web-connector.js +8 -0
  53. package/dist/cjs/wallets/in-app/web/lib/web-connector.js.map +1 -1
  54. package/dist/esm/exports/react.js +5 -0
  55. package/dist/esm/exports/react.js.map +1 -1
  56. package/dist/esm/exports/react.native.js +1 -0
  57. package/dist/esm/exports/react.native.js.map +1 -1
  58. package/dist/esm/exports/wallets/in-app.js +1 -1
  59. package/dist/esm/exports/wallets/in-app.js.map +1 -1
  60. package/dist/esm/exports/wallets/in-app.native.js +1 -1
  61. package/dist/esm/exports/wallets/in-app.native.js.map +1 -1
  62. package/dist/esm/exports/wallets.js +1 -1
  63. package/dist/esm/exports/wallets.js.map +1 -1
  64. package/dist/esm/exports/wallets.native.js +1 -1
  65. package/dist/esm/exports/wallets.native.js.map +1 -1
  66. package/dist/esm/extensions/prebuilts/deploy-published.js +22 -16
  67. package/dist/esm/extensions/prebuilts/deploy-published.js.map +1 -1
  68. package/dist/esm/react/native/hooks/wallets/useUnlinkProfile.js +55 -0
  69. package/dist/esm/react/native/hooks/wallets/useUnlinkProfile.js.map +1 -0
  70. package/dist/esm/react/web/hooks/wallets/useUnlinkProfile.js +55 -0
  71. package/dist/esm/react/web/hooks/wallets/useUnlinkProfile.js.map +1 -0
  72. package/dist/esm/react/web/ui/ConnectWallet/screens/LinkedProfilesScreen.js +22 -6
  73. package/dist/esm/react/web/ui/ConnectWallet/screens/LinkedProfilesScreen.js.map +1 -1
  74. package/dist/esm/react/web/ui/MediaRenderer/useResolvedMediaType.js +1 -1
  75. package/dist/esm/react/web/ui/MediaRenderer/useResolvedMediaType.js.map +1 -1
  76. package/dist/esm/react/web/ui/prebuilt/Chain/icon.js +1 -1
  77. package/dist/esm/react/web/ui/prebuilt/Chain/icon.js.map +1 -1
  78. package/dist/esm/react/web/ui/prebuilt/Chain/name.js +14 -11
  79. package/dist/esm/react/web/ui/prebuilt/Chain/name.js.map +1 -1
  80. package/dist/esm/react/web/ui/prebuilt/Chain/provider.js +1 -0
  81. package/dist/esm/react/web/ui/prebuilt/Chain/provider.js.map +1 -1
  82. package/dist/esm/react/web/ui/prebuilt/Wallet/icon.js +75 -0
  83. package/dist/esm/react/web/ui/prebuilt/Wallet/icon.js.map +1 -0
  84. package/dist/esm/react/web/ui/prebuilt/Wallet/name.js +100 -0
  85. package/dist/esm/react/web/ui/prebuilt/Wallet/name.js.map +1 -0
  86. package/dist/esm/react/web/ui/prebuilt/Wallet/provider.js +42 -0
  87. package/dist/esm/react/web/ui/prebuilt/Wallet/provider.js.map +1 -0
  88. package/dist/esm/react/web/wallets/in-app/CountrySelector.js +10 -10
  89. package/dist/esm/react/web/wallets/in-app/CountrySelector.js.map +1 -1
  90. package/dist/esm/react/web/wallets/in-app/InputSelectionUI.js +4 -2
  91. package/dist/esm/react/web/wallets/in-app/InputSelectionUI.js.map +1 -1
  92. package/dist/esm/react/web/wallets/in-app/supported-sms-countries.js.map +1 -1
  93. package/dist/esm/react/web/wallets/shared/ConnectWalletSocialOptions.js +1 -1
  94. package/dist/esm/react/web/wallets/shared/ConnectWalletSocialOptions.js.map +1 -1
  95. package/dist/esm/version.js +1 -1
  96. package/dist/esm/version.js.map +1 -1
  97. package/dist/esm/wallets/in-app/core/authentication/linkAccount.js +30 -0
  98. package/dist/esm/wallets/in-app/core/authentication/linkAccount.js.map +1 -1
  99. package/dist/esm/wallets/in-app/native/auth/index.js +29 -3
  100. package/dist/esm/wallets/in-app/native/auth/index.js.map +1 -1
  101. package/dist/esm/wallets/in-app/native/native-connector.js +9 -1
  102. package/dist/esm/wallets/in-app/native/native-connector.js.map +1 -1
  103. package/dist/esm/wallets/in-app/web/lib/auth/index.js +29 -0
  104. package/dist/esm/wallets/in-app/web/lib/auth/index.js.map +1 -1
  105. package/dist/esm/wallets/in-app/web/lib/web-connector.js +9 -1
  106. package/dist/esm/wallets/in-app/web/lib/web-connector.js.map +1 -1
  107. package/dist/types/exports/react.d.ts +4 -0
  108. package/dist/types/exports/react.d.ts.map +1 -1
  109. package/dist/types/exports/react.native.d.ts +1 -0
  110. package/dist/types/exports/react.native.d.ts.map +1 -1
  111. package/dist/types/exports/wallets/in-app.d.ts +3 -2
  112. package/dist/types/exports/wallets/in-app.d.ts.map +1 -1
  113. package/dist/types/exports/wallets/in-app.native.d.ts +3 -2
  114. package/dist/types/exports/wallets/in-app.native.d.ts.map +1 -1
  115. package/dist/types/exports/wallets.d.ts +3 -2
  116. package/dist/types/exports/wallets.d.ts.map +1 -1
  117. package/dist/types/exports/wallets.native.d.ts +3 -2
  118. package/dist/types/exports/wallets.native.d.ts.map +1 -1
  119. package/dist/types/extensions/prebuilts/deploy-published.d.ts.map +1 -1
  120. package/dist/types/react/native/hooks/wallets/useUnlinkProfile.d.ts +34 -0
  121. package/dist/types/react/native/hooks/wallets/useUnlinkProfile.d.ts.map +1 -0
  122. package/dist/types/react/web/hooks/wallets/useUnlinkProfile.d.ts +34 -0
  123. package/dist/types/react/web/hooks/wallets/useUnlinkProfile.d.ts.map +1 -0
  124. package/dist/types/react/web/ui/ConnectWallet/screens/LinkedProfilesScreen.d.ts.map +1 -1
  125. package/dist/types/react/web/ui/prebuilt/Chain/name.d.ts +10 -1
  126. package/dist/types/react/web/ui/prebuilt/Chain/name.d.ts.map +1 -1
  127. package/dist/types/react/web/ui/prebuilt/Chain/provider.d.ts +1 -0
  128. package/dist/types/react/web/ui/prebuilt/Chain/provider.d.ts.map +1 -1
  129. package/dist/types/react/web/ui/prebuilt/Wallet/icon.d.ts +81 -0
  130. package/dist/types/react/web/ui/prebuilt/Wallet/icon.d.ts.map +1 -0
  131. package/dist/types/react/web/ui/prebuilt/Wallet/name.d.ts +111 -0
  132. package/dist/types/react/web/ui/prebuilt/Wallet/name.d.ts.map +1 -0
  133. package/dist/types/react/web/ui/prebuilt/Wallet/provider.d.ts +41 -0
  134. package/dist/types/react/web/ui/prebuilt/Wallet/provider.d.ts.map +1 -0
  135. package/dist/types/react/web/wallets/in-app/CountrySelector.d.ts +2 -0
  136. package/dist/types/react/web/wallets/in-app/CountrySelector.d.ts.map +1 -1
  137. package/dist/types/react/web/wallets/in-app/InputSelectionUI.d.ts +2 -0
  138. package/dist/types/react/web/wallets/in-app/InputSelectionUI.d.ts.map +1 -1
  139. package/dist/types/react/web/wallets/in-app/supported-sms-countries.d.ts +946 -5
  140. package/dist/types/react/web/wallets/in-app/supported-sms-countries.d.ts.map +1 -1
  141. package/dist/types/react/web/wallets/shared/ConnectWalletSocialOptions.d.ts.map +1 -1
  142. package/dist/types/version.d.ts +1 -1
  143. package/dist/types/version.d.ts.map +1 -1
  144. package/dist/types/wallets/ecosystem/types.d.ts +5 -0
  145. package/dist/types/wallets/ecosystem/types.d.ts.map +1 -1
  146. package/dist/types/wallets/in-app/core/authentication/linkAccount.d.ts +13 -0
  147. package/dist/types/wallets/in-app/core/authentication/linkAccount.d.ts.map +1 -1
  148. package/dist/types/wallets/in-app/core/authentication/types.d.ts +5 -0
  149. package/dist/types/wallets/in-app/core/authentication/types.d.ts.map +1 -1
  150. package/dist/types/wallets/in-app/core/interfaces/connector.d.ts +1 -0
  151. package/dist/types/wallets/in-app/core/interfaces/connector.d.ts.map +1 -1
  152. package/dist/types/wallets/in-app/core/wallet/types.d.ts +8 -3
  153. package/dist/types/wallets/in-app/core/wallet/types.d.ts.map +1 -1
  154. package/dist/types/wallets/in-app/native/auth/index.d.ts +27 -4
  155. package/dist/types/wallets/in-app/native/auth/index.d.ts.map +1 -1
  156. package/dist/types/wallets/in-app/native/native-connector.d.ts +4 -3
  157. package/dist/types/wallets/in-app/native/native-connector.d.ts.map +1 -1
  158. package/dist/types/wallets/in-app/web/lib/auth/index.d.ts +27 -1
  159. package/dist/types/wallets/in-app/web/lib/auth/index.d.ts.map +1 -1
  160. package/dist/types/wallets/in-app/web/lib/web-connector.d.ts +4 -3
  161. package/dist/types/wallets/in-app/web/lib/web-connector.d.ts.map +1 -1
  162. package/package.json +3 -2
  163. package/src/exports/react.native.ts +1 -0
  164. package/src/exports/react.ts +15 -0
  165. package/src/exports/wallets/in-app.native.ts +7 -0
  166. package/src/exports/wallets/in-app.ts +7 -0
  167. package/src/exports/wallets.native.ts +7 -0
  168. package/src/exports/wallets.ts +7 -0
  169. package/src/extensions/prebuilts/deploy-published.ts +27 -20
  170. package/src/react/core/hooks/wallets/useAddConnectedWallet.test.tsx +52 -0
  171. package/src/react/core/hooks/wallets/useConnect.test.tsx +105 -0
  172. package/src/react/core/hooks/wallets/useSetActiveWallet.test.tsx +53 -0
  173. package/src/react/native/hooks/wallets/useUnlinkProfile.test.tsx +75 -0
  174. package/src/react/native/hooks/wallets/useUnlinkProfile.ts +62 -0
  175. package/src/react/web/hooks/wallets/useUnlinkProfile.test.tsx +75 -0
  176. package/src/react/web/hooks/wallets/useUnlinkProfile.ts +62 -0
  177. package/src/react/web/ui/ConnectWallet/screens/LinkedProfilesScreen.test.tsx +25 -0
  178. package/src/react/web/ui/ConnectWallet/screens/LinkedProfilesScreen.tsx +86 -44
  179. package/src/react/web/ui/MediaRenderer/useResolvedMediaType.ts +1 -1
  180. package/src/react/web/ui/prebuilt/Chain/icon.tsx +1 -1
  181. package/src/react/web/ui/prebuilt/Chain/name.test.tsx +19 -1
  182. package/src/react/web/ui/prebuilt/Chain/name.tsx +19 -13
  183. package/src/react/web/ui/prebuilt/Chain/provider.tsx +1 -0
  184. package/src/react/web/ui/prebuilt/Wallet/icon.test.tsx +30 -0
  185. package/src/react/web/ui/prebuilt/Wallet/icon.tsx +120 -0
  186. package/src/react/web/ui/prebuilt/Wallet/name.test.tsx +55 -0
  187. package/src/react/web/ui/prebuilt/Wallet/name.tsx +164 -0
  188. package/src/react/web/ui/prebuilt/Wallet/provider.test.tsx +61 -0
  189. package/src/react/web/ui/prebuilt/Wallet/provider.tsx +65 -0
  190. package/src/react/web/wallets/in-app/CountrySelector.test.tsx +45 -0
  191. package/src/react/web/wallets/in-app/CountrySelector.tsx +16 -13
  192. package/src/react/web/wallets/in-app/InputSelectionUI.test.tsx +45 -0
  193. package/src/react/web/wallets/in-app/InputSelectionUI.tsx +8 -2
  194. package/src/react/web/wallets/in-app/supported-sms-countries.ts +3 -1
  195. package/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx +3 -0
  196. package/src/version.ts +1 -1
  197. package/src/wallets/ecosystem/types.ts +5 -0
  198. package/src/wallets/in-app/core/authentication/linkAccount.test.ts +160 -0
  199. package/src/wallets/in-app/core/authentication/linkAccount.ts +49 -0
  200. package/src/wallets/in-app/core/authentication/types.ts +6 -0
  201. package/src/wallets/in-app/core/interfaces/connector.ts +1 -0
  202. package/src/wallets/in-app/core/wallet/types.ts +12 -8
  203. package/src/wallets/in-app/native/auth/index.ts +31 -3
  204. package/src/wallets/in-app/native/native-connector.ts +11 -0
  205. package/src/wallets/in-app/web/lib/auth/index.ts +31 -0
  206. package/src/wallets/in-app/web/lib/web-connector.ts +11 -0
  207. package/src/wallets/manager/connection-manager.test.ts +133 -133
@@ -0,0 +1,45 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { render, screen } from "../../../../../test/src/react-render.js";
3
+ import { getCountrySelector } from "./CountrySelector.js";
4
+ import { InputSelectionUI } from "./InputSelectionUI.js";
5
+
6
+ vi.mock("./CountrySelector.js", async (importOriginal) => ({
7
+ ...(await importOriginal()),
8
+ getCountrySelector: vi.fn(),
9
+ }));
10
+
11
+ describe("InputSelectionUI", () => {
12
+ it("should initialize countryCodeInfo with defaultSmsCountryCode", () => {
13
+ const mockGetCountrySelector = vi.mocked(getCountrySelector);
14
+ mockGetCountrySelector.mockReturnValue("CA +1");
15
+
16
+ render(
17
+ <InputSelectionUI
18
+ defaultSmsCountryCode="CA"
19
+ onSelect={vi.fn()}
20
+ placeholder=""
21
+ name=""
22
+ type=""
23
+ submitButtonText=""
24
+ format="phone"
25
+ />,
26
+ );
27
+
28
+ expect(screen.getByRole("combobox")).toHaveValue("CA +1");
29
+ });
30
+
31
+ it('should initialize countryCodeInfo with "US +1" if defaultSmsCountryCode is not provided', () => {
32
+ render(
33
+ <InputSelectionUI
34
+ onSelect={vi.fn()}
35
+ placeholder=""
36
+ name=""
37
+ type=""
38
+ submitButtonText=""
39
+ format="phone"
40
+ />,
41
+ );
42
+
43
+ expect(screen.getByRole("combobox")).toHaveValue("US +1");
44
+ });
45
+ });
@@ -10,7 +10,8 @@ import { Spacer } from "../../ui/components/Spacer.js";
10
10
  import { IconButton } from "../../ui/components/buttons.js";
11
11
  import { Input, InputContainer } from "../../ui/components/formElements.js";
12
12
  import { Text } from "../../ui/components/text.js";
13
- import { CountrySelector } from "./CountrySelector.js";
13
+ import { CountrySelector, getCountrySelector } from "./CountrySelector.js";
14
+ import type { SupportedSmsCountry } from "./supported-sms-countries.js";
14
15
 
15
16
  export function InputSelectionUI(props: {
16
17
  onSelect: (data: string) => void;
@@ -22,8 +23,13 @@ export function InputSelectionUI(props: {
22
23
  submitButtonText: string;
23
24
  format?: "phone";
24
25
  disabled?: boolean;
26
+ defaultSmsCountryCode?: SupportedSmsCountry;
25
27
  }) {
26
- const [countryCodeInfo, setCountryCodeInfo] = useState("US +1");
28
+ const [countryCodeInfo, setCountryCodeInfo] = useState(
29
+ props.defaultSmsCountryCode
30
+ ? getCountrySelector(props.defaultSmsCountryCode)
31
+ : "US +1",
32
+ );
27
33
  const [input, setInput] = useState("");
28
34
  const [error, setError] = useState<string | undefined>();
29
35
  const [showError, setShowError] = useState(false);
@@ -1,3 +1,5 @@
1
+ export type SupportedSmsCountry =
2
+ (typeof supportedSmsCountries)[number]["countryIsoCode"];
1
3
  export const supportedSmsCountries = [
2
4
  {
3
5
  countryIsoCode: "AD",
@@ -1183,4 +1185,4 @@ export const supportedSmsCountries = [
1183
1185
  countryName: "Zimbabwe",
1184
1186
  phoneNumberCode: "263",
1185
1187
  },
1186
- ];
1188
+ ] as const;
@@ -448,6 +448,9 @@ export const ConnectWalletSocialOptions = (
448
448
  disabled={props.disabled}
449
449
  emptyErrorMessage={emptyErrorMessage}
450
450
  submitButtonText={locale.submitEmail}
451
+ defaultSmsCountryCode={
452
+ wallet.getConfig()?.auth?.defaultSmsCountryCode
453
+ }
451
454
  />
452
455
  ) : (
453
456
  <WalletTypeRowButton
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "5.77.0";
1
+ export const version = "5.79.0-nightly-f91f6310e9396918d0ffc5217eeb4a44cef0b8c8-20241215000412";
@@ -1,3 +1,4 @@
1
+ import type { SupportedSmsCountry } from "../../react/web/wallets/in-app/supported-sms-countries.js";
1
2
  import type {
2
3
  InAppWalletAutoConnectOptions,
3
4
  InAppWalletConnectionOptions,
@@ -13,6 +14,10 @@ export type EcosystemWalletCreationOptions = {
13
14
  * Optional url to redirect to after authentication
14
15
  */
15
16
  redirectUrl?: string;
17
+ /**
18
+ * The default country code to use for SMS authentication
19
+ */
20
+ defaultSmsCountryCode?: SupportedSmsCountry;
16
21
  };
17
22
  /**
18
23
  * The partnerId of the ecosystem wallet to connect to
@@ -0,0 +1,160 @@
1
+ import { beforeEach, describe, expect, it, vi } from "vitest";
2
+ import { createThirdwebClient } from "../../../../client/client.js";
3
+ import { getClientFetch } from "../../../../utils/fetch.js";
4
+ import type { ClientScopedStorage } from "./client-scoped-storage.js";
5
+ import {
6
+ getLinkedProfilesInternal,
7
+ linkAccount,
8
+ unlinkAccount,
9
+ } from "./linkAccount.js";
10
+ import type { Profile } from "./types.js";
11
+
12
+ vi.mock("../../../../utils/fetch.js");
13
+
14
+ describe("Account linking functions", () => {
15
+ const mockClient = createThirdwebClient({ clientId: "mock-client-id" });
16
+ const mockStorage = {
17
+ getAuthCookie: vi.fn(),
18
+ } as unknown as ClientScopedStorage;
19
+ const mockFetch = vi.fn();
20
+ const mockLinkedAccounts = [
21
+ { type: "email", details: { email: "user@example.com" } },
22
+ { type: "phone", details: { phone: "1234567890" } },
23
+ { type: "wallet", details: { address: "0x123456789" } },
24
+ ] satisfies Profile[];
25
+
26
+ beforeEach(() => {
27
+ vi.clearAllMocks();
28
+ vi.mocked(getClientFetch).mockReturnValue(mockFetch);
29
+ vi.mocked(mockStorage.getAuthCookie).mockResolvedValue("mock-token");
30
+ mockFetch.mockResolvedValue({
31
+ ok: true,
32
+ json: () => Promise.resolve({ linkedAccounts: mockLinkedAccounts }),
33
+ });
34
+ });
35
+
36
+ describe("linkAccount", () => {
37
+ it("should successfully link an account", async () => {
38
+ const result = await linkAccount({
39
+ client: mockClient,
40
+ tokenToLink: "token-to-link",
41
+ storage: mockStorage,
42
+ });
43
+
44
+ expect(mockFetch).toHaveBeenCalledWith(
45
+ "https://embedded-wallet.thirdweb.com/api/2024-05-05/account/connect",
46
+ {
47
+ method: "POST",
48
+ headers: {
49
+ Authorization: "Bearer iaw-auth-token:mock-token",
50
+ "Content-Type": "application/json",
51
+ },
52
+ body: JSON.stringify({
53
+ accountAuthTokenToConnect: "token-to-link",
54
+ }),
55
+ },
56
+ );
57
+ expect(result).toEqual(mockLinkedAccounts);
58
+ });
59
+
60
+ it("should throw error when no user is logged in", async () => {
61
+ vi.mocked(mockStorage.getAuthCookie).mockResolvedValue(null);
62
+
63
+ await expect(
64
+ linkAccount({
65
+ client: mockClient,
66
+ tokenToLink: "token-to-link",
67
+ storage: mockStorage,
68
+ }),
69
+ ).rejects.toThrow("Failed to link account, no user logged in");
70
+ });
71
+ });
72
+
73
+ describe("unlinkAccount", () => {
74
+ const profileToUnlink = {
75
+ type: "email",
76
+ details: { email: "user@example.com" },
77
+ } satisfies Profile;
78
+ it("should successfully unlink an account", async () => {
79
+ const result = await unlinkAccount({
80
+ client: mockClient,
81
+ profileToUnlink,
82
+ storage: mockStorage,
83
+ });
84
+
85
+ expect(mockFetch).toHaveBeenCalledWith(
86
+ "https://embedded-wallet.thirdweb.com/api/2024-05-05/account/disconnect",
87
+ {
88
+ method: "POST",
89
+ headers: {
90
+ Authorization: "Bearer iaw-auth-token:mock-token",
91
+ "Content-Type": "application/json",
92
+ },
93
+ body: JSON.stringify(profileToUnlink),
94
+ },
95
+ );
96
+ expect(result).toEqual(mockLinkedAccounts);
97
+ });
98
+
99
+ it("should throw error when no user is logged in", async () => {
100
+ vi.mocked(mockStorage.getAuthCookie).mockResolvedValue(null);
101
+
102
+ await expect(
103
+ unlinkAccount({
104
+ client: mockClient,
105
+ profileToUnlink,
106
+ storage: mockStorage,
107
+ }),
108
+ ).rejects.toThrow("Failed to unlink account, no user logged in");
109
+ });
110
+ it("should handle API errors", async () => {
111
+ mockFetch.mockResolvedValue({
112
+ ok: false,
113
+ json: () => Promise.resolve({ message: "API Error" }),
114
+ });
115
+
116
+ await expect(
117
+ unlinkAccount({
118
+ client: mockClient,
119
+ profileToUnlink,
120
+ storage: mockStorage,
121
+ }),
122
+ ).rejects.toThrow("API Error");
123
+ });
124
+ });
125
+
126
+ describe("getLinkedProfilesInternal", () => {
127
+ it("should successfully get linked profiles", async () => {
128
+ const result = await getLinkedProfilesInternal({
129
+ client: mockClient,
130
+ storage: mockStorage,
131
+ });
132
+
133
+ expect(mockFetch).toHaveBeenCalledWith(
134
+ "https://embedded-wallet.thirdweb.com/api/2024-05-05/accounts",
135
+ {
136
+ method: "GET",
137
+ headers: {
138
+ Authorization: "Bearer iaw-auth-token:mock-token",
139
+ "Content-Type": "application/json",
140
+ },
141
+ },
142
+ );
143
+ expect(result).toEqual(mockLinkedAccounts);
144
+ });
145
+
146
+ it("should handle API errors", async () => {
147
+ mockFetch.mockResolvedValue({
148
+ ok: false,
149
+ json: () => Promise.resolve({ message: "API Error" }),
150
+ });
151
+
152
+ await expect(
153
+ getLinkedProfilesInternal({
154
+ client: mockClient,
155
+ storage: mockStorage,
156
+ }),
157
+ ).rejects.toThrow("API Error");
158
+ });
159
+ });
160
+ });
@@ -57,6 +57,55 @@ export async function linkAccount({
57
57
  return (linkedAccounts ?? []) satisfies Profile[];
58
58
  }
59
59
 
60
+ /**
61
+ * @description
62
+ * Links a new account to the current one using an auth token.
63
+ * For the public-facing API, use `wallet.linkProfile` instead.
64
+ *
65
+ * @internal
66
+ */
67
+ export async function unlinkAccount({
68
+ client,
69
+ ecosystem,
70
+ profileToUnlink,
71
+ storage,
72
+ }: {
73
+ client: ThirdwebClient;
74
+ ecosystem?: Ecosystem;
75
+ profileToUnlink: Profile;
76
+ storage: ClientScopedStorage;
77
+ }): Promise<Profile[]> {
78
+ const clientFetch = getClientFetch(client, ecosystem);
79
+ const IN_APP_URL = getThirdwebBaseUrl("inAppWallet");
80
+ const currentAccountToken = await storage.getAuthCookie();
81
+
82
+ if (!currentAccountToken) {
83
+ throw new Error("Failed to unlink account, no user logged in");
84
+ }
85
+
86
+ const headers: Record<string, string> = {
87
+ Authorization: `Bearer iaw-auth-token:${currentAccountToken}`,
88
+ "Content-Type": "application/json",
89
+ };
90
+ const linkedDetailsResp = await clientFetch(
91
+ `${IN_APP_URL}/api/2024-05-05/account/disconnect`,
92
+ {
93
+ method: "POST",
94
+ headers,
95
+ body: stringify(profileToUnlink),
96
+ },
97
+ );
98
+
99
+ if (!linkedDetailsResp.ok) {
100
+ const body = await linkedDetailsResp.json();
101
+ throw new Error(body.message || "Failed to unlink account.");
102
+ }
103
+
104
+ const { linkedAccounts } = await linkedDetailsResp.json();
105
+
106
+ return (linkedAccounts ?? []) satisfies Profile[];
107
+ }
108
+
60
109
  /**
61
110
  * @description
62
111
  * Gets the linked accounts for the current user.
@@ -250,3 +250,9 @@ export type GetAuthenticatedUserParams = {
250
250
  client: ThirdwebClient;
251
251
  ecosystem?: Ecosystem;
252
252
  };
253
+
254
+ export type UnlinkParams = {
255
+ client: ThirdwebClient;
256
+ ecosystem?: Ecosystem;
257
+ profileToUnlink: Profile;
258
+ };
@@ -36,5 +36,6 @@ export interface InAppConnector {
36
36
  ): Promise<AuthLoginReturnType>;
37
37
  logout(): Promise<LogoutReturnType>;
38
38
  linkProfile(args: AuthArgsType): Promise<Profile[]>;
39
+ unlinkProfile(args: Profile): Promise<Profile[]>;
39
40
  getProfiles(): Promise<Profile[]>;
40
41
  }
@@ -1,5 +1,7 @@
1
1
  import type { Chain } from "../../../../chains/types.js";
2
2
  import type { ThirdwebClient } from "../../../../client/client.js";
3
+ import type { SupportedSmsCountry } from "../../../../react/web/wallets/in-app/supported-sms-countries.js";
4
+ import type { Prettify } from "../../../../utils/type-utils.js";
3
5
  import type { SmartWalletOptions } from "../../../smart/types.js";
4
6
  import type {
5
7
  AuthOption,
@@ -19,14 +21,12 @@ export type Ecosystem = {
19
21
  partnerId?: string;
20
22
  };
21
23
 
22
- export type InAppWalletConnectionOptions = (
23
- | MultiStepAuthArgsType
24
- | SingleStepAuthArgsType
25
- ) & {
26
- client: ThirdwebClient;
27
- chain?: Chain;
28
- redirect?: boolean;
29
- };
24
+ export type InAppWalletConnectionOptions = Prettify<
25
+ (MultiStepAuthArgsType | SingleStepAuthArgsType) & {
26
+ client: ThirdwebClient;
27
+ chain?: Chain;
28
+ }
29
+ >;
30
30
 
31
31
  export type InAppWalletAutoConnectOptions = {
32
32
  client: ThirdwebClient;
@@ -59,6 +59,10 @@ export type InAppWalletCreationOptions =
59
59
  * The domain of the passkey to use for authentication
60
60
  */
61
61
  passkeyDomain?: string;
62
+ /**
63
+ * The default country code to use for SMS authentication
64
+ */
65
+ defaultSmsCountryCode?: SupportedSmsCountry;
62
66
  };
63
67
  /**
64
68
  * Metadata to display in the Connect Modal
@@ -3,6 +3,7 @@ import type {
3
3
  AuthArgsType,
4
4
  GetAuthenticatedUserParams,
5
5
  PreAuthArgsType,
6
+ UnlinkParams,
6
7
  } from "../../core/authentication/types.js";
7
8
  import { getOrCreateInAppWalletConnector } from "../../core/wallet/in-app-core.js";
8
9
  import type { Ecosystem } from "../../core/wallet/types.js";
@@ -146,9 +147,6 @@ export async function authenticate(args: AuthArgsType) {
146
147
  *
147
148
  * **When a profile is linked to the account, that profile can then be used to sign into the account.**
148
149
  *
149
- * This method is only available for in-app wallets.
150
- *
151
- * @param wallet - The wallet to link an additional profile to.
152
150
  * @param auth - The authentications options to add the new profile.
153
151
  * @returns A promise that resolves to the currently linked profiles when the connection is successful.
154
152
  * @throws If the connection fails, if the profile is already linked to the account, or if the profile is already associated with another account.
@@ -167,6 +165,36 @@ export async function linkProfile(args: AuthArgsType) {
167
165
  return await connector.linkProfile(args);
168
166
  }
169
167
 
168
+ /**
169
+ * Disconnects an existing profile (authentication method) from the current user. Once disconnected, that profile can no longer be used to sign into the account.
170
+ *
171
+ * @param args - The object containing the profile that we want to unlink.
172
+ * @returns A promise that resolves to the updated linked profiles.
173
+ * @throws If the unlinking fails. This can happen if the account has no other associated profiles or if the profile that is being unlinked doesn't exists for the current logged in user.
174
+ *
175
+ * @example
176
+ * ```ts
177
+ * import { inAppWallet } from "thirdweb/wallets";
178
+ *
179
+ * const wallet = inAppWallet();
180
+ * wallet.connect({ strategy: "google" });
181
+ *
182
+ * const profiles = await getProfiles({
183
+ * client,
184
+ * });
185
+ *
186
+ * const updatedProfiles = await unlinkProfile({
187
+ * client,
188
+ * profileToUnlink: profiles[0],
189
+ * });
190
+ * ```
191
+ * @wallet
192
+ */
193
+ export async function unlinkProfile(args: UnlinkParams) {
194
+ const connector = await getInAppWalletConnector(args.client, args.ecosystem);
195
+ return await connector.unlinkProfile(args.profileToUnlink);
196
+ }
197
+
170
198
  /**
171
199
  * Gets the linked profiles for the connected in-app or ecosystem wallet.
172
200
  *
@@ -10,6 +10,7 @@ import { customJwt } from "../core/authentication/jwt.js";
10
10
  import {
11
11
  getLinkedProfilesInternal,
12
12
  linkAccount,
13
+ unlinkAccount,
13
14
  } from "../core/authentication/linkAccount.js";
14
15
  import {
15
16
  loginWithPasskey,
@@ -24,6 +25,7 @@ import type {
24
25
  LogoutReturnType,
25
26
  MultiStepAuthArgsType,
26
27
  MultiStepAuthProviderType,
28
+ Profile,
27
29
  SingleStepAuthArgsType,
28
30
  } from "../core/authentication/types.js";
29
31
  import type { InAppConnector } from "../core/interfaces/connector.js";
@@ -332,6 +334,15 @@ export class InAppNativeConnector implements InAppConnector {
332
334
  });
333
335
  }
334
336
 
337
+ async unlinkProfile(profile: Profile) {
338
+ return await unlinkAccount({
339
+ client: this.client,
340
+ ecosystem: this.ecosystem,
341
+ storage: this.storage,
342
+ profileToUnlink: profile,
343
+ });
344
+ }
345
+
335
346
  async getProfiles() {
336
347
  return getLinkedProfilesInternal({
337
348
  client: this.client,
@@ -5,6 +5,7 @@ import type {
5
5
  GetAuthenticatedUserParams,
6
6
  PreAuthArgsType,
7
7
  SocialAuthArgsType,
8
+ UnlinkParams,
8
9
  } from "../../../core/authentication/types.js";
9
10
  import { getOrCreateInAppWalletConnector } from "../../../core/wallet/in-app-core.js";
10
11
  import type { Ecosystem } from "../../../core/wallet/types.js";
@@ -204,6 +205,36 @@ export async function linkProfile(args: AuthArgsType) {
204
205
  return await connector.linkProfile(args);
205
206
  }
206
207
 
208
+ /**
209
+ * Disconnects an existing profile (authentication method) from the current user. Once disconnected, that profile can no longer be used to sign into the account.
210
+ *
211
+ * @param args - The object containing the profile that we want to unlink.
212
+ * @returns A promise that resolves to the updated linked profiles.
213
+ * @throws If the unlinking fails. This can happen if the account has no other associated profiles or if the profile that is being unlinked doesn't exists for the current logged in user.
214
+ *
215
+ * @example
216
+ * ```ts
217
+ * import { inAppWallet } from "thirdweb/wallets";
218
+ *
219
+ * const wallet = inAppWallet();
220
+ * wallet.connect({ strategy: "google" });
221
+ *
222
+ * const profiles = await getProfiles({
223
+ * client,
224
+ * });
225
+ *
226
+ * const updatedProfiles = await unlinkProfile({
227
+ * client,
228
+ * profileToUnlink: profiles[0],
229
+ * });
230
+ * ```
231
+ * @wallet
232
+ */
233
+ export async function unlinkProfile(args: UnlinkParams) {
234
+ const connector = await getInAppWalletConnector(args.client, args.ecosystem);
235
+ return await connector.unlinkProfile(args.profileToUnlink);
236
+ }
237
+
207
238
  /**
208
239
  * Gets the linked profiles for the connected in-app or ecosystem wallet.
209
240
  *
@@ -11,6 +11,7 @@ import { customJwt } from "../../core/authentication/jwt.js";
11
11
  import {
12
12
  getLinkedProfilesInternal,
13
13
  linkAccount,
14
+ unlinkAccount,
14
15
  } from "../../core/authentication/linkAccount.js";
15
16
  import {
16
17
  loginWithPasskey,
@@ -25,6 +26,7 @@ import type {
25
26
  LogoutReturnType,
26
27
  MultiStepAuthArgsType,
27
28
  MultiStepAuthProviderType,
29
+ Profile,
28
30
  SingleStepAuthArgsType,
29
31
  } from "../../core/authentication/types.js";
30
32
  import type { InAppConnector } from "../../core/interfaces/connector.js";
@@ -456,6 +458,15 @@ export class InAppWebConnector implements InAppConnector {
456
458
  });
457
459
  }
458
460
 
461
+ async unlinkProfile(profile: Profile) {
462
+ return await unlinkAccount({
463
+ client: this.client,
464
+ storage: this.storage,
465
+ ecosystem: this.ecosystem,
466
+ profileToUnlink: profile,
467
+ });
468
+ }
469
+
459
470
  async getProfiles() {
460
471
  return getLinkedProfilesInternal({
461
472
  client: this.client,