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.
- package/dist/cjs/exports/extensions/erc1155.js +3 -2
- package/dist/cjs/exports/extensions/erc1155.js.map +1 -1
- package/dist/cjs/react/core/utils/walletIcon.js +5 -1
- package/dist/cjs/react/core/utils/walletIcon.js.map +1 -1
- package/dist/cjs/react/native/ui/connect/InAppWalletUI.js +1 -0
- package/dist/cjs/react/native/ui/connect/InAppWalletUI.js.map +1 -1
- package/dist/cjs/react/native/ui/icons/svgs.js +12 -1
- package/dist/cjs/react/native/ui/icons/svgs.js.map +1 -1
- package/dist/cjs/react/web/wallets/shared/ConnectWalletSocialOptions.js +1 -0
- package/dist/cjs/react/web/wallets/shared/ConnectWalletSocialOptions.js.map +1 -1
- package/dist/cjs/react/web/wallets/shared/oauthSignIn.js +2 -1
- package/dist/cjs/react/web/wallets/shared/oauthSignIn.js.map +1 -1
- package/dist/cjs/utils/fetch.js +10 -4
- package/dist/cjs/utils/fetch.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/version.js.map +1 -1
- package/dist/cjs/wallets/in-app/core/authentication/types.js +2 -0
- package/dist/cjs/wallets/in-app/core/authentication/types.js.map +1 -1
- package/dist/cjs/wallets/in-app/native/native-connector.js +1 -0
- package/dist/cjs/wallets/in-app/native/native-connector.js.map +1 -1
- package/dist/cjs/wallets/in-app/web/in-app.js +1 -0
- package/dist/cjs/wallets/in-app/web/in-app.js.map +1 -1
- package/dist/cjs/wallets/in-app/web/lib/actions/generate-wallet.enclave.js +26 -0
- package/dist/cjs/wallets/in-app/web/lib/actions/generate-wallet.enclave.js.map +1 -0
- package/dist/cjs/wallets/in-app/web/lib/actions/get-enclave-user-status.js +31 -0
- package/dist/cjs/wallets/in-app/web/lib/actions/get-enclave-user-status.js.map +1 -0
- package/dist/cjs/wallets/in-app/web/lib/actions/sign-message.enclave.js +30 -0
- package/dist/cjs/wallets/in-app/web/lib/actions/sign-message.enclave.js.map +1 -0
- package/dist/cjs/wallets/in-app/web/lib/actions/sign-transaction.enclave.js +28 -0
- package/dist/cjs/wallets/in-app/web/lib/actions/sign-transaction.enclave.js.map +1 -0
- package/dist/cjs/wallets/in-app/web/lib/actions/sign-typed-data.enclave.js +27 -0
- package/dist/cjs/wallets/in-app/web/lib/actions/sign-typed-data.enclave.js.map +1 -0
- package/dist/cjs/wallets/in-app/web/lib/auth/iframe-auth.js +42 -5
- package/dist/cjs/wallets/in-app/web/lib/auth/iframe-auth.js.map +1 -1
- package/dist/cjs/wallets/in-app/web/lib/enclave-wallet.js +195 -0
- package/dist/cjs/wallets/in-app/web/lib/enclave-wallet.js.map +1 -0
- package/dist/cjs/wallets/in-app/web/lib/get-auth-token.js +14 -0
- package/dist/cjs/wallets/in-app/web/lib/get-auth-token.js.map +1 -0
- package/dist/cjs/wallets/in-app/web/lib/{in-app-account.js → iframe-wallet.js} +8 -5
- package/dist/cjs/wallets/in-app/web/lib/iframe-wallet.js.map +1 -0
- package/dist/cjs/wallets/in-app/web/lib/web-connector.js +98 -37
- package/dist/cjs/wallets/in-app/web/lib/web-connector.js.map +1 -1
- package/dist/cjs/wallets/in-app/web/lib/web-wallet.js +3 -0
- package/dist/cjs/wallets/in-app/web/lib/web-wallet.js.map +1 -0
- package/dist/cjs/wallets/types.js +1 -0
- package/dist/cjs/wallets/types.js.map +1 -1
- package/dist/esm/exports/extensions/erc1155.js +1 -1
- package/dist/esm/exports/extensions/erc1155.js.map +1 -1
- package/dist/esm/react/core/utils/walletIcon.js +4 -0
- package/dist/esm/react/core/utils/walletIcon.js.map +1 -1
- package/dist/esm/react/native/ui/connect/InAppWalletUI.js +2 -1
- package/dist/esm/react/native/ui/connect/InAppWalletUI.js.map +1 -1
- package/dist/esm/react/native/ui/icons/svgs.js +11 -0
- package/dist/esm/react/native/ui/icons/svgs.js.map +1 -1
- package/dist/esm/react/web/wallets/shared/ConnectWalletSocialOptions.js +1 -0
- package/dist/esm/react/web/wallets/shared/ConnectWalletSocialOptions.js.map +1 -1
- package/dist/esm/react/web/wallets/shared/oauthSignIn.js +2 -1
- package/dist/esm/react/web/wallets/shared/oauthSignIn.js.map +1 -1
- package/dist/esm/utils/fetch.js +10 -4
- package/dist/esm/utils/fetch.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/esm/wallets/in-app/core/authentication/types.js +2 -0
- package/dist/esm/wallets/in-app/core/authentication/types.js.map +1 -1
- package/dist/esm/wallets/in-app/native/native-connector.js +1 -0
- package/dist/esm/wallets/in-app/native/native-connector.js.map +1 -1
- package/dist/esm/wallets/in-app/web/in-app.js +1 -0
- package/dist/esm/wallets/in-app/web/in-app.js.map +1 -1
- package/dist/esm/wallets/in-app/web/lib/actions/generate-wallet.enclave.js +23 -0
- package/dist/esm/wallets/in-app/web/lib/actions/generate-wallet.enclave.js.map +1 -0
- package/dist/esm/wallets/in-app/web/lib/actions/get-enclave-user-status.js +28 -0
- package/dist/esm/wallets/in-app/web/lib/actions/get-enclave-user-status.js.map +1 -0
- package/dist/esm/wallets/in-app/web/lib/actions/sign-message.enclave.js +27 -0
- package/dist/esm/wallets/in-app/web/lib/actions/sign-message.enclave.js.map +1 -0
- package/dist/esm/wallets/in-app/web/lib/actions/sign-transaction.enclave.js +25 -0
- package/dist/esm/wallets/in-app/web/lib/actions/sign-transaction.enclave.js.map +1 -0
- package/dist/esm/wallets/in-app/web/lib/actions/sign-typed-data.enclave.js +24 -0
- package/dist/esm/wallets/in-app/web/lib/actions/sign-typed-data.enclave.js.map +1 -0
- package/dist/esm/wallets/in-app/web/lib/auth/iframe-auth.js +42 -5
- package/dist/esm/wallets/in-app/web/lib/auth/iframe-auth.js.map +1 -1
- package/dist/esm/wallets/in-app/web/lib/enclave-wallet.js +191 -0
- package/dist/esm/wallets/in-app/web/lib/enclave-wallet.js.map +1 -0
- package/dist/esm/wallets/in-app/web/lib/get-auth-token.js +11 -0
- package/dist/esm/wallets/in-app/web/lib/get-auth-token.js.map +1 -0
- package/dist/esm/wallets/in-app/web/lib/{in-app-account.js → iframe-wallet.js} +8 -5
- package/dist/esm/wallets/in-app/web/lib/iframe-wallet.js.map +1 -0
- package/dist/esm/wallets/in-app/web/lib/web-connector.js +98 -37
- package/dist/esm/wallets/in-app/web/lib/web-connector.js.map +1 -1
- package/dist/esm/wallets/in-app/web/lib/web-wallet.js +2 -0
- package/dist/esm/wallets/in-app/web/lib/web-wallet.js.map +1 -0
- package/dist/esm/wallets/types.js +1 -0
- package/dist/esm/wallets/types.js.map +1 -1
- package/dist/types/exports/extensions/erc1155.d.ts +1 -1
- package/dist/types/exports/extensions/erc1155.d.ts.map +1 -1
- package/dist/types/react/core/utils/walletIcon.d.ts +3 -1
- package/dist/types/react/core/utils/walletIcon.d.ts.map +1 -1
- package/dist/types/react/native/ui/connect/InAppWalletUI.d.ts.map +1 -1
- package/dist/types/react/native/ui/icons/svgs.d.ts +1 -0
- package/dist/types/react/native/ui/icons/svgs.d.ts.map +1 -1
- package/dist/types/react/web/wallets/shared/ConnectWalletSocialOptions.d.ts.map +1 -1
- package/dist/types/react/web/wallets/shared/oauthSignIn.d.ts.map +1 -1
- package/dist/types/utils/fetch.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/version.d.ts.map +1 -1
- package/dist/types/wallets/in-app/core/authentication/types.d.ts +5 -2
- package/dist/types/wallets/in-app/core/authentication/types.d.ts.map +1 -1
- package/dist/types/wallets/in-app/native/native-connector.d.ts.map +1 -1
- package/dist/types/wallets/in-app/web/in-app.d.ts +1 -0
- package/dist/types/wallets/in-app/web/in-app.d.ts.map +1 -1
- package/dist/types/wallets/in-app/web/lib/actions/generate-wallet.enclave.d.ts +15 -0
- package/dist/types/wallets/in-app/web/lib/actions/generate-wallet.enclave.d.ts.map +1 -0
- package/dist/types/wallets/in-app/web/lib/actions/get-enclave-user-status.d.ts +14 -0
- package/dist/types/wallets/in-app/web/lib/actions/get-enclave-user-status.d.ts.map +1 -0
- package/dist/types/wallets/in-app/web/lib/actions/sign-message.enclave.d.ts +17 -0
- package/dist/types/wallets/in-app/web/lib/actions/sign-message.enclave.d.ts.map +1 -0
- package/dist/types/wallets/in-app/web/lib/actions/sign-transaction.enclave.d.ts +9 -0
- package/dist/types/wallets/in-app/web/lib/actions/sign-transaction.enclave.d.ts.map +1 -0
- package/dist/types/wallets/in-app/web/lib/actions/sign-typed-data.enclave.d.ts +16 -0
- package/dist/types/wallets/in-app/web/lib/actions/sign-typed-data.enclave.d.ts.map +1 -0
- package/dist/types/wallets/in-app/web/lib/auth/iframe-auth.d.ts +2 -1
- package/dist/types/wallets/in-app/web/lib/auth/iframe-auth.d.ts.map +1 -1
- package/dist/types/wallets/in-app/web/lib/enclave-wallet.d.ts +61 -0
- package/dist/types/wallets/in-app/web/lib/enclave-wallet.d.ts.map +1 -0
- package/dist/types/wallets/in-app/web/lib/get-auth-token.d.ts +4 -0
- package/dist/types/wallets/in-app/web/lib/get-auth-token.d.ts.map +1 -0
- package/dist/types/wallets/in-app/web/lib/{in-app-account.d.ts → iframe-wallet.d.ts} +5 -8
- package/dist/types/wallets/in-app/web/lib/iframe-wallet.d.ts.map +1 -0
- package/dist/types/wallets/in-app/web/lib/web-connector.d.ts +4 -2
- package/dist/types/wallets/in-app/web/lib/web-connector.d.ts.map +1 -1
- package/dist/types/wallets/in-app/web/lib/web-wallet.d.ts +15 -0
- package/dist/types/wallets/in-app/web/lib/web-wallet.d.ts.map +1 -0
- package/dist/types/wallets/types.d.ts +2 -2
- package/dist/types/wallets/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/exports/extensions/erc1155.ts +1 -0
- package/src/extensions/prebuilts/deploy-published.test.ts +34 -1
- package/src/react/core/utils/walletIcon.ts +5 -0
- package/src/react/native/ui/connect/InAppWalletUI.tsx +2 -0
- package/src/react/native/ui/icons/svgs.ts +12 -0
- package/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx +1 -0
- package/src/react/web/wallets/shared/oauthSignIn.ts +2 -1
- package/src/utils/fetch.ts +11 -4
- package/src/version.ts +1 -1
- package/src/wallets/in-app/core/authentication/types.ts +5 -1
- package/src/wallets/in-app/native/native-connector.ts +1 -0
- package/src/wallets/in-app/web/in-app.ts +1 -0
- package/src/wallets/in-app/web/lib/actions/generate-wallet.enclave.ts +44 -0
- package/src/wallets/in-app/web/lib/actions/get-enclave-user-status.ts +44 -0
- package/src/wallets/in-app/web/lib/actions/sign-message.enclave.ts +52 -0
- package/src/wallets/in-app/web/lib/actions/sign-transaction.enclave.ts +48 -0
- package/src/wallets/in-app/web/lib/actions/sign-typed-data.enclave.ts +51 -0
- package/src/wallets/in-app/web/lib/auth/iframe-auth.ts +42 -6
- package/src/wallets/in-app/web/lib/enclave-wallet.ts +244 -0
- package/src/wallets/in-app/web/lib/get-auth-token.ts +17 -0
- package/src/wallets/in-app/web/lib/{in-app-account.ts → iframe-wallet.ts} +14 -15
- package/src/wallets/in-app/web/lib/web-connector.ts +107 -39
- package/src/wallets/in-app/web/lib/web-wallet.ts +23 -0
- package/src/wallets/types.ts +1 -0
- package/dist/cjs/wallets/in-app/web/lib/in-app-account.js.map +0 -1
- package/dist/esm/wallets/in-app/web/lib/in-app-account.js.map +0 -1
- 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
|
-
|
48
|
+
throw new Error(`Unsupported auth option: ${authOption}`);
|
48
49
|
}
|
49
50
|
}
|
50
51
|
|
package/src/utils/fetch.ts
CHANGED
@@ -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 (
|
45
|
-
headers.set("x-secret-key",
|
46
|
-
} else if (
|
47
|
-
headers.set("x-client-id",
|
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.
|
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
|
-
|
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 = {
|
@@ -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:
|
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
|
+
}
|