thirdweb 5.82.1-nightly-5e2eec3b178bcad0988ba7086e31514a3fb7b5d5-20250108000440 → 5.83.1-nightly-bfc477833422995187a92d905dc564219b629974-20250109000324

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 (74) hide show
  1. package/dist/cjs/chains/utils.js +3 -1
  2. package/dist/cjs/chains/utils.js.map +1 -1
  3. package/dist/cjs/version.js +1 -1
  4. package/dist/cjs/wallets/in-app/core/authentication/backend.js +31 -0
  5. package/dist/cjs/wallets/in-app/core/authentication/backend.js.map +1 -0
  6. package/dist/cjs/wallets/in-app/core/wallet/in-app-core.js +5 -1
  7. package/dist/cjs/wallets/in-app/core/wallet/in-app-core.js.map +1 -1
  8. package/dist/cjs/wallets/in-app/native/auth/index.js +11 -0
  9. package/dist/cjs/wallets/in-app/native/auth/index.js.map +1 -1
  10. package/dist/cjs/wallets/in-app/native/native-connector.js +13 -0
  11. package/dist/cjs/wallets/in-app/native/native-connector.js.map +1 -1
  12. package/dist/cjs/wallets/in-app/web/in-app.js +14 -0
  13. package/dist/cjs/wallets/in-app/web/in-app.js.map +1 -1
  14. package/dist/cjs/wallets/in-app/web/lib/auth/index.js +11 -0
  15. package/dist/cjs/wallets/in-app/web/lib/auth/index.js.map +1 -1
  16. package/dist/cjs/wallets/in-app/web/lib/web-connector.js +9 -0
  17. package/dist/cjs/wallets/in-app/web/lib/web-connector.js.map +1 -1
  18. package/dist/cjs/wallets/types.js +1 -0
  19. package/dist/cjs/wallets/types.js.map +1 -1
  20. package/dist/esm/chains/utils.js +3 -1
  21. package/dist/esm/chains/utils.js.map +1 -1
  22. package/dist/esm/version.js +1 -1
  23. package/dist/esm/wallets/in-app/core/authentication/backend.js +28 -0
  24. package/dist/esm/wallets/in-app/core/authentication/backend.js.map +1 -0
  25. package/dist/esm/wallets/in-app/core/wallet/in-app-core.js +5 -1
  26. package/dist/esm/wallets/in-app/core/wallet/in-app-core.js.map +1 -1
  27. package/dist/esm/wallets/in-app/native/auth/index.js +11 -0
  28. package/dist/esm/wallets/in-app/native/auth/index.js.map +1 -1
  29. package/dist/esm/wallets/in-app/native/native-connector.js +13 -0
  30. package/dist/esm/wallets/in-app/native/native-connector.js.map +1 -1
  31. package/dist/esm/wallets/in-app/web/in-app.js +14 -0
  32. package/dist/esm/wallets/in-app/web/in-app.js.map +1 -1
  33. package/dist/esm/wallets/in-app/web/lib/auth/index.js +11 -0
  34. package/dist/esm/wallets/in-app/web/lib/auth/index.js.map +1 -1
  35. package/dist/esm/wallets/in-app/web/lib/web-connector.js +9 -0
  36. package/dist/esm/wallets/in-app/web/lib/web-connector.js.map +1 -1
  37. package/dist/esm/wallets/types.js +1 -0
  38. package/dist/esm/wallets/types.js.map +1 -1
  39. package/dist/types/chains/utils.d.ts.map +1 -1
  40. package/dist/types/react/core/utils/storage.d.ts +1 -1
  41. package/dist/types/react/core/utils/storage.d.ts.map +1 -1
  42. package/dist/types/react/web/utils/storage.d.ts +1 -1
  43. package/dist/types/react/web/utils/storage.d.ts.map +1 -1
  44. package/dist/types/version.d.ts +1 -1
  45. package/dist/types/wallets/in-app/core/authentication/backend.d.ts +13 -0
  46. package/dist/types/wallets/in-app/core/authentication/backend.d.ts.map +1 -0
  47. package/dist/types/wallets/in-app/core/authentication/types.d.ts +4 -2
  48. package/dist/types/wallets/in-app/core/authentication/types.d.ts.map +1 -1
  49. package/dist/types/wallets/in-app/core/wallet/in-app-core.d.ts.map +1 -1
  50. package/dist/types/wallets/in-app/native/auth/index.d.ts +11 -0
  51. package/dist/types/wallets/in-app/native/auth/index.d.ts.map +1 -1
  52. package/dist/types/wallets/in-app/native/native-connector.d.ts.map +1 -1
  53. package/dist/types/wallets/in-app/web/in-app.d.ts +14 -0
  54. package/dist/types/wallets/in-app/web/in-app.d.ts.map +1 -1
  55. package/dist/types/wallets/in-app/web/lib/auth/index.d.ts +11 -0
  56. package/dist/types/wallets/in-app/web/lib/auth/index.d.ts.map +1 -1
  57. package/dist/types/wallets/in-app/web/lib/web-connector.d.ts.map +1 -1
  58. package/dist/types/wallets/types.d.ts +1 -1
  59. package/dist/types/wallets/types.d.ts.map +1 -1
  60. package/package.json +2 -2
  61. package/src/chains/utils.test.ts +72 -0
  62. package/src/chains/utils.ts +3 -1
  63. package/src/version.ts +1 -1
  64. package/src/wallets/in-app/core/authentication/backend.test.ts +69 -0
  65. package/src/wallets/in-app/core/authentication/backend.ts +36 -0
  66. package/src/wallets/in-app/core/authentication/types.ts +5 -1
  67. package/src/wallets/in-app/core/wallet/in-app-core.ts +5 -1
  68. package/src/wallets/in-app/native/auth/index.ts +11 -0
  69. package/src/wallets/in-app/native/native-connector.ts +13 -0
  70. package/src/wallets/in-app/web/in-app.ts +14 -0
  71. package/src/wallets/in-app/web/lib/auth/index.ts +11 -0
  72. package/src/wallets/in-app/web/lib/web-connector.test.ts +163 -0
  73. package/src/wallets/in-app/web/lib/web-connector.ts +9 -0
  74. package/src/wallets/types.ts +1 -0
