Skip to content

Commit 976e61c

Browse files
feat: auto-migrate in-app wallets to enclave system
1 parent 519349b commit 976e61c

File tree

9 files changed

+105
-80
lines changed

9 files changed

+105
-80
lines changed

.changeset/empty-needles-reply.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
Automatically migrate in-app wallets to the new enclave system

packages/react-native-adapter/package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@
2323
},
2424
"./package.json": "./package.json"
2525
},
26-
"files": [
27-
"dist/*",
28-
"src/*"
29-
],
26+
"files": ["dist/*", "src/*"],
3027
"dependencies": {
3128
"@aws-sdk/client-kms": "3.679.0",
3229
"@aws-sdk/client-lambda": "3.680.0",

packages/thirdweb/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@
326326
"@codspeed/vitest-plugin": "3.1.1",
327327
"@coinbase/wallet-mobile-sdk": "1.1.2",
328328
"@mobile-wallet-protocol/client": "0.1.1",
329-
"@react-native-async-storage/async-storage": "2.0.0",
329+
"@react-native-async-storage/async-storage": "1.24.0",
330330
"@size-limit/preset-big-lib": "11.1.6",
331331
"@storybook/addon-essentials": "8.3.6",
332332
"@storybook/addon-interactions": "8.3.6",

packages/thirdweb/src/react/web/wallets/shared/PassKeyLogin.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ function LoginScreen(props: {
160160
await setLastAuthProvider("passkey", webLocalStorage);
161161
}
162162
done();
163-
} catch {
163+
} catch (e) {
164+
console.error("Failed to login with passkey", e);
164165
setStatus("error");
165166
}
166167
}

