Skip to content

Commit 9cfed46

Browse files
committed
wallet only mode
1 parent 74512bb commit 9cfed46

File tree

2 files changed

+38
-10
lines changed

2 files changed

+38
-10
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ yalc.lock
2121
package-lock.json
2222

2323
docs/
24+
.cursor-docs/
2425

2526

2627

pkg/wallet/src/provider.ts

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* EIP-1193 compatible provider for Immutable zkEVM
33
*/
44

5-
import type { User, Auth } from '@imtbl/auth';
5+
import { type User, Auth } from '@imtbl/auth';
66
import {
77
toHex, fromHex, createPublicClient, http, isAddress, hexToString,
88
} from 'viem';
@@ -287,6 +287,20 @@ export class PassportEVMProvider implements Provider {
287287
});
288288
}
289289

290+
/**
291+
* Creates a shared auth client for wallet-only mode
292+
* Used when apps don't provide their own OAuth client
293+
* @internal
294+
*/
295+
// eslint-disable-next-line class-methods-use-this
296+
private createSharedAuthClient(): Auth {
297+
return new Auth({
298+
clientId: 'immutable-passport-wallet-only', // Shared OAuth client ID for wallet-only mode
299+
redirectUri: 'https://passport.immutable.com/wallet-callback', // This callback page is hosted by Passport and handles OAuth redirects
300+
scope: 'openid transact', // Wallet-only scope, no profile/email access
301+
});
302+
}
303+
290304
/**
291305
* Sets signer (internal use only)
292306
* @internal
@@ -380,29 +394,42 @@ export class PassportEVMProvider implements Provider {
380394

381395
/**
382396
* Ensures user is authenticated, triggers login automatically if auth client provided
397+
* If no auth client is provided, creates a shared auth client for wallet-only mode
383398
*/
384399
private async ensureAuthenticated(): Promise<void> {
385400
if (this.authenticatedUser) {
386401
return;
387402
}
388403

389-
if (this.auth) {
390-
const user = await this.auth.loginPopup();
391-
if (user) {
392-
this.setAuthenticatedUser(user);
393-
return;
394-
}
404+
// If no auth client provided, create shared client for wallet-only mode
405+
if (!this.auth) {
406+
this.auth = this.createSharedAuthClient();
407+
}
408+
409+
// Attempt to get existing user first (checks localStorage/session)
410+
const existingUser = await this.auth.getUser();
411+
if (existingUser) {
412+
this.setAuthenticatedUser(existingUser);
413+
return;
414+
}
415+
416+
// No existing user, trigger login popup
417+
const user = await this.auth.loginPopup();
418+
if (user) {
419+
this.setAuthenticatedUser(user);
420+
return;
395421
}
396422

397423
throw new JsonRpcError(
398424
ProviderErrorCode.UNAUTHORIZED,
399-
'User not authenticated. Please provide an auth client or login first.',
425+
'User not authenticated. Login popup was closed or cancelled.',
400426
);
401427
}
402428

403429
/**
404430
* Handles eth_requestAccounts
405-
* Automatically triggers login if auth client is provided and user not authenticated
431+
* Automatically triggers login if user not authenticated
432+
* If no auth client is provided, uses shared client ID for wallet-only mode
406433
*/
407434
private async handleRequestAccounts(): Promise<string[]> {
408435
// Check if we already have a wallet address
@@ -412,7 +439,7 @@ export class PassportEVMProvider implements Provider {
412439
return [address];
413440
}
414441

415-
// Ensure authenticated (will auto-login if auth client provided)
442+
// Ensure authenticated (will auto-login using shared client if no auth provided)
416443
await this.ensureAuthenticated();
417444

418445
// Ensure signer is set

0 commit comments

Comments
 (0)