thirdweb 5.57.3 → 5.58.0-nightly-3229e1f03c3cbb62ddc8dccf22ad8a8feb0a95f0-20240920000335

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 (161) hide show
  1. package/dist/cjs/exports/extensions/erc1155.js +3 -2
  2. package/dist/cjs/exports/extensions/erc1155.js.map +1 -1
  3. package/dist/cjs/react/core/utils/walletIcon.js +5 -1
  4. package/dist/cjs/react/core/utils/walletIcon.js.map +1 -1
  5. package/dist/cjs/react/native/ui/connect/InAppWalletUI.js +1 -0
  6. package/dist/cjs/react/native/ui/connect/InAppWalletUI.js.map +1 -1
  7. package/dist/cjs/react/native/ui/icons/svgs.js +12 -1
  8. package/dist/cjs/react/native/ui/icons/svgs.js.map +1 -1
  9. package/dist/cjs/react/web/wallets/shared/ConnectWalletSocialOptions.js +1 -0
  10. package/dist/cjs/react/web/wallets/shared/ConnectWalletSocialOptions.js.map +1 -1
  11. package/dist/cjs/react/web/wallets/shared/oauthSignIn.js +2 -1
  12. package/dist/cjs/react/web/wallets/shared/oauthSignIn.js.map +1 -1
  13. package/dist/cjs/utils/fetch.js +10 -4
  14. package/dist/cjs/utils/fetch.js.map +1 -1
  15. package/dist/cjs/version.js +1 -1
  16. package/dist/cjs/version.js.map +1 -1
  17. package/dist/cjs/wallets/in-app/core/authentication/types.js +2 -0
  18. package/dist/cjs/wallets/in-app/core/authentication/types.js.map +1 -1
  19. package/dist/cjs/wallets/in-app/native/native-connector.js +1 -0
  20. package/dist/cjs/wallets/in-app/native/native-connector.js.map +1 -1
  21. package/dist/cjs/wallets/in-app/web/in-app.js +1 -0
  22. package/dist/cjs/wallets/in-app/web/in-app.js.map +1 -1
  23. package/dist/cjs/wallets/in-app/web/lib/actions/generate-wallet.enclave.js +26 -0
  24. package/dist/cjs/wallets/in-app/web/lib/actions/generate-wallet.enclave.js.map +1 -0
  25. package/dist/cjs/wallets/in-app/web/lib/actions/get-enclave-user-status.js +31 -0
  26. package/dist/cjs/wallets/in-app/web/lib/actions/get-enclave-user-status.js.map +1 -0
  27. package/dist/cjs/wallets/in-app/web/lib/actions/sign-message.enclave.js +30 -0
  28. package/dist/cjs/wallets/in-app/web/lib/actions/sign-message.enclave.js.map +1 -0
  29. package/dist/cjs/wallets/in-app/web/lib/actions/sign-transaction.enclave.js +28 -0
  30. package/dist/cjs/wallets/in-app/web/lib/actions/sign-transaction.enclave.js.map +1 -0
  31. package/dist/cjs/wallets/in-app/web/lib/actions/sign-typed-data.enclave.js +27 -0
  32. package/dist/cjs/wallets/in-app/web/lib/actions/sign-typed-data.enclave.js.map +1 -0
  33. package/dist/cjs/wallets/in-app/web/lib/auth/iframe-auth.js +42 -5
  34. package/dist/cjs/wallets/in-app/web/lib/auth/iframe-auth.js.map +1 -1
  35. package/dist/cjs/wallets/in-app/web/lib/enclave-wallet.js +195 -0
  36. package/dist/cjs/wallets/in-app/web/lib/enclave-wallet.js.map +1 -0
  37. package/dist/cjs/wallets/in-app/web/lib/get-auth-token.js +14 -0
  38. package/dist/cjs/wallets/in-app/web/lib/get-auth-token.js.map +1 -0
  39. package/dist/cjs/wallets/in-app/web/lib/{in-app-account.js → iframe-wallet.js} +8 -5
  40. package/dist/cjs/wallets/in-app/web/lib/iframe-wallet.js.map +1 -0
  41. package/dist/cjs/wallets/in-app/web/lib/web-connector.js +98 -37
  42. package/dist/cjs/wallets/in-app/web/lib/web-connector.js.map +1 -1
  43. package/dist/cjs/wallets/in-app/web/lib/web-wallet.js +3 -0
  44. package/dist/cjs/wallets/in-app/web/lib/web-wallet.js.map +1 -0
  45. package/dist/cjs/wallets/types.js +1 -0
  46. package/dist/cjs/wallets/types.js.map +1 -1
  47. package/dist/esm/exports/extensions/erc1155.js +1 -1
  48. package/dist/esm/exports/extensions/erc1155.js.map +1 -1
  49. package/dist/esm/react/core/utils/walletIcon.js +4 -0
  50. package/dist/esm/react/core/utils/walletIcon.js.map +1 -1
  51. package/dist/esm/react/native/ui/connect/InAppWalletUI.js +2 -1
  52. package/dist/esm/react/native/ui/connect/InAppWalletUI.js.map +1 -1
  53. package/dist/esm/react/native/ui/icons/svgs.js +11 -0
  54. package/dist/esm/react/native/ui/icons/svgs.js.map +1 -1
  55. package/dist/esm/react/web/wallets/shared/ConnectWalletSocialOptions.js +1 -0
  56. package/dist/esm/react/web/wallets/shared/ConnectWalletSocialOptions.js.map +1 -1
  57. package/dist/esm/react/web/wallets/shared/oauthSignIn.js +2 -1
  58. package/dist/esm/react/web/wallets/shared/oauthSignIn.js.map +1 -1
  59. package/dist/esm/utils/fetch.js +10 -4
  60. package/dist/esm/utils/fetch.js.map +1 -1
  61. package/dist/esm/version.js +1 -1
  62. package/dist/esm/version.js.map +1 -1
  63. package/dist/esm/wallets/in-app/core/authentication/types.js +2 -0
  64. package/dist/esm/wallets/in-app/core/authentication/types.js.map +1 -1
  65. package/dist/esm/wallets/in-app/native/native-connector.js +1 -0
  66. package/dist/esm/wallets/in-app/native/native-connector.js.map +1 -1
  67. package/dist/esm/wallets/in-app/web/in-app.js +1 -0
  68. package/dist/esm/wallets/in-app/web/in-app.js.map +1 -1
  69. package/dist/esm/wallets/in-app/web/lib/actions/generate-wallet.enclave.js +23 -0
  70. package/dist/esm/wallets/in-app/web/lib/actions/generate-wallet.enclave.js.map +1 -0
  71. package/dist/esm/wallets/in-app/web/lib/actions/get-enclave-user-status.js +28 -0
  72. package/dist/esm/wallets/in-app/web/lib/actions/get-enclave-user-status.js.map +1 -0
  73. package/dist/esm/wallets/in-app/web/lib/actions/sign-message.enclave.js +27 -0
  74. package/dist/esm/wallets/in-app/web/lib/actions/sign-message.enclave.js.map +1 -0
  75. package/dist/esm/wallets/in-app/web/lib/actions/sign-transaction.enclave.js +25 -0
  76. package/dist/esm/wallets/in-app/web/lib/actions/sign-transaction.enclave.js.map +1 -0
  77. package/dist/esm/wallets/in-app/web/lib/actions/sign-typed-data.enclave.js +24 -0
  78. package/dist/esm/wallets/in-app/web/lib/actions/sign-typed-data.enclave.js.map +1 -0
  79. package/dist/esm/wallets/in-app/web/lib/auth/iframe-auth.js +42 -5
  80. package/dist/esm/wallets/in-app/web/lib/auth/iframe-auth.js.map +1 -1
  81. package/dist/esm/wallets/in-app/web/lib/enclave-wallet.js +191 -0
  82. package/dist/esm/wallets/in-app/web/lib/enclave-wallet.js.map +1 -0
  83. package/dist/esm/wallets/in-app/web/lib/get-auth-token.js +11 -0
  84. package/dist/esm/wallets/in-app/web/lib/get-auth-token.js.map +1 -0
  85. package/dist/esm/wallets/in-app/web/lib/{in-app-account.js → iframe-wallet.js} +8 -5
  86. package/dist/esm/wallets/in-app/web/lib/iframe-wallet.js.map +1 -0
  87. package/dist/esm/wallets/in-app/web/lib/web-connector.js +98 -37
  88. package/dist/esm/wallets/in-app/web/lib/web-connector.js.map +1 -1
  89. package/dist/esm/wallets/in-app/web/lib/web-wallet.js +2 -0
  90. package/dist/esm/wallets/in-app/web/lib/web-wallet.js.map +1 -0
  91. package/dist/esm/wallets/types.js +1 -0
  92. package/dist/esm/wallets/types.js.map +1 -1
  93. package/dist/types/exports/extensions/erc1155.d.ts +1 -1
  94. package/dist/types/exports/extensions/erc1155.d.ts.map +1 -1
  95. package/dist/types/react/core/utils/walletIcon.d.ts +3 -1
  96. package/dist/types/react/core/utils/walletIcon.d.ts.map +1 -1
  97. package/dist/types/react/native/ui/connect/InAppWalletUI.d.ts.map +1 -1
  98. package/dist/types/react/native/ui/icons/svgs.d.ts +1 -0
  99. package/dist/types/react/native/ui/icons/svgs.d.ts.map +1 -1
  100. package/dist/types/react/web/wallets/shared/ConnectWalletSocialOptions.d.ts.map +1 -1
  101. package/dist/types/react/web/wallets/shared/oauthSignIn.d.ts.map +1 -1
  102. package/dist/types/utils/fetch.d.ts.map +1 -1
  103. package/dist/types/version.d.ts +1 -1
  104. package/dist/types/version.d.ts.map +1 -1
  105. package/dist/types/wallets/in-app/core/authentication/types.d.ts +5 -2
  106. package/dist/types/wallets/in-app/core/authentication/types.d.ts.map +1 -1
  107. package/dist/types/wallets/in-app/native/native-connector.d.ts.map +1 -1
  108. package/dist/types/wallets/in-app/web/in-app.d.ts +1 -0
  109. package/dist/types/wallets/in-app/web/in-app.d.ts.map +1 -1
  110. package/dist/types/wallets/in-app/web/lib/actions/generate-wallet.enclave.d.ts +15 -0
  111. package/dist/types/wallets/in-app/web/lib/actions/generate-wallet.enclave.d.ts.map +1 -0
  112. package/dist/types/wallets/in-app/web/lib/actions/get-enclave-user-status.d.ts +14 -0
  113. package/dist/types/wallets/in-app/web/lib/actions/get-enclave-user-status.d.ts.map +1 -0
  114. package/dist/types/wallets/in-app/web/lib/actions/sign-message.enclave.d.ts +17 -0
  115. package/dist/types/wallets/in-app/web/lib/actions/sign-message.enclave.d.ts.map +1 -0
  116. package/dist/types/wallets/in-app/web/lib/actions/sign-transaction.enclave.d.ts +9 -0
  117. package/dist/types/wallets/in-app/web/lib/actions/sign-transaction.enclave.d.ts.map +1 -0
  118. package/dist/types/wallets/in-app/web/lib/actions/sign-typed-data.enclave.d.ts +16 -0
  119. package/dist/types/wallets/in-app/web/lib/actions/sign-typed-data.enclave.d.ts.map +1 -0
  120. package/dist/types/wallets/in-app/web/lib/auth/iframe-auth.d.ts +2 -1
  121. package/dist/types/wallets/in-app/web/lib/auth/iframe-auth.d.ts.map +1 -1
  122. package/dist/types/wallets/in-app/web/lib/enclave-wallet.d.ts +61 -0
  123. package/dist/types/wallets/in-app/web/lib/enclave-wallet.d.ts.map +1 -0
  124. package/dist/types/wallets/in-app/web/lib/get-auth-token.d.ts +4 -0
  125. package/dist/types/wallets/in-app/web/lib/get-auth-token.d.ts.map +1 -0
  126. package/dist/types/wallets/in-app/web/lib/{in-app-account.d.ts → iframe-wallet.d.ts} +5 -8
  127. package/dist/types/wallets/in-app/web/lib/iframe-wallet.d.ts.map +1 -0
  128. package/dist/types/wallets/in-app/web/lib/web-connector.d.ts +4 -2
  129. package/dist/types/wallets/in-app/web/lib/web-connector.d.ts.map +1 -1
  130. package/dist/types/wallets/in-app/web/lib/web-wallet.d.ts +15 -0
  131. package/dist/types/wallets/in-app/web/lib/web-wallet.d.ts.map +1 -0
  132. package/dist/types/wallets/types.d.ts +2 -2
  133. package/dist/types/wallets/types.d.ts.map +1 -1
  134. package/package.json +1 -1
  135. package/src/exports/extensions/erc1155.ts +1 -0
  136. package/src/extensions/prebuilts/deploy-published.test.ts +34 -1
  137. package/src/react/core/utils/walletIcon.ts +5 -0
  138. package/src/react/native/ui/connect/InAppWalletUI.tsx +2 -0
  139. package/src/react/native/ui/icons/svgs.ts +12 -0
  140. package/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx +1 -0
  141. package/src/react/web/wallets/shared/oauthSignIn.ts +2 -1
  142. package/src/utils/fetch.ts +11 -4
  143. package/src/version.ts +1 -1
  144. package/src/wallets/in-app/core/authentication/types.ts +5 -1
  145. package/src/wallets/in-app/native/native-connector.ts +1 -0
  146. package/src/wallets/in-app/web/in-app.ts +1 -0
  147. package/src/wallets/in-app/web/lib/actions/generate-wallet.enclave.ts +44 -0
  148. package/src/wallets/in-app/web/lib/actions/get-enclave-user-status.ts +44 -0
  149. package/src/wallets/in-app/web/lib/actions/sign-message.enclave.ts +52 -0
  150. package/src/wallets/in-app/web/lib/actions/sign-transaction.enclave.ts +48 -0
  151. package/src/wallets/in-app/web/lib/actions/sign-typed-data.enclave.ts +51 -0
  152. package/src/wallets/in-app/web/lib/auth/iframe-auth.ts +42 -6
  153. package/src/wallets/in-app/web/lib/enclave-wallet.ts +244 -0
  154. package/src/wallets/in-app/web/lib/get-auth-token.ts +17 -0
  155. package/src/wallets/in-app/web/lib/{in-app-account.ts → iframe-wallet.ts} +14 -15
  156. package/src/wallets/in-app/web/lib/web-connector.ts +107 -39
  157. package/src/wallets/in-app/web/lib/web-wallet.ts +23 -0
  158. package/src/wallets/types.ts +1 -0
  159. package/dist/cjs/wallets/in-app/web/lib/in-app-account.js.map +0 -1
  160. package/dist/esm/wallets/in-app/web/lib/in-app-account.js.map +0 -1
  161. package/dist/types/wallets/in-app/web/lib/in-app-account.d.ts.map +0 -1