packages/thirdweb/src/wallets/in-app/core/actions/generate-wallet.enclave.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ import type { Ecosystem } from "../wallet/types.js";
99
* @internal
1010
*/
1111
export async function generateWallet({
12-
authToken,
1312
client,
1413
ecosystem,
14+
authToken,
1515
}: {
1616
client: ThirdwebClient;
17-
ecosystem: Ecosystem;
1817
authToken: string;
18+
ecosystem?: Ecosystem;
1919
}) {
2020
const clientFetch = getClientFetch(client, ecosystem);
2121
const response = await clientFetch(

packages/thirdweb/src/wallets/in-app/native/native-connector.ts

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -80,27 +80,26 @@ export class InAppNativeConnector implements InAppConnector {
8080
}
8181
let wallet = user.wallets[0];
8282

83-
// TODO (enclaves): Migration to enclave wallet for in-app wallets as well
84-
if (
85-
authResult &&
86-
this.storage.ecosystem &&
87-
wallet &&
88-
wallet.type === "sharded"
89-
) {
90-
const { migrateToEnclaveWallet } = await import(
91-
"./helpers/wallet/migration.js"
92-
);
93-
wallet = await migrateToEnclaveWallet({
94-
client: this.client,
95-
storage: this.storage,
96-
storedToken: authResult.storedToken,
97-
encryptionKey,
98-
});
83+
if (authResult && wallet && wallet.type === "sharded") {
84+
try {
85+
const { migrateToEnclaveWallet } = await import(
86+
"./helpers/wallet/migration.js"
87+
);
88+
wallet = await migrateToEnclaveWallet({
89+
client: this.client,
90+
storage: this.storage,
91+
storedToken: authResult.storedToken,
92+
encryptionKey,
93+
});
94+
} catch {
95+
console.warn(
96+
"Failed to migrate from sharded to enclave wallet, continuing with sharded wallet",
97+
);
98+
}
9999
}
100100

101-
if (authResult && this.ecosystem && !wallet) {
102-
// new ecosystem user, generate enclave wallet
103-
// TODO (enclaves): same flow for in-app wallets
101+
if (authResult && !wallet) {
102+
// new user, generate enclave wallet
104103
const { generateWallet } = await import(
105104
"../core/actions/generate-wallet.enclave.js"
106105
);

packages/thirdweb/src/wallets/in-app/web/lib/auth/iframe-auth.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ export class Auth {
128128
});
129129
}
130130

131-
if (user.wallets.length === 0 && this.ecosystem) {
131+
if (user.wallets.length === 0) {
132132
// If this is a new ecosystem wallet without an enclave yet, we'll generate an enclave
133133
const result = await generateWallet({
134134
authToken: authToken.storedToken.cookieString,

packages/thirdweb/src/wallets/in-app/web/lib/web-connector.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,7 @@ export class InAppWebConnector implements InAppConnector {
9999
onAuthSuccess: async (authResult) => {
100100
onAuthSuccess?.(authResult);
101101

102-
if (
103-
this.ecosystem &&
104-
authResult.storedToken.authDetails.walletType === "sharded"
105-
) {
102+
if (authResult.storedToken.authDetails.walletType === "sharded") {
106103
// If this is an existing sharded ecosystem wallet, we'll need to migrate
107104
const result = await this.querier.call<boolean>({
108105
procedureName: "migrateFromShardToEnclave",
@@ -111,11 +108,15 @@ export class InAppWebConnector implements InAppConnector {
111108
},
112109
});
113110
if (!result) {
114-
throw new Error("Failed to migrate from sharded to enclave wallet");
111+
console.warn(
112+
"Failed to migrate from sharded to enclave wallet, continuing with sharded wallet",
113+
);
115114
}
116115
}
117116

118-
await this.initializeWallet(authResult.storedToken.cookieString);
117+
this.wallet = await this.initializeWallet(
118+
authResult.storedToken.cookieString,
119+
);
119120

120121
if (!this.wallet) {
121122
throw new Error("Failed to initialize wallet");
@@ -131,7 +132,7 @@ export class InAppWebConnector implements InAppConnector {
131132
deviceShareStored,
132133
});
133134

134-
if (authResult.storedToken.authDetails.walletType !== "enclave") {
135+
if (this.wallet instanceof IFrameWallet) {
135136
await this.querier.call({
136137
procedureName: "initIframe",
137138
params: {
@@ -161,7 +162,7 @@ export class InAppWebConnector implements InAppConnector {
161162
});
162163
}
163164

164-
async initializeWallet(authToken?: string) {
165+
async initializeWallet(authToken?: string): Promise<IWebWallet> {
165166
const storedAuthToken = await this.storage.getAuthCookie();
166167
if (!authToken && storedAuthToken === null) {
167168
throw new Error(
@@ -174,6 +175,7 @@ export class InAppWebConnector implements InAppConnector {
174175
client: this.client,
175176
ecosystem: this.ecosystem,
176177
});
178+
177179
if (!user) {
178180
throw new Error("Cannot initialize wallet, no user logged in");
179181
}
@@ -184,16 +186,15 @@ export class InAppWebConnector implements InAppConnector {
184186
}
185187

186188
if (user.wallets[0]?.type === "enclave") {
187-
this.wallet = new EnclaveWallet({
189+
return new EnclaveWallet({
188190
client: this.client,
189191
ecosystem: this.ecosystem,
190192
address: user.wallets[0].address,
191193
storage: this.storage,
192194
});
193-
return;
194195
}
195196

196-
this.wallet = new IFrameWallet({
197+
return new IFrameWallet({
197198
client: this.client,
198199
ecosystem: this.ecosystem,
199200
querier: this.querier,
@@ -231,7 +232,7 @@ export class InAppWebConnector implements InAppConnector {
231232
if (!localAuthToken) {
232233
return { status: "Logged Out" };
233234
}
234-
await this.initializeWallet(localAuthToken);
235+
this.wallet = await this.initializeWallet(localAuthToken);
235236
}
236237
if (!this.wallet) {
237238
throw new Error("Wallet not initialized");

0 commit comments

Comments
 (0)