diff --git a/.changeset/empty-needles-reply.md b/.changeset/empty-needles-reply.md new file mode 100644 index 00000000000..85dbed9f532 --- /dev/null +++ b/.changeset/empty-needles-reply.md @@ -0,0 +1,5 @@ +--- +"thirdweb": patch +--- + +Automatically migrate in-app wallets to the new enclave system diff --git a/packages/thirdweb/src/react/web/wallets/shared/PassKeyLogin.tsx b/packages/thirdweb/src/react/web/wallets/shared/PassKeyLogin.tsx index 4b732d73eec..e39a1b3dcdf 100644 --- a/packages/thirdweb/src/react/web/wallets/shared/PassKeyLogin.tsx +++ b/packages/thirdweb/src/react/web/wallets/shared/PassKeyLogin.tsx @@ -160,7 +160,8 @@ function LoginScreen(props: { await setLastAuthProvider("passkey", webLocalStorage); } done(); - } catch { + } catch (e) { + console.error("Failed to login with passkey", e); setStatus("error"); } } diff --git a/packages/thirdweb/src/wallets/in-app/core/actions/generate-wallet.enclave.ts b/packages/thirdweb/src/wallets/in-app/core/actions/generate-wallet.enclave.ts index 118e70431a7..a136f37763f 100644 --- a/packages/thirdweb/src/wallets/in-app/core/actions/generate-wallet.enclave.ts +++ b/packages/thirdweb/src/wallets/in-app/core/actions/generate-wallet.enclave.ts @@ -9,13 +9,13 @@ import type { Ecosystem } from "../wallet/types.js"; * @internal */ export async function generateWallet({ - authToken, client, ecosystem, + authToken, }: { client: ThirdwebClient; - ecosystem: Ecosystem; authToken: string; + ecosystem?: Ecosystem; }) { const clientFetch = getClientFetch(client, ecosystem); const response = await clientFetch( diff --git a/packages/thirdweb/src/wallets/in-app/native/native-connector.ts b/packages/thirdweb/src/wallets/in-app/native/native-connector.ts index 57db63615cf..c9ba843949c 100644 --- a/packages/thirdweb/src/wallets/in-app/native/native-connector.ts +++ b/packages/thirdweb/src/wallets/in-app/native/native-connector.ts @@ -80,27 +80,26 @@ export class InAppNativeConnector implements InAppConnector { } let wallet = user.wallets[0]; - // TODO (enclaves): Migration to enclave wallet for in-app wallets as well - if ( - authResult && - this.storage.ecosystem && - wallet && - wallet.type === "sharded" - ) { - const { migrateToEnclaveWallet } = await import( - "./helpers/wallet/migration.js" - ); - wallet = await migrateToEnclaveWallet({ - client: this.client, - storage: this.storage, - storedToken: authResult.storedToken, - encryptionKey, - }); + if (authResult && wallet && wallet.type === "sharded") { + try { + const { migrateToEnclaveWallet } = await import( + "./helpers/wallet/migration.js" + ); + wallet = await migrateToEnclaveWallet({ + client: this.client, + storage: this.storage, + storedToken: authResult.storedToken, + encryptionKey, + }); + } catch { + console.warn( + "Failed to migrate from sharded to enclave wallet, continuing with sharded wallet", + ); + } } - if (authResult && this.ecosystem && !wallet) { - // new ecosystem user, generate enclave wallet - // TODO (enclaves): same flow for in-app wallets + if (authResult && !wallet) { + // new user, generate enclave wallet const { generateWallet } = await import( "../core/actions/generate-wallet.enclave.js" ); diff --git a/packages/thirdweb/src/wallets/in-app/web/lib/auth/iframe-auth.ts b/packages/thirdweb/src/wallets/in-app/web/lib/auth/iframe-auth.ts index 8681c562cd4..d7d09c7abc8 100644 --- a/packages/thirdweb/src/wallets/in-app/web/lib/auth/iframe-auth.ts +++ b/packages/thirdweb/src/wallets/in-app/web/lib/auth/iframe-auth.ts @@ -128,7 +128,7 @@ export class Auth { }); } - if (user.wallets.length === 0 && this.ecosystem) { + if (user.wallets.length === 0) { // If this is a new ecosystem wallet without an enclave yet, we'll generate an enclave const result = await generateWallet({ authToken: authToken.storedToken.cookieString, diff --git a/packages/thirdweb/src/wallets/in-app/web/lib/web-connector.ts b/packages/thirdweb/src/wallets/in-app/web/lib/web-connector.ts index 69bc50c88fc..7b6227ea11c 100644 --- a/packages/thirdweb/src/wallets/in-app/web/lib/web-connector.ts +++ b/packages/thirdweb/src/wallets/in-app/web/lib/web-connector.ts @@ -101,10 +101,7 @@ export class InAppWebConnector implements InAppConnector { onAuthSuccess: async (authResult) => { onAuthSuccess?.(authResult); - if ( - this.ecosystem && - authResult.storedToken.authDetails.walletType === "sharded" - ) { + if (authResult.storedToken.authDetails.walletType === "sharded") { // If this is an existing sharded ecosystem wallet, we'll need to migrate const result = await this.querier.call({ procedureName: "migrateFromShardToEnclave", @@ -113,11 +110,15 @@ export class InAppWebConnector implements InAppConnector { }, }); if (!result) { - throw new Error("Failed to migrate from sharded to enclave wallet"); + console.warn( + "Failed to migrate from sharded to enclave wallet, continuing with sharded wallet", + ); } } - await this.initializeWallet(authResult.storedToken.cookieString); + this.wallet = await this.initializeWallet( + authResult.storedToken.cookieString, + ); if (!this.wallet) { throw new Error("Failed to initialize wallet"); @@ -133,7 +134,7 @@ export class InAppWebConnector implements InAppConnector { deviceShareStored, }); - if (authResult.storedToken.authDetails.walletType !== "enclave") { + if (this.wallet instanceof IFrameWallet) { await this.querier.call({ procedureName: "initIframe", params: { @@ -163,7 +164,7 @@ export class InAppWebConnector implements InAppConnector { }); } - async initializeWallet(authToken?: string) { + async initializeWallet(authToken?: string): Promise { const storedAuthToken = await this.storage.getAuthCookie(); if (!authToken && storedAuthToken === null) { throw new Error( @@ -176,6 +177,7 @@ export class InAppWebConnector implements InAppConnector { client: this.client, ecosystem: this.ecosystem, }); + if (!user) { throw new Error("Cannot initialize wallet, no user logged in"); } @@ -186,16 +188,15 @@ export class InAppWebConnector implements InAppConnector { } if (user.wallets[0]?.type === "enclave") { - this.wallet = new EnclaveWallet({ + return new EnclaveWallet({ client: this.client, ecosystem: this.ecosystem, address: user.wallets[0].address, storage: this.storage, }); - return; } - this.wallet = new IFrameWallet({ + return new IFrameWallet({ client: this.client, ecosystem: this.ecosystem, querier: this.querier, @@ -233,7 +234,7 @@ export class InAppWebConnector implements InAppConnector { if (!localAuthToken) { return { status: "Logged Out" }; } - await this.initializeWallet(localAuthToken); + this.wallet = await this.initializeWallet(localAuthToken); } if (!this.wallet) { throw new Error("Wallet not initialized"); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6979b9523eb..85e7b89a8c1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23652,8 +23652,8 @@ snapshots: '@typescript-eslint/parser': 7.14.1(eslint@8.57.0)(typescript@5.6.3) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.0) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.0) eslint-plugin-react: 7.37.1(eslint@8.57.0) eslint-plugin-react-hooks: 5.0.0(eslint@8.57.0) @@ -23672,19 +23672,19 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.0): + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint@8.57.0))(eslint@8.57.0): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.3.7(supports-color@8.1.1) enhanced-resolve: 5.17.1 eslint: 8.57.0 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 is-glob: 4.0.3 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-node @@ -23712,18 +23712,18 @@ snapshots: - bluebird - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.0))(eslint@8.57.0): + eslint-module-utils@2.12.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 7.14.1(eslint@8.57.0)(typescript@5.6.3) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint@8.57.0))(eslint@8.57.0) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -23734,7 +23734,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.6.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3