@@ -0,0 +1,69 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { TEST_CLIENT } from "~test/test-clients.js";
3
+ import { getClientFetch } from "../../../../utils/fetch.js";
4
+ import { stringify } from "../../../../utils/json.js";
5
+ import { backendAuthenticate } from "./backend.js";
6
+ import { getLoginUrl } from "./getLoginPath.js";
7
+
8
+ // Mock dependencies
9
+ vi.mock("../../../../utils/fetch.js");
10
+ vi.mock("./getLoginPath.js");
11
+
12
+ describe("backendAuthenticate", () => {
13
+ it("should successfully authenticate and return token", async () => {
14
+ // Mock response data
15
+ const mockResponse = {
16
+ token: "mock-token",
17
+ cookieString: "mock-cookie",
18
+ };
19
+
20
+ // Mock fetch implementation
21
+ const mockFetch = vi.fn().mockResolvedValue({
22
+ ok: true,
23
+ json: () => Promise.resolve(mockResponse),
24
+ });
25
+
26
+ // Mock dependencies
27
+ vi.mocked(getClientFetch).mockReturnValue(mockFetch);
28
+ vi.mocked(getLoginUrl).mockReturnValue("/auth/login");
29
+
30
+ const result = await backendAuthenticate({
31
+ client: TEST_CLIENT,
32
+ walletSecret: "test-secret",
33
+ });
34
+
35
+ // Verify the fetch call
36
+ expect(mockFetch).toHaveBeenCalledWith("/auth/login", {
37
+ method: "POST",
38
+ headers: {
39
+ "Content-Type": "application/json",
40
+ },
41
+ body: stringify({ walletSecret: "test-secret" }),
42
+ });
43
+
44
+ // Verify response
45
+ expect(result).toEqual(mockResponse);
46
+ });
47
+
48
+ it("should throw error when authentication fails", async () => {
49
+ // Mock failed fetch response
50
+ const mockFetch = vi.fn().mockResolvedValue({
51
+ ok: false,
52
+ });
53
+
54
+ // Mock dependencies
55
+ vi.mocked(getClientFetch).mockReturnValue(mockFetch);
56
+ vi.mocked(getLoginUrl).mockReturnValue("/auth/login");
57
+
58
+ // Test inputs
59
+ const args = {
60
+ client: TEST_CLIENT,
61
+ walletSecret: "test-secret",
62
+ };
63
+
64
+ // Verify error is thrown
65
+ await expect(backendAuthenticate(args)).rejects.toThrow(
66
+ "Failed to generate backend account",
67
+ );
68
+ });
69
+ });
@@ -0,0 +1,36 @@
1
+ import type { ThirdwebClient } from "../../../../client/client.js";
2
+ import { getClientFetch } from "../../../../utils/fetch.js";
3
+ import { stringify } from "../../../../utils/json.js";
4
+ import type { Ecosystem } from "../wallet/types.js";
5
+ import { getLoginUrl } from "./getLoginPath.js";
6
+ import type { AuthStoredTokenWithCookieReturnType } from "./types.js";
7
+
8
+ /**
9
+ * Authenticates via the wallet secret
10
+ * @internal
11
+ */
12
+ export async function backendAuthenticate(args: {
13
+ client: ThirdwebClient;
14
+ walletSecret: string;
15
+ ecosystem?: Ecosystem;
16
+ }): Promise<AuthStoredTokenWithCookieReturnType> {
17
+ const clientFetch = getClientFetch(args.client, args.ecosystem);
18
+ const path = getLoginUrl({
19
+ authOption: "backend",
20
+ client: args.client,
21
+ ecosystem: args.ecosystem,
22
+ });
23
+ const res = await clientFetch(`${path}`, {
24
+ method: "POST",
25
+ headers: {
26
+ "Content-Type": "application/json",
27
+ },
28
+ body: stringify({
29
+ walletSecret: args.walletSecret,
30
+ }),
31
+ });
32
+
33
+ if (!res.ok) throw new Error("Failed to generate backend account");
34
+
35
+ return (await res.json()) satisfies AuthStoredTokenWithCookieReturnType;
36
+ }
@@ -74,7 +74,10 @@ export type SingleStepAuthArgsType =
74
74
  }
