2025-04-04 15:46:31 -04:00
|
|
|
import NDK, { NDKUser, NDKEvent, NDKSigner } from '@nostr-dev-kit/ndk-mobile';
|
|
|
|
import * as SecureStore from 'expo-secure-store';
|
|
|
|
import { NDKPrivateKeySigner } from '@nostr-dev-kit/ndk-mobile';
|
|
|
|
import { NDKAmberSigner } from '../signers/NDKAmberSigner';
|
|
|
|
import { generateId, generateDTag } from '@/utils/ids';
|
|
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
|
|
import { AuthMethod } from './types';
|
2025-04-04 22:43:03 -04:00
|
|
|
import { createLogger, enableModule } from '@/lib/utils/logger';
|
|
|
|
import { SECURE_STORE_KEYS } from './constants';
|
|
|
|
import { Platform } from 'react-native';
|
|
|
|
|
|
|
|
// Create auth-specific logger with extended logging
|
|
|
|
enableModule('AuthService');
|
|
|
|
const logger = createLogger('AuthService');
|
|
|
|
const platform = Platform.OS === 'ios' ? 'iOS' : 'Android';
|
2025-04-02 23:40:54 -04:00
|
|
|
|
|
|
|
/**
|
2025-04-04 15:46:31 -04:00
|
|
|
* Auth Service for managing authentication with NDK and React Query
|
|
|
|
*
|
|
|
|
* Provides functionality for:
|
|
|
|
* - Login with private key
|
|
|
|
* - Login with Amber external signer
|
|
|
|
* - Ephemeral key generation
|
|
|
|
* - Secure credential storage
|
|
|
|
* - Logout and cleanup
|
2025-04-02 23:40:54 -04:00
|
|
|
*/
|
|
|
|
export class AuthService {
|
|
|
|
private ndk: NDK;
|
2025-04-04 15:46:31 -04:00
|
|
|
private initialized: boolean = false;
|
2025-04-04 22:43:03 -04:00
|
|
|
private initPromise: Promise<void> | null = null;
|
2025-04-04 15:46:31 -04:00
|
|
|
|
2025-04-02 23:40:54 -04:00
|
|
|
constructor(ndk: NDK) {
|
|
|
|
this.ndk = ndk;
|
|
|
|
}
|
2025-04-04 15:46:31 -04:00
|
|
|
|
2025-04-02 23:40:54 -04:00
|
|
|
/**
|
2025-04-04 22:43:03 -04:00
|
|
|
* Initialize the auth service - with improved error handling
|
2025-04-04 15:46:31 -04:00
|
|
|
* This is called automatically by the ReactQueryAuthProvider
|
2025-04-02 23:40:54 -04:00
|
|
|
*/
|
|
|
|
async initialize(): Promise<void> {
|
2025-04-04 22:43:03 -04:00
|
|
|
// Single initialization pattern with promise caching
|
|
|
|
if (this.initPromise) {
|
|
|
|
logger.debug("Initialization already in progress, waiting for completion");
|
|
|
|
return this.initPromise;
|
|
|
|
}
|
|
|
|
|
2025-04-04 15:46:31 -04:00
|
|
|
if (this.initialized) {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.debug("Already initialized, skipping");
|
2025-04-04 15:46:31 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
// Create a promise we can return for concurrent calls
|
|
|
|
this.initPromise = this._doInitialize();
|
|
|
|
try {
|
|
|
|
await this.initPromise;
|
|
|
|
this.initialized = true;
|
|
|
|
} catch (error) {
|
|
|
|
logger.error("Initialization failed:", error);
|
|
|
|
// Reset promise so we can try again later
|
|
|
|
this.initPromise = null;
|
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal method that does the actual initialization work
|
|
|
|
*/
|
|
|
|
private async _doInitialize(): Promise<void> {
|
2025-04-02 23:40:54 -04:00
|
|
|
try {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.info(`[${platform}] Starting initialization...`);
|
|
|
|
|
2025-04-04 15:46:31 -04:00
|
|
|
// Check if we have credentials stored
|
2025-04-04 22:43:03 -04:00
|
|
|
const privateKey = await SecureStore.getItemAsync(SECURE_STORE_KEYS.PRIVATE_KEY);
|
|
|
|
const externalSignerJson = await SecureStore.getItemAsync(SECURE_STORE_KEYS.EXTERNAL_SIGNER);
|
|
|
|
const storedPubkey = await SecureStore.getItemAsync(SECURE_STORE_KEYS.PUBKEY);
|
|
|
|
|
|
|
|
// Check both storage keys for compatibility with legacy storage
|
|
|
|
const legacyPrivateKey = await SecureStore.getItemAsync('nostr_privkey');
|
|
|
|
const newPrivateKey = await SecureStore.getItemAsync('powr.private_key');
|
|
|
|
|
|
|
|
logger.debug(`[${platform}] Found stored credentials:`, {
|
|
|
|
hasPrivateKey: !!privateKey,
|
|
|
|
hasExternalSigner: !!externalSignerJson,
|
|
|
|
storedPubkey: storedPubkey ? storedPubkey.substring(0, 8) + '...' : null,
|
|
|
|
hasLegacyPrivateKey: !!legacyPrivateKey,
|
|
|
|
hasNewPrivateKey: !!newPrivateKey,
|
|
|
|
storageKeyUsed: SECURE_STORE_KEYS.PRIVATE_KEY
|
|
|
|
});
|
2025-04-04 15:46:31 -04:00
|
|
|
|
|
|
|
// Login with stored credentials if available
|
2025-04-02 23:40:54 -04:00
|
|
|
if (privateKey) {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.info(`[${platform}] Restoring from private key`);
|
|
|
|
try {
|
|
|
|
// Try to normalize the key if needed (some platforms may add extra characters)
|
|
|
|
let normalizedKey = privateKey.trim();
|
|
|
|
// If key is longer than 64 chars, truncate it to the standard length
|
|
|
|
if (normalizedKey.length > 64) {
|
|
|
|
logger.warn(`[${platform}] Trimming private key from ${normalizedKey.length} chars to 64 chars`);
|
|
|
|
normalizedKey = normalizedKey.substring(0, 64);
|
|
|
|
}
|
|
|
|
|
|
|
|
await this.loginWithPrivateKey(normalizedKey, false); // false = don't save again
|
|
|
|
logger.info(`[${platform}] Successfully restored private key auth`);
|
|
|
|
|
|
|
|
// Double-check that pubkey was saved
|
|
|
|
const currentPubkey = this.ndk.activeUser?.pubkey;
|
|
|
|
if (currentPubkey && (!storedPubkey || storedPubkey !== currentPubkey)) {
|
|
|
|
logger.info(`[${platform}] Updating stored pubkey to match current user`);
|
|
|
|
await SecureStore.setItemAsync(SECURE_STORE_KEYS.PUBKEY, currentPubkey);
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
logger.error(`[${platform}] Error restoring private key auth:`, e);
|
|
|
|
// If we failed to restore, delete the stored key to avoid persistent errors
|
|
|
|
await SecureStore.deleteItemAsync(SECURE_STORE_KEYS.PRIVATE_KEY);
|
|
|
|
throw e;
|
|
|
|
}
|
2025-04-04 15:46:31 -04:00
|
|
|
} else if (externalSignerJson) {
|
2025-04-04 22:43:03 -04:00
|
|
|
try {
|
|
|
|
logger.info("Restoring from external signer");
|
|
|
|
const { method, data } = JSON.parse(externalSignerJson);
|
|
|
|
if (method === 'amber') {
|
|
|
|
await this.restoreAmberSigner(data);
|
|
|
|
logger.info("Successfully restored Amber signer");
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
logger.error("Error restoring external signer:", e);
|
|
|
|
// If we failed to restore, delete the stored data to avoid persistent errors
|
|
|
|
await SecureStore.deleteItemAsync(SECURE_STORE_KEYS.EXTERNAL_SIGNER);
|
|
|
|
throw e;
|
2025-04-02 23:40:54 -04:00
|
|
|
}
|
2025-04-04 22:43:03 -04:00
|
|
|
} else {
|
|
|
|
logger.debug("No stored credentials found");
|
2025-04-02 23:40:54 -04:00
|
|
|
}
|
2025-04-04 15:46:31 -04:00
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.info("Initialization complete");
|
2025-04-02 23:40:54 -04:00
|
|
|
} catch (error) {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.error("Initialization error:", error);
|
2025-04-04 15:46:31 -04:00
|
|
|
throw error;
|
2025-04-02 23:40:54 -04:00
|
|
|
}
|
|
|
|
}
|
2025-04-04 15:46:31 -04:00
|
|
|
|
2025-04-02 23:40:54 -04:00
|
|
|
/**
|
2025-04-04 22:43:03 -04:00
|
|
|
* Login with a private key - with improved logging and error handling
|
2025-04-04 15:46:31 -04:00
|
|
|
* @param privateKey hex private key
|
2025-04-04 22:43:03 -04:00
|
|
|
* @param saveKey whether to save the key to SecureStore (default true)
|
2025-04-04 15:46:31 -04:00
|
|
|
* @returns NDK user
|
2025-04-02 23:40:54 -04:00
|
|
|
*/
|
2025-04-04 22:43:03 -04:00
|
|
|
async loginWithPrivateKey(privateKey: string, saveKey: boolean = true): Promise<NDKUser> {
|
2025-04-02 23:40:54 -04:00
|
|
|
try {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.debug(`[${platform}] Creating private key signer, key length: ${privateKey.length}`);
|
|
|
|
|
|
|
|
// Debug verification for the key format
|
|
|
|
if (privateKey.length !== 64) {
|
|
|
|
logger.warn(`[${platform}] Private key has unusual length: ${privateKey.length}, expected 64 chars`);
|
|
|
|
// But we'll still try to use it
|
|
|
|
}
|
|
|
|
|
|
|
|
// Log a small fragment of the key for debugging
|
|
|
|
if (privateKey.length > 0) {
|
|
|
|
const keyPrefix = privateKey.substring(0, 4);
|
|
|
|
logger.debug(`[${platform}] Private key starts with: ${keyPrefix}...`);
|
|
|
|
}
|
|
|
|
|
2025-04-04 15:46:31 -04:00
|
|
|
// Create signer
|
|
|
|
const signer = new NDKPrivateKeySigner(privateKey);
|
|
|
|
this.ndk.signer = signer;
|
2025-04-02 23:40:54 -04:00
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
// Make sure we're connected
|
|
|
|
logger.debug(`[${platform}] Connecting to NDK with private key signer`);
|
2025-04-04 15:46:31 -04:00
|
|
|
await this.ndk.connect();
|
2025-04-04 22:43:03 -04:00
|
|
|
|
2025-04-04 15:46:31 -04:00
|
|
|
if (!this.ndk.activeUser) {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.error(`[${platform}] NDK connect succeeded but activeUser is null`);
|
2025-04-04 15:46:31 -04:00
|
|
|
throw new Error('Failed to set active user after login');
|
2025-04-02 23:40:54 -04:00
|
|
|
}
|
2025-04-04 15:46:31 -04:00
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
const pubkeyFragment = this.ndk.activeUser.pubkey.substring(0, 8);
|
|
|
|
logger.info(`[${platform}] Successfully logged in with private key for user: ${pubkeyFragment}...`);
|
|
|
|
|
|
|
|
// Persist the key securely if requested
|
|
|
|
if (saveKey) {
|
|
|
|
logger.debug(`[${platform}] Saving private key to SecureStore`);
|
|
|
|
await SecureStore.setItemAsync(SECURE_STORE_KEYS.PRIVATE_KEY, privateKey);
|
|
|
|
|
|
|
|
// Also save the public key for faster reference
|
|
|
|
await SecureStore.setItemAsync(SECURE_STORE_KEYS.PUBKEY, this.ndk.activeUser.pubkey);
|
|
|
|
|
|
|
|
logger.debug(`[${platform}] Credentials saved successfully`);
|
|
|
|
}
|
2025-04-04 15:46:31 -04:00
|
|
|
|
|
|
|
return this.ndk.activeUser;
|
2025-04-02 23:40:54 -04:00
|
|
|
} catch (error) {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.error("Error logging in with private key:", error);
|
2025-04-02 23:40:54 -04:00
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
}
|
2025-04-04 15:46:31 -04:00
|
|
|
|
2025-04-02 23:40:54 -04:00
|
|
|
/**
|
2025-04-04 22:43:03 -04:00
|
|
|
* Login with Amber external signer - enhanced error handling
|
2025-04-04 15:46:31 -04:00
|
|
|
* @returns NDK user
|
2025-04-02 23:40:54 -04:00
|
|
|
*/
|
2025-04-04 15:46:31 -04:00
|
|
|
async loginWithAmber(): Promise<NDKUser> {
|
2025-04-02 23:40:54 -04:00
|
|
|
try {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.info("Requesting public key from Amber");
|
2025-04-04 15:46:31 -04:00
|
|
|
// Request public key from Amber
|
|
|
|
const { pubkey, packageName } = await NDKAmberSigner.requestPublicKey();
|
2025-04-02 23:40:54 -04:00
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.debug("Creating Amber signer with pubkey:", pubkey);
|
2025-04-04 15:46:31 -04:00
|
|
|
// Create Amber signer
|
|
|
|
const amberSigner = new NDKAmberSigner(pubkey, packageName);
|
2025-04-02 23:40:54 -04:00
|
|
|
|
2025-04-04 15:46:31 -04:00
|
|
|
// Set as NDK signer
|
|
|
|
this.ndk.signer = amberSigner;
|
2025-04-02 23:40:54 -04:00
|
|
|
|
2025-04-04 15:46:31 -04:00
|
|
|
// Connect and get user
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.debug("Connecting to NDK with Amber signer");
|
2025-04-04 15:46:31 -04:00
|
|
|
await this.ndk.connect();
|
|
|
|
if (!this.ndk.activeUser) {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.error("NDK connect succeeded but activeUser is null for Amber signer");
|
2025-04-04 15:46:31 -04:00
|
|
|
throw new Error('Failed to set active user after amber login');
|
2025-04-02 23:40:54 -04:00
|
|
|
}
|
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.info("Successfully logged in with Amber for user:", pubkey);
|
|
|
|
|
2025-04-04 15:46:31 -04:00
|
|
|
// Store the signer info
|
|
|
|
const signerData = {
|
|
|
|
pubkey: pubkey,
|
|
|
|
packageName: packageName
|
|
|
|
};
|
|
|
|
const externalSignerInfo = JSON.stringify({
|
|
|
|
method: 'amber',
|
|
|
|
data: signerData
|
2025-04-02 23:40:54 -04:00
|
|
|
});
|
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.debug("Saving Amber signer data to SecureStore");
|
|
|
|
await SecureStore.setItemAsync(SECURE_STORE_KEYS.EXTERNAL_SIGNER, externalSignerInfo);
|
|
|
|
await SecureStore.setItemAsync(SECURE_STORE_KEYS.PUBKEY, pubkey);
|
|
|
|
await SecureStore.deleteItemAsync(SECURE_STORE_KEYS.PRIVATE_KEY); // Clear any stored private key
|
2025-04-02 23:40:54 -04:00
|
|
|
|
2025-04-04 15:46:31 -04:00
|
|
|
return this.ndk.activeUser;
|
2025-04-02 23:40:54 -04:00
|
|
|
} catch (error) {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.error("Error logging in with Amber:", error);
|
2025-04-02 23:40:54 -04:00
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2025-04-04 15:46:31 -04:00
|
|
|
* Restore an Amber signer session
|
|
|
|
* @param signerData Previous signer data
|
|
|
|
* @returns NDK user
|
2025-04-02 23:40:54 -04:00
|
|
|
*/
|
2025-04-04 15:46:31 -04:00
|
|
|
private async restoreAmberSigner(signerData: any): Promise<NDKUser> {
|
2025-04-02 23:40:54 -04:00
|
|
|
try {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.debug("Restoring Amber signer with data:", signerData);
|
2025-04-04 15:46:31 -04:00
|
|
|
// Create Amber signer with existing data
|
|
|
|
const amberSigner = new NDKAmberSigner(signerData.pubkey, signerData.packageName);
|
2025-04-02 23:40:54 -04:00
|
|
|
|
2025-04-04 15:46:31 -04:00
|
|
|
// Set as NDK signer
|
|
|
|
this.ndk.signer = amberSigner;
|
2025-04-02 23:40:54 -04:00
|
|
|
|
2025-04-04 15:46:31 -04:00
|
|
|
// Connect and get user
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.debug("Connecting to NDK with restored Amber signer");
|
2025-04-04 15:46:31 -04:00
|
|
|
await this.ndk.connect();
|
|
|
|
if (!this.ndk.activeUser) {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.error("NDK connect succeeded but activeUser is null for restored Amber signer");
|
2025-04-04 15:46:31 -04:00
|
|
|
throw new Error('Failed to set active user after amber signer restore');
|
|
|
|
}
|
2025-04-02 23:40:54 -04:00
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.info("Successfully restored Amber signer for user:", signerData.pubkey);
|
|
|
|
|
2025-04-04 15:46:31 -04:00
|
|
|
return this.ndk.activeUser;
|
2025-04-02 23:40:54 -04:00
|
|
|
} catch (error) {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.error("Error restoring Amber signer:", error);
|
2025-04-02 23:40:54 -04:00
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
}
|
2025-04-04 15:46:31 -04:00
|
|
|
|
2025-04-02 23:40:54 -04:00
|
|
|
/**
|
2025-04-04 15:46:31 -04:00
|
|
|
* Create an ephemeral key for temporary use
|
|
|
|
* @returns NDK user
|
2025-04-02 23:40:54 -04:00
|
|
|
*/
|
2025-04-04 15:46:31 -04:00
|
|
|
async createEphemeralKey(): Promise<NDKUser> {
|
2025-04-02 23:40:54 -04:00
|
|
|
try {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.info("Creating ephemeral key");
|
2025-04-04 15:46:31 -04:00
|
|
|
// Generate a random key (not persisted)
|
|
|
|
// This creates a hex string of 64 characters (32 bytes)
|
|
|
|
// Use uuidv4 to generate random bytes
|
|
|
|
const randomId = uuidv4().replace(/-/g, '') + uuidv4().replace(/-/g, '');
|
|
|
|
const privateKey = randomId.substring(0, 64); // Ensure exactly 64 hex chars (32 bytes)
|
|
|
|
const signer = new NDKPrivateKeySigner(privateKey);
|
|
|
|
|
|
|
|
// Set as NDK signer
|
|
|
|
this.ndk.signer = signer;
|
|
|
|
|
|
|
|
// Connect and get user
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.debug("Connecting to NDK with ephemeral key");
|
2025-04-04 15:46:31 -04:00
|
|
|
await this.ndk.connect();
|
|
|
|
if (!this.ndk.activeUser) {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.error("NDK connect succeeded but activeUser is null for ephemeral key");
|
2025-04-04 15:46:31 -04:00
|
|
|
throw new Error('Failed to set active user after ephemeral key creation');
|
2025-04-02 23:40:54 -04:00
|
|
|
}
|
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.info("Successfully created ephemeral key for user:", this.ndk.activeUser.pubkey);
|
|
|
|
|
2025-04-04 15:46:31 -04:00
|
|
|
// Clear any stored credentials
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.debug("Clearing stored credentials for ephemeral key");
|
|
|
|
await SecureStore.deleteItemAsync(SECURE_STORE_KEYS.PRIVATE_KEY);
|
|
|
|
await SecureStore.deleteItemAsync(SECURE_STORE_KEYS.EXTERNAL_SIGNER);
|
|
|
|
await SecureStore.deleteItemAsync(SECURE_STORE_KEYS.PUBKEY);
|
2025-04-02 23:40:54 -04:00
|
|
|
|
2025-04-04 15:46:31 -04:00
|
|
|
return this.ndk.activeUser;
|
2025-04-02 23:40:54 -04:00
|
|
|
} catch (error) {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.error("Error creating ephemeral key:", error);
|
2025-04-02 23:40:54 -04:00
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
}
|
2025-04-04 15:46:31 -04:00
|
|
|
|
2025-04-02 23:40:54 -04:00
|
|
|
/**
|
2025-04-04 15:46:31 -04:00
|
|
|
* Log out the current user
|
2025-04-02 23:40:54 -04:00
|
|
|
*/
|
2025-04-04 15:46:31 -04:00
|
|
|
async logout(): Promise<void> {
|
|
|
|
try {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.info("Logging out user");
|
|
|
|
|
2025-04-04 15:46:31 -04:00
|
|
|
// Clear stored credentials
|
2025-04-04 22:43:03 -04:00
|
|
|
await SecureStore.deleteItemAsync(SECURE_STORE_KEYS.PRIVATE_KEY);
|
|
|
|
await SecureStore.deleteItemAsync(SECURE_STORE_KEYS.EXTERNAL_SIGNER);
|
|
|
|
await SecureStore.deleteItemAsync(SECURE_STORE_KEYS.PUBKEY);
|
2025-04-04 15:46:31 -04:00
|
|
|
|
|
|
|
// Reset NDK
|
|
|
|
this.ndk.signer = undefined;
|
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
// Clean up relay connections if they exist
|
2025-04-02 23:40:54 -04:00
|
|
|
try {
|
2025-04-04 15:46:31 -04:00
|
|
|
if (this.ndk.pool) {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.debug("Cleaning up relay connections");
|
2025-04-04 15:46:31 -04:00
|
|
|
// Cast to any to bypass TypeScript errors with internal NDK API
|
|
|
|
const pool = this.ndk.pool as any;
|
|
|
|
if (pool.relayByUrl) {
|
|
|
|
Object.values(pool.relayByUrl).forEach((relay: any) => {
|
|
|
|
try {
|
|
|
|
if (relay && relay.close) relay.close();
|
|
|
|
} catch (e) {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.warn("Error closing relay:", e);
|
2025-04-04 15:46:31 -04:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (e) {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.warn("Error during NDK resource cleanup:", e);
|
2025-04-02 23:40:54 -04:00
|
|
|
}
|
2025-04-04 15:46:31 -04:00
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.info("Logged out successfully");
|
2025-04-04 15:46:31 -04:00
|
|
|
} catch (error) {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.error("Error during logout:", error);
|
2025-04-04 15:46:31 -04:00
|
|
|
throw error;
|
2025-04-02 23:40:54 -04:00
|
|
|
}
|
|
|
|
}
|
2025-04-04 15:46:31 -04:00
|
|
|
|
2025-04-02 23:40:54 -04:00
|
|
|
/**
|
2025-04-04 15:46:31 -04:00
|
|
|
* Get the current authentication method
|
|
|
|
* @returns Auth method or undefined if not authenticated
|
2025-04-02 23:40:54 -04:00
|
|
|
*/
|
2025-04-04 15:46:31 -04:00
|
|
|
async getCurrentAuthMethod(): Promise<AuthMethod | undefined> {
|
2025-04-02 23:40:54 -04:00
|
|
|
try {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.debug("Getting current auth method");
|
|
|
|
if (await SecureStore.getItemAsync(SECURE_STORE_KEYS.PRIVATE_KEY)) {
|
|
|
|
logger.debug("Found private key authentication");
|
2025-04-04 15:46:31 -04:00
|
|
|
return 'private_key';
|
|
|
|
}
|
2025-04-02 23:40:54 -04:00
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
const externalSignerJson = await SecureStore.getItemAsync(SECURE_STORE_KEYS.EXTERNAL_SIGNER);
|
2025-04-04 15:46:31 -04:00
|
|
|
if (externalSignerJson) {
|
|
|
|
const { method } = JSON.parse(externalSignerJson);
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.debug(`Found external signer authentication: ${method}`);
|
2025-04-04 15:46:31 -04:00
|
|
|
return method === 'amber' ? 'amber' : undefined;
|
2025-04-02 23:40:54 -04:00
|
|
|
}
|
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.debug("No authentication method found");
|
2025-04-04 15:46:31 -04:00
|
|
|
return undefined;
|
2025-04-02 23:40:54 -04:00
|
|
|
} catch (error) {
|
2025-04-04 22:43:03 -04:00
|
|
|
logger.error("Error getting current auth method:", error);
|
2025-04-04 15:46:31 -04:00
|
|
|
return undefined;
|
2025-04-02 23:40:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|