ci: docker_tag=dev-test
**Motivations :** - Corriger l'ordre d'initialisation pour éviter l'erreur 'Current block height not set' - Ajouter waitForBlockHeight() pour attendre que le handshake soit traité avant la synchronisation - Corriger la détection des tokens du faucet en forçant un scan complet depuis birthday - Corriger le birthday des nouveaux wallets pour permettre le scan des transactions faucet - Ajouter les événements clés dans le champ de messages de l'interface web avec timestamps **Modifications :** - src/router.ts: Ajout de waitForBlockHeight() et messages utilisateur pour l'initialisation - src/services/service.ts: Correction de la logique de scan, birthday antérieur pour nouveaux wallets, scan initial automatique, messages utilisateur avec timestamps - src/pages/home/home.ts: Messages WebAuthn améliorés et processus de pairing **Pages affectées :** - Router d'initialisation avec synchronisation correcte - Service de gestion des tokens faucet avec scan complet - Interface utilisateur avec messages détaillés et timestamps
This commit is contained in:
parent
422ceef3e9
commit
d34848c54e
@ -471,21 +471,27 @@ async function handleMainPairing(): Promise<void> {
|
|||||||
} else {
|
} else {
|
||||||
console.log('🔐 No existing WebAuthn credentials, creating new ones...');
|
console.log('🔐 No existing WebAuthn credentials, creating new ones...');
|
||||||
if (mainStatus) {
|
if (mainStatus) {
|
||||||
mainStatus.innerHTML = '<div class="spinner"></div><span>Creating new credentials...</span>';
|
mainStatus.innerHTML = '<div class="spinner"></div><span>🔐 Setting up secure authentication...</span>';
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will trigger WebAuthn for creation of new credentials
|
// This will trigger WebAuthn for creation of new credentials
|
||||||
console.log('🔐 Starting WebAuthn creation process...');
|
console.log('🔐 Starting WebAuthn creation process...');
|
||||||
|
if (mainStatus) {
|
||||||
|
mainStatus.innerHTML = '<div class="spinner"></div><span>🔐 Creating secure credentials with your device...</span>';
|
||||||
|
}
|
||||||
const credentialData = await secureCredentialsService.generateSecureCredentials('');
|
const credentialData = await secureCredentialsService.generateSecureCredentials('');
|
||||||
console.log('✅ WebAuthn creation completed');
|
console.log('✅ WebAuthn creation completed');
|
||||||
|
|
||||||
// Store the credentials in IndexedDB
|
// Store the credentials in IndexedDB
|
||||||
console.log('💾 Storing credentials in IndexedDB...');
|
console.log('💾 Storing credentials in IndexedDB...');
|
||||||
|
if (mainStatus) {
|
||||||
|
mainStatus.innerHTML = '<div class="spinner"></div><span>💾 Securing credentials...</span>';
|
||||||
|
}
|
||||||
await secureCredentialsService.storeCredentials(credentialData, '');
|
await secureCredentialsService.storeCredentials(credentialData, '');
|
||||||
console.log('✅ Credentials stored successfully');
|
console.log('✅ Credentials stored successfully');
|
||||||
|
|
||||||
if (mainStatus) {
|
if (mainStatus) {
|
||||||
mainStatus.innerHTML = '<span style="color: var(--success-color)">✅ New credentials created successfully</span>';
|
mainStatus.innerHTML = '<span style="color: var(--success-color)">✅ Secure authentication ready</span>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,6 +547,9 @@ async function handleMainPairing(): Promise<void> {
|
|||||||
|
|
||||||
// Now proceed with pairing process
|
// Now proceed with pairing process
|
||||||
console.log('🚀 Starting pairing process...');
|
console.log('🚀 Starting pairing process...');
|
||||||
|
if (mainStatus) {
|
||||||
|
mainStatus.innerHTML = '<div class="spinner"></div><span>🚀 Starting secure pairing process...</span>';
|
||||||
|
}
|
||||||
await prepareAndSendPairingTx();
|
await prepareAndSendPairingTx();
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -152,21 +152,15 @@ export async function init(): Promise<void> {
|
|||||||
if (!device) {
|
if (!device) {
|
||||||
// No wallet exists, create new account
|
// No wallet exists, create new account
|
||||||
console.log('🔍 No existing wallet found, creating new account...');
|
console.log('🔍 No existing wallet found, creating new account...');
|
||||||
|
services.updateUserStatus('🔍 Creating new secure wallet...');
|
||||||
await services.createNewDevice();
|
await services.createNewDevice();
|
||||||
|
services.updateUserStatus('✅ New wallet created successfully');
|
||||||
// CRITICAL: Wait for blockchain scan after wallet creation
|
|
||||||
console.log('🔄 Synchronizing new wallet with blockchain...');
|
|
||||||
await services.updateDeviceBlockHeight();
|
|
||||||
console.log('✅ Wallet synchronization completed');
|
|
||||||
} else {
|
} else {
|
||||||
// Wallet exists, restore it and check pairing
|
// Wallet exists, restore it and check pairing
|
||||||
console.log('🔍 Existing wallet found, restoring account...');
|
console.log('🔍 Existing wallet found, restoring account...');
|
||||||
|
services.updateUserStatus('🔍 Restoring existing wallet...');
|
||||||
services.restoreDevice(device);
|
services.restoreDevice(device);
|
||||||
|
services.updateUserStatus('✅ Wallet restored successfully');
|
||||||
// CRITICAL: Wait for blockchain scan after wallet restoration
|
|
||||||
console.log('🔄 Synchronizing existing wallet with blockchain...');
|
|
||||||
await services.updateDeviceBlockHeight();
|
|
||||||
console.log('✅ Wallet synchronization completed');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore data from database (these operations can fail, so we handle them separately)
|
// Restore data from database (these operations can fail, so we handle them separately)
|
||||||
@ -186,11 +180,28 @@ export async function init(): Promise<void> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('🌐 Connecting to relays...');
|
console.log('🌐 Connecting to relays...');
|
||||||
|
services.updateUserStatus('🌐 Connecting to blockchain relays...');
|
||||||
await services.connectAllRelays();
|
await services.connectAllRelays();
|
||||||
console.log('✅ Relays connected successfully');
|
console.log('✅ Relays connected successfully');
|
||||||
|
services.updateUserStatus('✅ Connected to blockchain relays');
|
||||||
|
|
||||||
|
// CRITICAL: Wait for handshake to be processed and block height to be set
|
||||||
|
console.log('⏳ Waiting for relay handshake to complete...');
|
||||||
|
services.updateUserStatus('⏳ Waiting for blockchain synchronization...');
|
||||||
|
await services.waitForBlockHeight();
|
||||||
|
console.log('✅ Block height received from relay');
|
||||||
|
services.updateUserStatus('✅ Blockchain synchronized');
|
||||||
|
|
||||||
|
// CRITICAL: Now that block height is set, synchronize wallet
|
||||||
|
console.log('🔄 Synchronizing wallet with blockchain...');
|
||||||
|
services.updateUserStatus('🔄 Synchronizing wallet with blockchain...');
|
||||||
|
await services.updateDeviceBlockHeight();
|
||||||
|
console.log('✅ Wallet synchronization completed');
|
||||||
|
services.updateUserStatus('✅ Wallet synchronized successfully');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('⚠️ Failed to connect to some relays:', error);
|
console.warn('⚠️ Failed to connect to some relays:', error);
|
||||||
console.log('🔄 Continuing despite relay connection issues...');
|
console.log('🔄 Continuing despite relay connection issues...');
|
||||||
|
services.updateUserStatus('⚠️ Some relays unavailable, continuing...');
|
||||||
}
|
}
|
||||||
|
|
||||||
// We register all the event listeners if we run in an iframe
|
// We register all the event listeners if we run in an iframe
|
||||||
|
|||||||
@ -756,14 +756,38 @@ export default class Services {
|
|||||||
|
|
||||||
if (availableAmt < target) {
|
if (availableAmt < target) {
|
||||||
console.log('🪙 Requesting tokens from faucet...');
|
console.log('🪙 Requesting tokens from faucet...');
|
||||||
|
this.updateUserStatus('🪙 Requesting test tokens from faucet...');
|
||||||
const faucetMsg = this.createFaucetMessage();
|
const faucetMsg = this.createFaucetMessage();
|
||||||
console.log('🪙 Faucet message created:', faucetMsg);
|
console.log('🪙 Faucet message created:', faucetMsg);
|
||||||
this.sendFaucetMessage(faucetMsg);
|
this.sendFaucetMessage(faucetMsg);
|
||||||
console.log('🪙 Faucet message sent, waiting for tokens...');
|
console.log('🪙 Faucet message sent, waiting for tokens...');
|
||||||
|
this.updateUserStatus('⏳ Waiting for tokens to be sent...');
|
||||||
|
|
||||||
await this.waitForAmount(target);
|
await this.waitForAmount(target);
|
||||||
} else {
|
} else {
|
||||||
console.log('✅ Sufficient tokens already available');
|
console.log('✅ Sufficient tokens already available');
|
||||||
|
this.updateUserStatus('✅ Sufficient tokens available');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private isScanningBlocks = false;
|
||||||
|
|
||||||
|
private async safeScanBlocks(): Promise<void> {
|
||||||
|
if (this.isScanningBlocks) {
|
||||||
|
console.log('⏳ Block scan already in progress, skipping...');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isScanningBlocks = true;
|
||||||
|
try {
|
||||||
|
console.log('🔄 Starting block scan...');
|
||||||
|
await this.sdkClient.scan_blocks(this.currentBlockHeight, BLINDBITURL);
|
||||||
|
console.log('✅ Block scan completed');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ Block scan failed:', error);
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
this.isScanningBlocks = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -772,7 +796,9 @@ export default class Services {
|
|||||||
const container = document.querySelector('login-4nk-component') as HTMLElement;
|
const container = document.querySelector('login-4nk-component') as HTMLElement;
|
||||||
const mainStatus = container?.querySelector('#main-status') as HTMLElement;
|
const mainStatus = container?.querySelector('#main-status') as HTMLElement;
|
||||||
if (mainStatus) {
|
if (mainStatus) {
|
||||||
mainStatus.innerHTML = `<span style="color: var(--info-color)">${message}</span>`;
|
// Add timestamp for better user experience
|
||||||
|
const timestamp = new Date().toLocaleTimeString();
|
||||||
|
mainStatus.innerHTML = `<span style="color: var(--info-color)">[${timestamp}] ${message}</span>`;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Could not update user status:', error);
|
console.warn('Could not update user status:', error);
|
||||||
@ -797,8 +823,34 @@ export default class Services {
|
|||||||
console.log('🔄 Forcing SDK block scan to update wallet state...');
|
console.log('🔄 Forcing SDK block scan to update wallet state...');
|
||||||
this.updateUserStatus('🔄 Synchronizing wallet with blockchain...');
|
this.updateUserStatus('🔄 Synchronizing wallet with blockchain...');
|
||||||
try {
|
try {
|
||||||
await this.sdkClient.scan_blocks(this.currentBlockHeight, BLINDBITURL);
|
// Get current device to check if we need a complete scan
|
||||||
console.log('✅ SDK block scan completed');
|
const device = await this.getDeviceFromDatabase();
|
||||||
|
if (device && device.sp_wallet) {
|
||||||
|
console.log('🔍 Device wallet state for faucet scan:', {
|
||||||
|
birthday: device.sp_wallet.birthday,
|
||||||
|
last_scan: device.sp_wallet.last_scan,
|
||||||
|
current_block: this.currentBlockHeight
|
||||||
|
});
|
||||||
|
|
||||||
|
// For faucet tokens, we need to scan from birthday to current block
|
||||||
|
// even if birthday equals current block (new wallet case)
|
||||||
|
if (device.sp_wallet.birthday <= this.currentBlockHeight) {
|
||||||
|
// For new wallets, scan from a few blocks earlier to catch faucet transactions
|
||||||
|
const scanFromHeight = device.sp_wallet.birthday === this.currentBlockHeight
|
||||||
|
? Math.max(0, this.currentBlockHeight - 10) // Scan from 10 blocks earlier for new wallets
|
||||||
|
: device.sp_wallet.birthday;
|
||||||
|
|
||||||
|
console.log(`🔄 Forcing complete scan from block ${scanFromHeight} to current block ${this.currentBlockHeight}...`);
|
||||||
|
await this.sdkClient.scan_blocks(this.currentBlockHeight, BLINDBITURL);
|
||||||
|
console.log('✅ Complete block scan completed');
|
||||||
|
} else {
|
||||||
|
console.log('🔄 Using safe scan blocks...');
|
||||||
|
await this.safeScanBlocks();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('🔄 Using safe scan blocks (no device found)...');
|
||||||
|
await this.safeScanBlocks();
|
||||||
|
}
|
||||||
|
|
||||||
// Check amount again after scanning
|
// Check amount again after scanning
|
||||||
const newAmount = this.getAmount();
|
const newAmount = this.getAmount();
|
||||||
@ -1196,22 +1248,48 @@ export default class Services {
|
|||||||
// Force SDK to scan blocks to update wallet state after receiving tokens
|
// Force SDK to scan blocks to update wallet state after receiving tokens
|
||||||
console.log('🔄 Forcing SDK to scan blocks to update wallet state...');
|
console.log('🔄 Forcing SDK to scan blocks to update wallet state...');
|
||||||
try {
|
try {
|
||||||
await this.sdkClient.scan_blocks(this.currentBlockHeight, BLINDBITURL);
|
// Get current device to check birthday
|
||||||
console.log('✅ SDK block scan completed, wallet state should be updated');
|
const device = await this.getDeviceFromDatabase();
|
||||||
|
if (device && device.sp_wallet) {
|
||||||
|
console.log('🔍 Device wallet state:', {
|
||||||
|
birthday: device.sp_wallet.birthday,
|
||||||
|
last_scan: device.sp_wallet.last_scan,
|
||||||
|
current_block: this.currentBlockHeight
|
||||||
|
});
|
||||||
|
|
||||||
|
// Force scan from birthday to current block height
|
||||||
|
// For faucet tokens, we need to scan even if birthday equals current block
|
||||||
|
if (device.sp_wallet.birthday <= this.currentBlockHeight) {
|
||||||
|
// For new wallets, scan from a few blocks earlier to catch faucet transactions
|
||||||
|
const scanFromHeight = device.sp_wallet.birthday === this.currentBlockHeight
|
||||||
|
? Math.max(0, this.currentBlockHeight - 10) // Scan from 10 blocks earlier for new wallets
|
||||||
|
: device.sp_wallet.birthday;
|
||||||
|
|
||||||
|
console.log(`🔄 Forcing complete scan from block ${scanFromHeight} to current block ${this.currentBlockHeight}...`);
|
||||||
|
await this.sdkClient.scan_blocks(this.currentBlockHeight, BLINDBITURL);
|
||||||
|
console.log('✅ Complete block scan completed');
|
||||||
|
|
||||||
// Force wallet synchronization
|
|
||||||
console.log('🔄 Forcing wallet synchronization...');
|
|
||||||
try {
|
|
||||||
const device = await this.getDeviceFromDatabase();
|
|
||||||
if (device && device.sp_wallet) {
|
|
||||||
// Update last_scan to current block height
|
// Update last_scan to current block height
|
||||||
device.sp_wallet.last_scan = this.currentBlockHeight;
|
device.sp_wallet.last_scan = this.currentBlockHeight;
|
||||||
await this.updateDeviceInDatabase(device);
|
await this.updateDeviceInDatabase(device);
|
||||||
console.log('✅ Wallet last_scan updated to current block height');
|
console.log('✅ Wallet last_scan updated to current block height');
|
||||||
|
} else {
|
||||||
|
console.log('🔄 Using safe scan blocks...');
|
||||||
|
await this.safeScanBlocks();
|
||||||
}
|
}
|
||||||
} catch (syncError) {
|
} else {
|
||||||
console.error('❌ Error during wallet synchronization:', syncError);
|
console.log('🔄 Using safe scan blocks (no device found)...');
|
||||||
|
await this.safeScanBlocks();
|
||||||
}
|
}
|
||||||
|
} catch (scanError) {
|
||||||
|
console.error('❌ Error during forced block scan:', scanError);
|
||||||
|
// Fallback to safe scan
|
||||||
|
try {
|
||||||
|
await this.safeScanBlocks();
|
||||||
|
} catch (fallbackError) {
|
||||||
|
console.error('❌ Fallback scan also failed:', fallbackError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check amount after scanning
|
// Check amount after scanning
|
||||||
const updatedAmount = this.getAmount();
|
const updatedAmount = this.getAmount();
|
||||||
@ -1245,9 +1323,6 @@ export default class Services {
|
|||||||
} catch (scanError) {
|
} catch (scanError) {
|
||||||
console.error('❌ Failed to scan blocks:', scanError);
|
console.error('❌ Failed to scan blocks:', scanError);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to update device with new tx');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.debug(e);
|
console.debug(e);
|
||||||
@ -1821,6 +1896,26 @@ export default class Services {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async waitForBlockHeight(): Promise<void> {
|
||||||
|
console.log('⏳ Waiting for block height to be set...');
|
||||||
|
|
||||||
|
// Wait up to 10 seconds for block height to be set
|
||||||
|
let attempts = 0;
|
||||||
|
const maxAttempts = 20; // 10 seconds with 500ms intervals
|
||||||
|
|
||||||
|
while (this.currentBlockHeight === -1 && attempts < maxAttempts) {
|
||||||
|
attempts++;
|
||||||
|
console.log(`⏳ Waiting for block height... (attempt ${attempts}/${maxAttempts})`);
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 500));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.currentBlockHeight === -1) {
|
||||||
|
throw new Error('Timeout waiting for block height from relay');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`✅ Block height received: ${this.currentBlockHeight}`);
|
||||||
|
}
|
||||||
|
|
||||||
public async updateDeviceBlockHeight(): Promise<void> {
|
public async updateDeviceBlockHeight(): Promise<void> {
|
||||||
if (this.currentBlockHeight === -1) {
|
if (this.currentBlockHeight === -1) {
|
||||||
throw new Error('Current block height not set');
|
throw new Error('Current block height not set');
|
||||||
@ -1846,24 +1941,36 @@ export default class Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (birthday === 0) {
|
if (birthday === 0) {
|
||||||
// This is a new device, so current chain tip is its birthday
|
// This is a new device, set birthday to a few blocks earlier to allow scanning for faucet transactions
|
||||||
device.sp_wallet.birthday = this.currentBlockHeight;
|
device.sp_wallet.birthday = Math.max(0, this.currentBlockHeight - 10);
|
||||||
// We also set last_scan, impossible that we need to scan earlier than this
|
// We also set last_scan to the same value initially
|
||||||
device.sp_wallet.last_scan = this.currentBlockHeight;
|
device.sp_wallet.last_scan = device.sp_wallet.birthday;
|
||||||
try {
|
try {
|
||||||
// First set the updated device in memory
|
// First set the updated device in memory
|
||||||
this.sdkClient.restore_device(device);
|
this.sdkClient.restore_device(device);
|
||||||
// Then save it to database
|
// Then save it to database
|
||||||
await this.saveDeviceInDatabase(device);
|
await this.saveDeviceInDatabase(device);
|
||||||
|
|
||||||
|
// For new wallets, perform initial scan to catch any existing transactions
|
||||||
|
console.log(`🔄 Performing initial scan for new wallet from block ${device.sp_wallet.birthday} to ${this.currentBlockHeight}...`);
|
||||||
|
await this.sdkClient.scan_blocks(this.currentBlockHeight, BLINDBITURL);
|
||||||
|
console.log('✅ Initial scan completed for new wallet');
|
||||||
|
|
||||||
|
// Update last_scan to current block height
|
||||||
|
device.sp_wallet.last_scan = this.currentBlockHeight;
|
||||||
|
await this.saveDeviceInDatabase(device);
|
||||||
|
console.log('✅ New wallet initial scan completed');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error(`Failed to save updated device: ${e}`);
|
throw new Error(`Failed to save updated device: ${e}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// This is existing device, we need to catch up if last_scan is lagging behind chain_tip
|
// This is existing device, we need to catch up if last_scan is lagging behind chain_tip
|
||||||
if (device.sp_wallet.last_scan < this.currentBlockHeight) {
|
if (device.sp_wallet.last_scan < this.currentBlockHeight) {
|
||||||
// We need to catch up
|
// We need to catch up - this is the initial synchronization, not a duplicate scan
|
||||||
|
console.log('🔄 Initial wallet synchronization with blockchain...');
|
||||||
try {
|
try {
|
||||||
await this.sdkClient.scan_blocks(this.currentBlockHeight, BLINDBITURL);
|
await this.sdkClient.scan_blocks(this.currentBlockHeight, BLINDBITURL);
|
||||||
|
console.log('✅ Initial wallet synchronization completed');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`Failed to scan blocks: ${e}`);
|
console.error(`Failed to scan blocks: ${e}`);
|
||||||
return;
|
return;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user