75
75
  | {
76
76
  strategy: "guest";
77
- client: ThirdwebClient;
77
+ }
78
+ | {
79
+ strategy: "backend";
80
+ walletSecret: string;
78
81
  };
79
82
 
80
83
  export type AuthArgsType = (MultiStepAuthArgsType | SingleStepAuthArgsType) & {
@@ -89,6 +92,7 @@ type RecoveryShareManagement = "USER_MANAGED" | "AWS_MANAGED" | "ENCLAVE";
89
92
  export type AuthProvider =
90
93
  | "Cognito"
91
94
  | "Guest"
95
+ | "Backend"
92
96
  | "Google"
93
97
  | "EmailOtp"
94
98
  | "CustomJWT"
@@ -26,7 +26,11 @@ export async function getOrCreateInAppWalletConnector(
26
26
  connectorFactory: (client: ThirdwebClient) => Promise<InAppConnector>,
27
27
  ecosystem?: Ecosystem,
28
28
  ) {
29
- const key = stringify({ clientId: client.clientId, ecosystem });
29
+ const key = stringify({
30
+ clientId: client.clientId,
31
+ ecosystem,
32
+ partialSecretKey: client.secretKey?.slice(0, 5),
33
+ });
30
34
  if (connectorCache.has(key)) {
31
35
  return connectorCache.get(key) as InAppConnector;
32
36
  }
@@ -133,6 +133,17 @@ export async function preAuthenticate(args: PreAuthArgsType) {
133
133
  * verificationCode: "123456",
134
134
  * });
135
135
  * ```
136
+ *
137
+ * Authenticate to a backend account (only do this on your backend):
138
+ * ```ts
139
+ * import { authenticate } from "thirdweb/wallets/in-app";
140
+ *
141
+ * const result = await authenticate({
142
+ * client,
143
+ * strategy: "backend",
144
+ * walletSecret: "...", // Provided by your app
145
+ * });
146
+ * ```
136
147
  * @wallet
137
148
  */
138
149
  export async function authenticate(args: AuthArgsType) {
@@ -4,6 +4,7 @@ import { nativeLocalStorage } from "../../../utils/storage/nativeStorage.js";
4
4
  import type { Account } from "../../interfaces/wallet.js";
5
5
  import { getUserStatus } from "../core/actions/get-enclave-user-status.js";
6
6
  import { authEndpoint } from "../core/authentication/authEndpoint.js";
7
+ import { backendAuthenticate } from "../core/authentication/backend.js";
7
8
  import { ClientScopedStorage } from "../core/authentication/client-scoped-storage.js";
8
9
  import { guestAuthenticate } from "../core/authentication/guest.js";
9
10
  import { customJwt } from "../core/authentication/jwt.js";
@@ -171,6 +172,13 @@ export class InAppNativeConnector implements InAppConnector {
171
172
  storage: nativeLocalStorage,
172
173
  });
173
174
  }
175
+ case "backend": {
176
+ return backendAuthenticate({
177
+ client: this.client,
178
+ walletSecret: params.walletSecret,
179
+ ecosystem: params.ecosystem,
180
+ });
181
+ }
174
182
  case "wallet": {
175
183
  return siweAuthenticate({
176
184
  client: this.client,
@@ -179,6 +187,11 @@ export class InAppNativeConnector implements InAppConnector {
179
187
  ecosystem: params.ecosystem,
180
188
  });
181
189
  }
190
+ case "github":
191
+ case "twitch":
192
+ case "steam":
193
+ case "farcaster":
194
+ case "telegram":
182
195
  case "google":
183
196
  case "facebook":
184
197
  case "discord":
@@ -139,6 +139,20 @@ import { createInAppWallet } from "../core/wallet/in-app-core.js";
139
139
  * });
140
140
  * ```
141
141
  *
142
+ * ### Connect to a backend account
143
+ *
144
+ * ```ts
145
+ * import { inAppWallet } from "thirdweb/wallets";
146
+ *
147
+ * const wallet = inAppWallet();
148
+ *
149
+ * const account = await wallet.connect({
150
+ * client,
151
+ * strategy: "backend",
152
+ * walletSecret: "...", // Provided by your app
153
+ * });
154
+ * ```
155
+ *
142
156
  * ### Connect with custom JWT (any OIDC provider)
143
157
  *
144
158
  * You can use any OIDC provider to authenticate your users. Make sure to configure it in your dashboard under in-app wallet settings.
@@ -140,6 +140,17 @@ export async function preAuthenticate(args: PreAuthArgsType) {
140
140
  * verificationCode: "123456",
141
141
  * });