@@ -41,10 +41,11 @@ function getOauthLoginPath(
41
41
  case "line":
42
42
  case "x":
43
43
  case "guest":
44
+ case "coinbase":
44
45
  case "discord":
45
46
  return getLoginUrl({ authOption, client, ecosystem });
46
47
  default:
47
- return "";
48
+ throw new Error(`Unsupported auth option: ${authOption}`);
48
49
  }
49
50
  }
50
51
 
@@ -32,19 +32,26 @@ export function getClientFetch(client: ThirdwebClient, ecosystem?: Ecosystem) {
32
32
  if (!headers) {
33
33
  headers = new Headers();
34
34
  }
35
+ // auth token if secret key === jwt
35
36
  const authToken =
36
37
  client.secretKey && isJWT(client.secretKey)
37
38
  ? client.secretKey
38
39
  : undefined;
40
+ // secret key if secret key !== jwt
41
+ const secretKey =
42
+ client.secretKey && !isJWT(client.secretKey)
43
+ ? client.secretKey
44
+ : undefined;
45
+ const clientId = client.clientId;
39
46
 
40
47
  // if we have an auth token set, use that (thirdweb.com/dashboard sets this for the user)
41
48
  // pay urls should never send the auth token, because we always want the "developer" to be the one making the request, not the "end user"
42
49
  if (authToken && !isPayUrl(url)) {
43
50
  headers.set("authorization", `Bearer ${authToken}`);
44
- } else if (client.secretKey) {
45
- headers.set("x-secret-key", client.secretKey);
46
- } else if (client.clientId) {
47
- headers.set("x-client-id", client.clientId);
51
+ } else if (secretKey) {
52
+ headers.set("x-secret-key", secretKey);
53
+ } else if (clientId) {
54
+ headers.set("x-client-id", clientId);
48
55
  }
49
56
 
50
57
  if (ecosystem) {
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "5.57.3";
1
+ export const version = "5.58.0-nightly-3229e1f03c3cbb62ddc8dccf22ad8a8feb0a95f0-20240920000335";
@@ -67,6 +67,7 @@ export type AuthArgsType = (MultiStepAuthArgsType | SingleStepAuthArgsType) & {
67
67
  export enum RecoveryShareManagement {
68
68
  USER_MANAGED = "USER_MANAGED",
69
69
  CLOUD_MANAGED = "AWS_MANAGED",
70
+ ENCLAVE = "ENCLAVE",
70
71
  }
71
72
 
72
73
  // TODO: remove usage of enums, instead use object with as const
@@ -81,6 +82,7 @@ export enum AuthProvider {
81
82
  APPLE = "Apple",
82
83
  PASSKEY = "Passkey",
83
84
  DISCORD = "Discord",
85
+ COINBASE = "Coinbase",
84
86
  X = "X",
85
87
  LINE = "Line",
86
88
  FARCASTER = "Farcaster",
@@ -133,7 +135,8 @@ export type AuthStoredTokenWithCookieReturnType = {
133
135
  };
134
136
  };
135
137
  export type AuthAndWalletRpcReturnType = AuthStoredTokenWithCookieReturnType & {
136
- walletDetails: SetUpWalletRpcReturnType;
138
+ // Will just be WalletAddressObjectType for enclave wallets
139
+ walletDetails: SetUpWalletRpcReturnType | WalletAddressObjectType;
137
140
  };
138
141
 
139
142
  export type AuthLoginReturnType = { user: InitializedUser };
@@ -151,6 +154,7 @@ export type AuthDetails = (
151
154
  encryptionKey?: string;
152
155
  backupRecoveryCodes?: string[];
153
156
  recoveryShareManagement: RecoveryShareManagement;
157
+ walletType?: "sharded" | "enclave";
154
158
  };
155
159
 
156
160
  export type InitializedUser = {
@@ -158,6 +158,7 @@ export class InAppNativeConnector implements InAppConnector {
158
158
  case "x":
159
159
  case "farcaster":
160
160
  case "telegram":
161
+ case "coinbase":
161
162
  case "apple": {
162
163
  const ExpoLinking = require("expo-linking");
163
164
  const redirectUrl =
@@ -15,6 +15,7 @@ import { createInAppWallet } from "../core/wallet/in-app-core.js";
15
15
  * - Apple
16
16
  * - Facebook
17
17
  * - Discord
18
+ * - Coinbase
18
19
  * - Telegram
19
20
  * - LINE
20
21
  * - X
@@ -0,0 +1,44 @@
1
+ import type { ThirdwebClient } from "../../../../../client/client.js";
2
+ import { getThirdwebBaseUrl } from "../../../../../utils/domains.js";
3
+ import { getClientFetch } from "../../../../../utils/fetch.js";
4
+ import type { Ecosystem } from "../../types.js";
5
+
6
+ /**
7
+ * Generate a new enclave wallet using an auth token
8
+ * @internal
9
+ */
10
+ export async function generateWallet({
11
+ authToken,
12
+ client,
13
+ ecosystem,
14
+ }: {
15
+ client: ThirdwebClient;
16
+ ecosystem: Ecosystem;
17
+ authToken: string;
18
+ }) {
19
+ const clientFetch = getClientFetch(client, ecosystem);
20
+ const response = await clientFetch(
21
+ `${getThirdwebBaseUrl("inAppWallet")}/api/v1/enclave-wallet/generate`,
22
+ {
23
+ method: "POST",
24
+ headers: {
25
+ "Content-Type": "application/json",
26
+ "x-thirdweb-client-id": client.clientId,
27
+ Authorization: `Bearer embedded-wallet-token:${authToken}`,
28
+ },
29
+ },
30
+ );
31
+
32
+ if (!response.ok) {
33
+ throw new Error("Failed to generate wallet");
34
+ }
35
+
36
+ const { wallet } = (await response.json()) as {
37
+ wallet: {
38
+ address: string;
39
+ type: "enclave";
40
+ };
41
+ };
42
+
43
+ return wallet;
44
+ }
@@ -0,0 +1,44 @@
1
+ import type { ThirdwebClient } from "../../../../../client/client.js";
2
+ import { getThirdwebBaseUrl } from "../../../../../utils/domains.js";
3
+ import { getClientFetch } from "../../../../../utils/fetch.js";
4
+ import type { UserStatus } from "../../lib/enclave-wallet.js";
5
+ import type { Ecosystem } from "../../types.js";
6
+
7
+ /**
8
+ * Gets the user's status from the backend.
9
+ *
10
+ * @internal
11
+ */
12
+ export async function getEnclaveUserStatus({
13
+ authToken,
14
+ client,
15
+ ecosystem,
16
+ }: {
17
+ authToken: string;
18
+ client: ThirdwebClient;
19
+ ecosystem?: Ecosystem;
20
+ }): Promise<UserStatus | undefined> {
21
+ const clientFetch = getClientFetch(client, ecosystem);
22
+ const response = await clientFetch(
23
+ `${getThirdwebBaseUrl("inAppWallet")}/api/2024-05-05/accounts`,
24
+ {
25
+ method: "GET",
26
+ headers: {
27
+ "Content-Type": "application/json",
28
+ "x-thirdweb-client-id": client.clientId,
29
+ Authorization: `Bearer embedded-wallet-token:${authToken}`,
30
+ },
31
+ },
32
+ );
33
+
34
+ if (!response.ok) {
35
+ if (response.status === 401) {
36
+ // 401 response indicates there is no user logged in, so we return undefined
37
+ return undefined;
38
+ }
39
+ const result = await response.json();
40
+ throw new Error(`Failed to get user status: ${result.error}`);
41
+ }
42
+
43
+ return (await response.json()) as UserStatus;
44
+ }
@@ -0,0 +1,52 @@
1
+ import type { ThirdwebClient } from "../../../../../client/client.js";
2
+ import { getThirdwebBaseUrl } from "../../../../../utils/domains.js";
3
+ import { getClientFetch } from "../../../../../utils/fetch.js";
4
+ import type { Ecosystem } from "../../types.js";
5
+ import { getAuthToken } from "../get-auth-token.js";
6
+
7
+ export async function signMessage({
8
+ client,
9
+ ecosystem,
10
+ payload: { message, isRaw },
11
+ }: {
12
+ client: ThirdwebClient;
13
+ ecosystem?: Ecosystem;
14
+ payload: {
15
+ message: string;
16
+ isRaw: boolean;
17
+ };
18
+ }) {
19
+ const clientFetch = getClientFetch(client, ecosystem);
20
+ const authToken = await getAuthToken(client, ecosystem);
21
+
22
+ const response = await clientFetch(
23
+ `${getThirdwebBaseUrl("inAppWallet")}/api/v1/enclave-wallet/sign-message`,
24
+ {
25
+ method: "POST",
26
+ headers: {
27
+ "Content-Type": "application/json",
28
+ "x-thirdweb-client-id": client.clientId,
29
+ Authorization: `Bearer embedded-wallet-token:${authToken}`,
30
+ },
31
+ body: JSON.stringify({
32
+ messagePayload: {
33
+ message,
34
+ isRaw,
35
+ },
36
+ }),
37
+ },
38
+ );
39
+
40
+ if (!response.ok) {
41
+ throw new Error("Failed to sign message");
42
+ }
43
+
44
+ const signedMessage = (await response.json()) as {
45
+ r: string;
46
+ s: string;
47
+ v: number;
48
+ signature: string;
49
+ hash: string;
50
+ };
51
+ return signedMessage;
52
+ }
@@ -0,0 +1,48 @@
1
+ import type { ThirdwebClient } from "../../../../../client/client.js";
2
+ import { getThirdwebBaseUrl } from "../../../../../utils/domains.js";
3
+ import type { Hex } from "../../../../../utils/encoding/hex.js";
4
+ import { getClientFetch } from "../../../../../utils/fetch.js";
5
+ import type { Ecosystem } from "../../types.js";
6
+ import { getAuthToken } from "../get-auth-token.js";
7
+
8
+ export async function signTransaction({
9
+ client,
10
+ ecosystem,
11
+ payload,
12
+ }: {
13
+ client: ThirdwebClient;
14
+ ecosystem?: Ecosystem;
15
+ payload: Record<string, Hex | number | undefined>;
16
+ }) {
17
+ console.log("payload", payload);
18
+ const clientFetch = getClientFetch(client, ecosystem);
19
+ const authToken = await getAuthToken(client, ecosystem);
20
+
21
+ const response = await clientFetch(
22
+ `${getThirdwebBaseUrl("inAppWallet")}/api/v1/enclave-wallet/sign-transaction`,
23
+ {
24
+ method: "POST",
25
+ headers: {
26
+ "Content-Type": "application/json",
27
+ "x-thirdweb-client-id": client.clientId,
28
+ Authorization: `Bearer embedded-wallet-token:${authToken}`,
29
+ },
30
+ body: JSON.stringify({
31
+ transactionPayload: payload,
32
+ }),
33
+ },
34
+ );
35
+
36
+ if (!response.ok) {
37
+ throw new Error("Failed to sign transaction");
38
+ }
39
+
40
+ const signedTransaction = (await response.json()) as {
41
+ r: string;
42
+ s: string;
43
+ v: number;
44
+ signature: string;
45
+ hash: string;
46
+ };
47
+ return signedTransaction.signature as Hex;
48
+ }
@@ -0,0 +1,51 @@
1
+ import type { TypedData } from "abitype";
2
+ import type { TypedDataDefinition } from "viem";
3
+ import type { ThirdwebClient } from "../../../../../client/client.js";
4
+ import { getThirdwebBaseUrl } from "../../../../../utils/domains.js";
5
+ import { getClientFetch } from "../../../../../utils/fetch.js";
6
+ import type { Ecosystem } from "../../types.js";
7
+ import { getAuthToken } from "../get-auth-token.js";
8
+
9
+ export async function signTypedData<
10
+ const typedData extends TypedData | Record<string, unknown>,
11
+ primaryType extends keyof typedData | "EIP712Domain" = keyof typedData,
12
+ >({
13
+ client,
14
+ ecosystem,
15
+ payload,
16
+ }: {
17
+ client: ThirdwebClient;
18
+ ecosystem?: Ecosystem;
19
+ payload: TypedDataDefinition<typedData, primaryType>;
20
+ }) {
21
+ const clientFetch = getClientFetch(client, ecosystem);
22
+ const authToken = await getAuthToken(client, ecosystem);
23
+
24
+ const response = await clientFetch(
25
+ `${getThirdwebBaseUrl("inAppWallet")}/api/v1/enclave-wallet/sign-typed-data`,
26
+ {
27
+ method: "POST",
28
+ headers: {
29
+ "Content-Type": "application/json",
30
+ "x-thirdweb-client-id": client.clientId,
31
+ Authorization: `Bearer embedded-wallet-token:${authToken}`,
32
+ },
33
+ body: JSON.stringify({
34
+ ...payload,
35
+ }),
36
+ },
37
+ );
38
+
39
+ if (!response.ok) {
40
+ throw new Error("Failed to sign typed data");
41
+ }
42
+
43
+ const signedTypedData = (await response.json()) as {
44
+ r: string;
45
+ s: string;
46
+ v: number;
47
+ signature: string;
48
+ hash: string;
49
+ };
50
+ return signedTypedData;
51
+ }
@@ -10,6 +10,8 @@ import type {
10
10
  } from "../../../core/authentication/types.js";
11
11
  import type { ClientIdWithQuerierType, Ecosystem } from "../../types.js";
12
12
  import type { InAppWalletIframeCommunicator } from "../../utils/iFrameCommunication/InAppWalletIframeCommunicator.js";
13
+ import { generateWallet } from "../actions/generate-wallet.enclave.js";
14
+ import { getEnclaveUserStatus } from "../actions/get-enclave-user-status.js";
13
15
  import { BaseLogin } from "./base-login.js";
14
16
 
15
17
  export type AuthQuerierTypes = {
@@ -20,7 +22,7 @@ export type AuthQuerierTypes = {
20
22
  clientId: string;
21
23
  authCookie: string;
22
24
  walletUserId: string;
23
- deviceShareStored: string;
25
+ deviceShareStored: string | null;
24
26
  };
25
27
  loginWithStoredTokenDetails: {
26
28
  storedToken: AuthStoredTokenWithCookieReturnType["storedToken"];
@@ -33,6 +35,7 @@ export type AuthQuerierTypes = {
33
35
  */
34
36
  export class Auth {
35
37
  protected client: ThirdwebClient;
38
+ protected ecosystem?: Ecosystem;
36
39
  protected AuthQuerier: InAppWalletIframeCommunicator<AuthQuerierTypes>;
37
40
  protected localStorage: ClientScopedStorage;
38
41
  protected onAuthSuccess: (
@@ -58,6 +61,7 @@ export class Auth {
58
61
  ) => Promise<AuthLoginReturnType>;
59
62
  }) {
60
63
  this.client = client;
64
+ this.ecosystem = ecosystem;
61
65
 
62
66
  this.AuthQuerier = querier;
63
67
  this.localStorage = new ClientScopedStorage({
@@ -103,6 +107,42 @@ export class Auth {
103
107
  recoveryCode?: string,
104
108
  ): Promise<AuthLoginReturnType> {
105
109
  await this.preLogin();
110
+
111
+ const user = await getEnclaveUserStatus({
112
+ authToken: authToken.storedToken.cookieString,
113
+ client: this.client,
114
+ ecosystem: this.ecosystem,
115
+ });
116
+ if (!user) {
117
+ throw new Error("Cannot login, no user found for auth token");
118
+ }
119
+
120
+ // If they're already an enclave wallet, proceed to login
121
+ if (user.wallets.length > 0 && user.wallets[0]?.type === "enclave") {
122
+ return this.postLogin({
123
+ storedToken: authToken.storedToken,
124
+ walletDetails: {
125
+ walletAddress: user.wallets[0].address,
126
+ },
127
+ });
128
+ }
129
+
130
+ if (user.wallets.length === 0 && this.ecosystem) {
131
+ // If this is a new ecosystem wallet without an enclave yet, we'll generate an enclave
132
+ const result = await generateWallet({
133
+ authToken: authToken.storedToken.cookieString,
134
+ client: this.client,
135
+ ecosystem: this.ecosystem,
136
+ });
137
+ return this.postLogin({
138
+ storedToken: authToken.storedToken,
139
+ walletDetails: {
140
+ walletAddress: result.address,
141
+ },
142
+ });
143
+ }
144
+
145
+ // If this is an existing sharded wallet or in-app wallet, we'll login with the sharded wallet
106
146
  const result = await this.AuthQuerier.call<AuthAndWalletRpcReturnType>({
107
147
  procedureName: "loginWithStoredTokenDetails",
108
148
  params: {
@@ -280,15 +320,11 @@ export class Auth {
280
320
  * @internal
281
321
  */
282
322
  async logout(): Promise<LogoutReturnType> {
283
- const { success } = await this.AuthQuerier.call<LogoutReturnType>({
284
- procedureName: "logout",
285
- params: undefined,
286
- });
287
323
  const isRemoveAuthCookie = await this.localStorage.removeAuthCookie();
288
324
  const isRemoveUserId = await this.localStorage.removeWalletUserId();
289
325
 
290
326
  return {
291
- success: success || isRemoveAuthCookie || isRemoveUserId,
327
+ success: isRemoveAuthCookie || isRemoveUserId,
292
328
  };
293
329
  }
294
330
  }
@@ -0,0 +1,244 @@
1
+ import { bytesToHex } from "viem";
2
+ import { getCachedChain } from "../../../../chains/utils.js";
3
+ import type { ThirdwebClient } from "../../../../client/client.js";
4
+ import { eth_sendRawTransaction } from "../../../../rpc/actions/eth_sendRawTransaction.js";
5
+ import { getRpcClient } from "../../../../rpc/rpc.js";
6
+ import { getAddress } from "../../../../utils/address.js";
7
+ import { type Hex, toHex } from "../../../../utils/encoding/hex.js";
8
+ import { parseTypedData } from "../../../../utils/signatures/helpers/parseTypedData.js";
9
+ import { webLocalStorage } from "../../../../utils/storage/webStorage.js";
10
+ import type { Prettify } from "../../../../utils/type-utils.js";
11
+ import type {
12
+ Account,
13
+ SendTransactionOption,
14
+ } from "../../../interfaces/wallet.js";
15
+ import { ClientScopedStorage } from "../../core/authentication/client-scoped-storage.js";
16
+ import {
17
+ type GetUser,
18
+ RecoveryShareManagement,
19
+ UserWalletStatus,
20
+ type WalletAddressObjectType,
21
+ } from "../../core/authentication/types.js";
22
+ import type { Ecosystem } from "../types.js";
23
+ import { getEnclaveUserStatus } from "./actions/get-enclave-user-status.js";
24
+ import { signMessage as signEnclaveMessage } from "./actions/sign-message.enclave.js";
25
+ import { signTransaction as signEnclaveTransaction } from "./actions/sign-transaction.enclave.js";
26
+ import { signTypedData as signEnclaveTypedData } from "./actions/sign-typed-data.enclave.js";
27
+ import type { IWebWallet, PostWalletSetup } from "./web-wallet.js";
28
+
29
+ export type UserStatus = {
30
+ linkedAccounts: {
31
+ type: string;
32
+ details:
33
+ | { email: string; [key: string]: string }
34
+ | { phone: string; [key: string]: string }
35
+ | { address: string; [key: string]: string }
36
+ | { id: string; [key: string]: string };
37
+ }[];
38
+ wallets:
39
+ | [
40
+ {
41
+ address: string;
42
+ createdAt: string;
43
+ type: "sharded" | "enclave";
44
+ },
45
+ ]
46
+ | [];
47
+ id: string;
48
+ };
49
+
50
+ export class EnclaveWallet implements IWebWallet {
51
+ public client: ThirdwebClient;
52
+ public ecosystem?: Ecosystem;
53
+ public address: string;
54
+ protected localStorage: ClientScopedStorage;
55
+
56
+ constructor({
57
+ client,
58
+ ecosystem,
59
+ address,
60
+ }: Prettify<{
61
+ client: ThirdwebClient;
62
+ ecosystem?: Ecosystem;
63
+ address: string;
64
+ }>) {
65
+ this.client = client;
66
+ this.ecosystem = ecosystem;
67
+ this.address = address;
68
+
69
+ this.localStorage = new ClientScopedStorage({
70
+ storage: webLocalStorage,
71
+ clientId: client.clientId,
72
+ ecosystemId: ecosystem?.id,
73
+ });
74
+ }
75
+
76
+ /**
77
+ * Store the auth token for use
78
+ * @returns `{walletAddress: string }` The user's wallet details
79
+ * @internal
80
+ */
81
+ async postWalletSetUp({
82
+ walletAddress,
83
+ authToken,
84
+ }: PostWalletSetup): Promise<WalletAddressObjectType> {
85
+ await this.localStorage.saveAuthCookie(authToken);
86
+ return { walletAddress };
87
+ }
88
+
89
+ /**
90
+ * Gets the current user's details
91
+ * @internal
92
+ */
93
+ async getUserWalletStatus(): Promise<GetUser> {
94
+ const token = await this.localStorage.getAuthCookie();
95
+ if (!token) {
96
+ return { status: UserWalletStatus.LOGGED_OUT };
97
+ }
98
+
99
+ const userStatus = await getEnclaveUserStatus({
100
+ authToken: token,
101
+ client: this.client,
102
+ ecosystem: this.ecosystem,
103
+ });
104
+ if (!userStatus) {
105
+ return { status: UserWalletStatus.LOGGED_OUT };
106
+ }
107
+ const wallet = userStatus.wallets[0];
108
+
109
+ const authDetails = {
110
+ email: userStatus.linkedAccounts.find(
111
+ (account) => account.type === "email",
112
+ )?.details.email,
113
+ phoneNumber: userStatus.linkedAccounts.find(
114
+ (account) => account.type === "phone",
115
+ )?.details.phone,
116
+ userWalletId: userStatus.id || "",
117
+ recoveryShareManagement: RecoveryShareManagement.ENCLAVE,
118
+ };
119
+
120
+ if (!wallet) {
121
+ return {
122
+ status: UserWalletStatus.LOGGED_IN_WALLET_UNINITIALIZED,
123
+ authDetails,
124
+ };
125
+ }
126
+
127
+ return {
128
+ status: UserWalletStatus.LOGGED_IN_WALLET_INITIALIZED,
129
+ walletAddress: wallet.address,
130
+ authDetails,
131
+ account: await this.getAccount(),
132
+ };
133
+ }
134
+
135
+ /**
136
+ * Returns an account to perform wallet operations
137
+ * @internal
138
+ */
139
+ async getAccount(): Promise<Account> {
140
+ const client = this.client;
141
+ const ecosystem = this.ecosystem;
142
+
143
+ const _signTransaction = async (tx: SendTransactionOption) => {
144
+ const rpcRequest = getRpcClient({
145
+ client,
146
+ chain: getCachedChain(tx.chainId),
147
+ });
148
+ const transaction: Record<string, Hex | number | undefined> = {
149
+ to: (tx.to as Hex) ?? undefined,
150
+ data: tx.data ? toHex(tx.data) : undefined,
151
+ value: tx.value ? toHex(tx.value) : undefined,
152
+ gas: tx.gas ? toHex(tx.gas + tx.gas / BigInt(10)) : undefined, // Add a 10% buffer to gas
153
+ nonce: tx.nonce
154
+ ? toHex(tx.nonce)
155
+ : toHex(
156
+ await import(
157
+ "../../../../rpc/actions/eth_getTransactionCount.js"
158
+ ).then(({ eth_getTransactionCount }) =>
159
+ eth_getTransactionCount(rpcRequest, {
160
+ address: this.address,
161
+ blockTag: "pending",
162
+ }),
163
+ ),
164
+ ),
165
+ chainId: toHex(tx.chainId),
166
+ };
167
+
168
+ if (tx.maxFeePerGas) {
169
+ transaction.maxFeePerGas = toHex(tx.maxFeePerGas);
170
+ transaction.maxPriorityFeePerGas = tx.maxPriorityFeePerGas
171
+ ? toHex(tx.maxPriorityFeePerGas)
172
+ : undefined;
173
+ transaction.type = 2;
174
+ } else {
175
+ transaction.gasPrice = tx.gasPrice ? toHex(tx.gasPrice) : undefined;
176
+ transaction.type = 0;
177
+ }
178
+
179
+ return signEnclaveTransaction({
180
+ client,
181
+ ecosystem,
182
+ payload: transaction,
183
+ });
184
+ };
185
+ return {
186
+ address: getAddress(this.address),
187
+ async signTransaction(tx) {
188
+ if (!tx.chainId) {
189
+ throw new Error("chainId required in tx to sign");
190
+ }
191
+
192
+ return _signTransaction({
193
+ chainId: tx.chainId,
194
+ ...tx,
195
+ });
196
+ },
197
+ async sendTransaction(tx) {
198
+ const rpcRequest = getRpcClient({
199
+ client,
200
+ chain: getCachedChain(tx.chainId),
201
+ });
202
+ const signedTx = await _signTransaction(tx);
203
+ const transactionHash = await eth_sendRawTransaction(
204
+ rpcRequest,
205
+ signedTx,
206
+ );
207
+ return {
208
+ transactionHash,
209
+ };
210
+ },
211
+ async signMessage({ message }) {
212
+ const messagePayload = (() => {
213
+ if (typeof message === "string") {
214
+ return { message, isRaw: false };
215
+ }
216
+ return {
217
+ message:
218
+ typeof message.raw === "string"
219
+ ? message.raw
220
+ : bytesToHex(message.raw),
221
+ isRaw: true,
222
+ };
223
+ })();
224
+
225
+ const { signature } = await signEnclaveMessage({
226
+ client,
227
+ ecosystem,
228
+ payload: messagePayload,
229
+ });
230
+ return signature as Hex;
231
+ },
232
+ async signTypedData(_typedData) {
233
+ const parsedTypedData = parseTypedData(_typedData);
234
+ const { signature } = await signEnclaveTypedData({
235
+ client,
236
+ ecosystem,
237
+ payload: parsedTypedData,
238
+ });
239
+
240
+ return signature as Hex;
241
+ },
242
+ };
243
+ }
244
+ }