142
142
  * ```
143
+ *
144
+ * Authenticate to a backend account (only do this on your backend):
145
+ * ```ts
146
+ * import { authenticate } from "thirdweb/wallets/in-app";
147
+ *
148
+ * const result = await authenticate({
149
+ * client,
150
+ * strategy: "backend",
151
+ * walletSecret: "...", // Provided by your app
152
+ * });
153
+ * ```
143
154
  * @wallet
144
155
  */
145
156
  export async function authenticate(args: AuthArgsType) {
@@ -0,0 +1,163 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { TEST_CLIENT } from "~test/test-clients.js";
3
+ import { TEST_ACCOUNT_A } from "~test/test-wallets.js";
4
+ import { createWalletAdapter } from "../../../../adapters/wallet-adapter.js";
5
+ import { ethereum } from "../../../../chains/chain-definitions/ethereum.js";
6
+ import { backendAuthenticate } from "../../core/authentication/backend.js";
7
+ import { guestAuthenticate } from "../../core/authentication/guest.js";
8
+ import { siweAuthenticate } from "../../core/authentication/siwe.js";
9
+ import { loginWithOauth } from "./auth/oauth.js";
10
+ import { verifyOtp } from "./auth/otp.js";
11
+ import { InAppWebConnector } from "./web-connector.js";
12
+
13
+ vi.mock("./auth/oauth");
14
+ vi.mock("./auth/iframe-auth.ts", () => {
15
+ const Auth = vi.fn();
16
+ Auth.prototype.loginWithAuthToken = vi.fn(() => {
17
+ return Promise.resolve({
18
+ user: {
19
+ authDetails: {
20
+ recoveryShareManagement: "ENCLAVE",
21
+ userWalletId: "123",
22
+ },
23
+ status: "Logged In, Wallet Initialized",
24
+ walletAddress: "0x123",
25
+ },
26
+ });
27
+ });
28
+ return { Auth };
29
+ });
30
+ vi.mock("../../core/authentication/siwe");
31
+ vi.mock("../../core/authentication/guest");
32
+ vi.mock("../../core/authentication/backend");
33
+ vi.mock("./auth/otp");
34
+ vi.mock("../../core/authentication/authEndpoint");
35
+ vi.mock("../../core/authentication/jwt");
36
+ vi.mock("../../web/utils/iFrameCommunication/InAppWalletIframeCommunicator");
37
+
38
+ describe("InAppWebConnector.connect", () => {
39
+ const mockAuthToken = {
40
+ storedToken: {
41
+ authDetails: {
42
+ userWalletId: "123",
43
+ recoveryShareManagement: "ENCLAVE" as const,
44
+ },
45
+ authProvider: "EmailOtp" as const,
46
+ cookieString: "mock-cookie",
47
+ developerClientId: TEST_CLIENT.clientId,
48
+ isNewUser: false,
49
+ jwtToken: "mock-jwt-token",
50
+ shouldStoreCookieString: true,
51
+ },
52
+ };
53
+
54
+ const connector = new InAppWebConnector({
55
+ client: TEST_CLIENT,
56
+ });
57
+ const mockWallet = createWalletAdapter({
58
+ adaptedAccount: TEST_ACCOUNT_A,
59
+ client: TEST_CLIENT,
60
+ chain: ethereum,
61
+ onDisconnect: () => {},
62
+ switchChain: () => {},
63
+ });
64
+ const mockAccount = mockWallet.getAccount();
65
+ if (!mockAccount) {
66
+ throw new Error("mockAccount is undefined");
67
+ }
68
+
69
+ it("should handle email authentication", async () => {
70
+ vi.mocked(verifyOtp).mockResolvedValueOnce(mockAuthToken);
71
+
72
+ const result = await connector.connect({
73
+ strategy: "email",
74
+ email: "test@example.com",
75
+ verificationCode: "123456",
76
+ });
77
+
78
+ expect(verifyOtp).toHaveBeenCalledWith({
79
+ strategy: "email",
80
+ email: "test@example.com",
81
+ verificationCode: "123456",
82
+ client: TEST_CLIENT,
83
+ ecosystem: undefined,
84
+ });
85
+
86
+ expect(result).toBeDefined();
87
+ });
88
+
89
+ it("should handle wallet authentication", async () => {
90
+ vi.mocked(siweAuthenticate).mockResolvedValueOnce(mockAuthToken);
91
+
92
+ const mockWallet = createWalletAdapter({
93
+ adaptedAccount: TEST_ACCOUNT_A,
94
+ client: TEST_CLIENT,
95
+ chain: ethereum,
96
+ onDisconnect: () => {},
97
+ switchChain: () => {},
98
+ });
99
+
100
+ await connector.connect({
101
+ strategy: "wallet",
102
+ chain: ethereum,
103
+ wallet: mockWallet,
104
+ });
105
+
106
+ expect(siweAuthenticate).toHaveBeenCalledWith({
107
+ wallet: mockWallet,
108
+ chain: ethereum,
109
+ client: TEST_CLIENT,
110
+ ecosystem: undefined,
111
+ });
112
+ });
113
+
114
+ it("should handle guest authentication", async () => {
115
+ vi.mocked(guestAuthenticate).mockResolvedValueOnce(mockAuthToken);
116
+
117
+ await connector.connect({
118
+ strategy: "guest",
119
+ });
120
+
121
+ expect(guestAuthenticate).toHaveBeenCalled();
122
+ });
123
+
124
+ it("should handle backend authentication", async () => {
125
+ vi.mocked(backendAuthenticate).mockResolvedValueOnce(mockAuthToken);
126
+
127
+ await connector.connect({
128
+ strategy: "backend",
129
+ walletSecret: "secret123",
130
+ });
131
+
132
+ expect(backendAuthenticate).toHaveBeenCalledWith({
133
+ walletSecret: "secret123",
134
+ client: TEST_CLIENT,
135
+ ecosystem: undefined,
136
+ });
137
+ });
138
+
139
+ it("should handle oauth authentication", async () => {
140
+ vi.mocked(loginWithOauth).mockResolvedValueOnce(mockAuthToken);
141
+
142
+ await connector.connect({
143
+ strategy: "google",
144
+ });
145
+
146
+ expect(loginWithOauth).toHaveBeenCalledWith({
147
+ authOption: "google",
148
+ client: TEST_CLIENT,
149
+ ecosystem: undefined,
150
+ closeOpenedWindow: undefined,
151
+ openedWindow: undefined,
152
+ });
153
+ });
154
+
155
+ it("should throw error for invalid strategy", async () => {
156
+ await expect(
157
+ connector.connect({
158
+ // @ts-expect-error invalid strategy
159
+ strategy: "invalid",
160
+ }),
161
+ ).rejects.toThrow("Invalid param: invalid");
162
+ });
163
+ });
@@ -5,6 +5,7 @@ import type { SocialAuthOption } from "../../../../wallets/types.js";
5
5
  import type { Account } from "../../../interfaces/wallet.js";
6
6
  import { getUserStatus } from "../../core/actions/get-enclave-user-status.js";
7
7
  import { authEndpoint } from "../../core/authentication/authEndpoint.js";
8
+ import { backendAuthenticate } from "../../core/authentication/backend.js";
8
9
  import { ClientScopedStorage } from "../../core/authentication/client-scoped-storage.js";
9
10
  import { guestAuthenticate } from "../../core/authentication/guest.js";
10
11
  import { customJwt } from "../../core/authentication/jwt.js";
@@ -351,6 +352,13 @@ export class InAppWebConnector implements InAppConnector {
351
352
  storage: webLocalStorage,
352
353
  });
353
354
  }
355
+ case "backend": {
356
+ return backendAuthenticate({
357
+ client: this.client,
358
+ walletSecret: args.walletSecret,
359
+ ecosystem: this.ecosystem,
360
+ });
361
+ }
354
362
  case "wallet": {
355
363
  return siweAuthenticate({
356
364
  ecosystem: this.ecosystem,
@@ -387,6 +395,7 @@ export class InAppWebConnector implements InAppConnector {
387
395
  const authToken = await this.passkeyAuth(args);
388
396
  return this.loginWithAuthToken(authToken);
389
397
  }
398
+ case "backend":
390
399
  case "phone":
391
400
  case "email":
392
401
  case "wallet":
@@ -39,6 +39,7 @@ export type OAuthOption = SocialAuthOption | "guest";
39
39
  export const authOptions = [
40
40
  ...socialAuthOptions,
41
41
  "guest",
42
+ "backend",
42
43
  "email",
43
44
  "phone",
44
45
  "passkey",