Add some debug methods for pairing workflow
Some checks failed
Build and Push to Registry / build-and-push (push) Failing after 44s
Some checks failed
Build and Push to Registry / build-and-push (push) Failing after 44s
This commit is contained in:
parent
79633ed923
commit
7ea4ef1920
@ -401,13 +401,13 @@ export async function registerAllListeners() {
|
|||||||
// Retrieve the state for the process
|
// Retrieve the state for the process
|
||||||
const process = await services.getProcess(processId);
|
const process = await services.getProcess(processId);
|
||||||
if (!process) {
|
if (!process) {
|
||||||
throw new Error('Can\'t find process');
|
throw new Error("Can't find process");
|
||||||
}
|
}
|
||||||
const state = services.getStateFromId(process, stateId);
|
const state = services.getStateFromId(process, stateId);
|
||||||
|
|
||||||
await services.checkConnections(process, stateId);
|
await services.checkConnections(process, stateId);
|
||||||
|
|
||||||
let res: Record<string, any> = {};
|
const res: Record<string, any> = {};
|
||||||
if (state) {
|
if (state) {
|
||||||
// Decrypt all the data we have the key for
|
// Decrypt all the data we have the key for
|
||||||
for (const attribute of Object.keys(state.pcd_commitment)) {
|
for (const attribute of Object.keys(state.pcd_commitment)) {
|
||||||
@ -427,7 +427,7 @@ export async function registerAllListeners() {
|
|||||||
{
|
{
|
||||||
type: MessageType.DATA_RETRIEVED,
|
type: MessageType.DATA_RETRIEVED,
|
||||||
data: res,
|
data: res,
|
||||||
messageId: event.data.messageId
|
messageId: event.data.messageId,
|
||||||
},
|
},
|
||||||
event.origin
|
event.origin
|
||||||
);
|
);
|
||||||
@ -500,6 +500,8 @@ export async function registerAllListeners() {
|
|||||||
|
|
||||||
if (!services.isPaired()) {
|
if (!services.isPaired()) {
|
||||||
const errorMsg = 'Device not paired';
|
const errorMsg = 'Device not paired';
|
||||||
|
console.log('Device not paired - running diagnosis...');
|
||||||
|
await services.diagnosePairingState();
|
||||||
errorResponse(errorMsg, event.origin, event.data.messageId);
|
errorResponse(errorMsg, event.origin, event.data.messageId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -123,6 +123,7 @@ export default class Services {
|
|||||||
this.relayReadyResolver = null;
|
this.relayReadyResolver = null;
|
||||||
this.relayReadyPromise = null;
|
this.relayReadyPromise = null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async addWebsocketConnection(url: string): Promise<void> {
|
public async addWebsocketConnection(url: string): Promise<void> {
|
||||||
console.log('Opening new websocket connection');
|
console.log('Opening new websocket connection');
|
||||||
@ -171,7 +172,21 @@ export default class Services {
|
|||||||
|
|
||||||
public isPaired(): boolean {
|
public isPaired(): boolean {
|
||||||
try {
|
try {
|
||||||
return this.sdkClient.is_paired();
|
const result = this.sdkClient.is_paired();
|
||||||
|
console.log('isPaired() called, result:', result);
|
||||||
|
|
||||||
|
// Additional debugging: check device state
|
||||||
|
try {
|
||||||
|
const device = this.dumpDeviceFromMemory();
|
||||||
|
console.log('Current device state:', {
|
||||||
|
pairing_process_commitment: device.pairing_process_commitment,
|
||||||
|
paired_member: device.paired_member
|
||||||
|
});
|
||||||
|
} catch (deviceError) {
|
||||||
|
console.error('Failed to dump device for debugging:', deviceError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error(`isPaired ~ Error: ${e}`);
|
throw new Error(`isPaired ~ Error: ${e}`);
|
||||||
}
|
}
|
||||||
@ -230,7 +245,7 @@ export default class Services {
|
|||||||
// We will take the roles from the last state, wheter it's commited or not
|
// We will take the roles from the last state, wheter it's commited or not
|
||||||
public async checkConnections(process: Process, stateId: string | null = null): Promise<void> {
|
public async checkConnections(process: Process, stateId: string | null = null): Promise<void> {
|
||||||
if (process.states.length < 2) {
|
if (process.states.length < 2) {
|
||||||
throw new Error('Process doesn\'t have any state yet');
|
throw new Error("Process doesn't have any state yet");
|
||||||
}
|
}
|
||||||
let roles: Record<string, RoleDefinition> | null = null;
|
let roles: Record<string, RoleDefinition> | null = null;
|
||||||
if (!stateId) {
|
if (!stateId) {
|
||||||
@ -251,12 +266,29 @@ export default class Services {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (members.size === 0) {
|
if (members.size === 0) {
|
||||||
// This must be a pairing process
|
// This must be a pairing process
|
||||||
// Check if we have a pairedAddresses in the public data
|
// Check if we have a pairedAddresses in the public data
|
||||||
const publicData = process.states[0]?.public_data;
|
let publicData: Record<string, any> | null = null;
|
||||||
if (!publicData || !publicData['pairedAddresses']) {
|
if (!stateId) {
|
||||||
|
publicData = process.states[process.states.length - 2]?.public_data;
|
||||||
|
} else {
|
||||||
|
publicData = process.states.find(state => state.state_id === stateId)?.public_data || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If pairedAddresses is not in the current state, look in previous states
|
||||||
|
if (!publicData?.['pairedAddresses']) {
|
||||||
|
// Look for pairedAddresses in previous states
|
||||||
|
for (let i = process.states.length - 1; i >= 0; i--) {
|
||||||
|
const state = process.states[i];
|
||||||
|
if (state.public_data && state.public_data['pairedAddresses']) {
|
||||||
|
publicData = state.public_data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!publicData?.['pairedAddresses']) {
|
||||||
throw new Error('Not a pairing process');
|
throw new Error('Not a pairing process');
|
||||||
}
|
}
|
||||||
const decodedAddresses = this.decodeValue(publicData['pairedAddresses']);
|
const decodedAddresses = this.decodeValue(publicData['pairedAddresses']);
|
||||||
@ -268,15 +300,19 @@ export default class Services {
|
|||||||
|
|
||||||
// Ensure the amount is available before proceeding
|
// Ensure the amount is available before proceeding
|
||||||
await this.getTokensFromFaucet();
|
await this.getTokensFromFaucet();
|
||||||
let unconnectedAddresses = new Set<string>();
|
const unconnectedAddresses = new Set<string>();
|
||||||
const myAddress = this.getDeviceAddress();
|
const myAddress = await this.getDeviceAddress();
|
||||||
for (const member of Array.from(members)) {
|
for (const member of Array.from(members)) {
|
||||||
const sp_addresses = member.sp_addresses;
|
const sp_addresses = member.sp_addresses;
|
||||||
if (!sp_addresses || sp_addresses.length === 0) continue;
|
if (!sp_addresses || sp_addresses.length === 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (const address of sp_addresses) {
|
for (const address of sp_addresses) {
|
||||||
// For now, we ignore our own device address, although there might be use cases for having a secret with ourselves
|
// For now, we ignore our own device address, although there might be use cases for having a secret with ourselves
|
||||||
if (address === myAddress) continue;
|
if (address === myAddress) {
|
||||||
if (await this.getSecretForAddress(address) === null) {
|
continue;
|
||||||
|
}
|
||||||
|
if ((await this.getSecretForAddress(address)) === null) {
|
||||||
unconnectedAddresses.add(address);
|
unconnectedAddresses.add(address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -623,10 +659,17 @@ export default class Services {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const parsedTx = this.sdkClient.parse_new_tx(newTxMsg, 0, membersList);
|
const parsedTx = this.sdkClient.parse_new_tx(newTxMsg, 0, membersList);
|
||||||
if (parsedTx) {
|
if (parsedTx && (parsedTx.partial_tx || parsedTx.new_tx_to_send || parsedTx.secrets || parsedTx.updated_process)) {
|
||||||
try {
|
try {
|
||||||
await this.handleApiReturn(parsedTx);
|
await this.handleApiReturn(parsedTx);
|
||||||
const newDevice = this.dumpDeviceFromMemory();
|
const newDevice = this.dumpDeviceFromMemory();
|
||||||
|
|
||||||
|
// Preserve pairing_process_commitment from existing device
|
||||||
|
const existingDevice = await this.getDeviceFromDatabase();
|
||||||
|
if (existingDevice && existingDevice.pairing_process_commitment) {
|
||||||
|
newDevice.pairing_process_commitment = existingDevice.pairing_process_commitment;
|
||||||
|
}
|
||||||
|
|
||||||
await this.saveDeviceInDatabase(newDevice);
|
await this.saveDeviceInDatabase(newDevice);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to update device with new tx');
|
console.error('Failed to update device with new tx');
|
||||||
@ -639,6 +682,19 @@ export default class Services {
|
|||||||
|
|
||||||
public async handleApiReturn(apiReturn: ApiReturn) {
|
public async handleApiReturn(apiReturn: ApiReturn) {
|
||||||
console.log(apiReturn);
|
console.log(apiReturn);
|
||||||
|
|
||||||
|
// Skip processing if apiReturn is empty or contains only null values
|
||||||
|
if (!apiReturn || Object.keys(apiReturn).length === 0) {
|
||||||
|
console.log('Skipping empty apiReturn');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if all values are null
|
||||||
|
const hasValidData = Object.values(apiReturn).some(value => value !== null && value !== undefined);
|
||||||
|
if (!hasValidData) {
|
||||||
|
console.log('Skipping apiReturn with only null values');
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (apiReturn.partial_tx) {
|
if (apiReturn.partial_tx) {
|
||||||
try {
|
try {
|
||||||
const res = this.sdkClient.sign_transaction(apiReturn.partial_tx);
|
const res = this.sdkClient.sign_transaction(apiReturn.partial_tx);
|
||||||
@ -708,6 +764,21 @@ export default class Services {
|
|||||||
console.error('Failed to save diffs to db:', e);
|
console.error('Failed to save diffs to db:', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if this is a pairing process that's ready for confirmation
|
||||||
|
const existingDevice = await this.getDeviceFromDatabase();
|
||||||
|
if (existingDevice && existingDevice.pairing_process_commitment === processId) {
|
||||||
|
// This is our pairing process, check if it has paired addresses
|
||||||
|
const lastState = updatedProcess.current_process.states[updatedProcess.current_process.states.length - 1];
|
||||||
|
if (lastState && lastState.public_data && lastState.public_data['pairedAddresses']) {
|
||||||
|
console.log('Pairing process updated with paired addresses, confirming pairing...');
|
||||||
|
try {
|
||||||
|
await this.confirmPairing();
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to auto-confirm pairing:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apiReturn.push_to_storage && apiReturn.push_to_storage.length != 0) {
|
if (apiReturn.push_to_storage && apiReturn.push_to_storage.length != 0) {
|
||||||
@ -756,13 +827,100 @@ export default class Services {
|
|||||||
|
|
||||||
public async confirmPairing() {
|
public async confirmPairing() {
|
||||||
try {
|
try {
|
||||||
// Is the wasm paired?
|
// Get the pairing process ID from database
|
||||||
const pairingId = this.getPairingProcessId();
|
const existingDevice = await this.getDeviceFromDatabase();
|
||||||
// TODO confirm that the pairing process id is known, commited
|
if (!existingDevice || !existingDevice.pairing_process_commitment) {
|
||||||
|
console.error('No pairing process commitment found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pairingProcessId = existingDevice.pairing_process_commitment;
|
||||||
|
|
||||||
|
// Get the pairing process to extract paired addresses
|
||||||
|
const myPairingProcess = await this.getProcess(pairingProcessId);
|
||||||
|
if (!myPairingProcess) {
|
||||||
|
console.error('Unknown pairing process');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to get committed state first, fallback to current state
|
||||||
|
let myPairingState = this.getLastCommitedState(myPairingProcess);
|
||||||
|
if (!myPairingState && myPairingProcess.states.length > 0) {
|
||||||
|
// If no committed state, use the current state
|
||||||
|
myPairingState = myPairingProcess.states[myPairingProcess.states.length - 1];
|
||||||
|
console.log('Using current state instead of committed state');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!myPairingState) {
|
||||||
|
console.error('No state found in pairing process');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const encodedSpAddressList = myPairingState.public_data['pairedAddresses'];
|
||||||
|
if (!encodedSpAddressList) {
|
||||||
|
console.error('No paired addresses found in state');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const spAddressList = this.decodeValue(encodedSpAddressList);
|
||||||
|
if (spAddressList.length === 0) {
|
||||||
|
console.error('Empty pairedAddresses');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test parsing côté Rust
|
||||||
|
console.log('Checking if test_process_id_parsing is available:', typeof this.sdkClient.test_process_id_parsing);
|
||||||
|
try {
|
||||||
|
if (this.sdkClient.test_process_id_parsing) {
|
||||||
|
const rustParseResult = this.sdkClient.test_process_id_parsing(pairingProcessId);
|
||||||
|
console.log('Rust parsing test result:', rustParseResult);
|
||||||
|
} else {
|
||||||
|
console.error('test_process_id_parsing function not found in sdkClient');
|
||||||
|
console.log('Available functions:', Object.keys(this.sdkClient).filter(key => typeof this.sdkClient[key] === 'function'));
|
||||||
|
}
|
||||||
|
} catch (rustParseError) {
|
||||||
|
console.error('Rust parsing test failed:', rustParseError);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sdkClient.unpair_device(); // Clear any existing pairing
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.sdkClient.pair_device(pairingProcessId, spAddressList);
|
||||||
|
console.log('pair_device() call succeeded');
|
||||||
|
} catch (pairError) {
|
||||||
|
console.error('pair_device() failed:', pairError);
|
||||||
|
throw pairError;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify pairing was successful
|
||||||
|
const isPairedAfterPairing = this.sdkClient.is_paired();
|
||||||
|
console.log('Is paired after pair_device call:', isPairedAfterPairing);
|
||||||
|
|
||||||
|
// Save the updated device
|
||||||
const newDevice = this.dumpDeviceFromMemory();
|
const newDevice = this.dumpDeviceFromMemory();
|
||||||
|
console.log('Device from memory after pairing:', {
|
||||||
|
pairing_process_commitment: newDevice.pairing_process_commitment,
|
||||||
|
paired_member: newDevice.paired_member
|
||||||
|
});
|
||||||
|
|
||||||
|
// IMPORTANT: Only set pairing_process_commitment if WASM pairing succeeded
|
||||||
|
if (isPairedAfterPairing) {
|
||||||
|
console.log('WASM pairing succeeded, keeping WASM commitment');
|
||||||
|
// Don't override - use what WASM set
|
||||||
|
} else {
|
||||||
|
console.log('WASM pairing failed, manually setting commitment');
|
||||||
|
newDevice.pairing_process_commitment = pairingProcessId;
|
||||||
|
}
|
||||||
|
|
||||||
await this.saveDeviceInDatabase(newDevice);
|
await this.saveDeviceInDatabase(newDevice);
|
||||||
|
|
||||||
|
// Final verification
|
||||||
|
const finalIsPaired = this.sdkClient.is_paired();
|
||||||
|
console.log('Final is_paired status:', finalIsPaired);
|
||||||
|
console.log('Device successfully paired with process:', pairingProcessId);
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to confirm pairing');
|
console.error('Failed to confirm pairing:', e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -852,17 +1010,34 @@ export default class Services {
|
|||||||
const db = await Database.getInstance();
|
const db = await Database.getInstance();
|
||||||
const walletStore = 'wallet';
|
const walletStore = 'wallet';
|
||||||
try {
|
try {
|
||||||
|
console.log('Saving device to database:', {
|
||||||
|
pairing_process_commitment: device.pairing_process_commitment,
|
||||||
|
paired_member: device.paired_member
|
||||||
|
});
|
||||||
|
|
||||||
const prevDevice = await this.getDeviceFromDatabase();
|
const prevDevice = await this.getDeviceFromDatabase();
|
||||||
if (prevDevice) {
|
if (prevDevice) {
|
||||||
|
console.log('Previous device found, deleting...');
|
||||||
await db.deleteObject(walletStore, "1");
|
await db.deleteObject(walletStore, "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
await db.addObject({
|
await db.addObject({
|
||||||
storeName: walletStore,
|
storeName: walletStore,
|
||||||
object: { pre_id: '1', device },
|
object: { pre_id: '1', device },
|
||||||
key: null,
|
key: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log('Device saved successfully');
|
||||||
|
|
||||||
|
// Verify save
|
||||||
|
const savedDevice = await this.getDeviceFromDatabase();
|
||||||
|
console.log('Verification - saved device:', {
|
||||||
|
pairing_process_commitment: savedDevice?.pairing_process_commitment,
|
||||||
|
paired_member: savedDevice?.paired_member
|
||||||
|
});
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error('Error saving device to database:', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -152,8 +152,8 @@ export function initAddressInput() {
|
|||||||
async function onCreateButtonClick() {
|
async function onCreateButtonClick() {
|
||||||
try {
|
try {
|
||||||
await prepareAndSendPairingTx();
|
await prepareAndSendPairingTx();
|
||||||
const service = await Services.getInstance();
|
// Don't call confirmPairing immediately - it will be called when the pairing process is complete
|
||||||
await service.confirmPairing();
|
console.log('Pairing process initiated. Waiting for completion...');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`onCreateButtonClick error: ${e}`);
|
console.error(`onCreateButtonClick error: ${e}`);
|
||||||
}
|
}
|
||||||
@ -162,12 +162,6 @@ async function onCreateButtonClick() {
|
|||||||
export async function prepareAndSendPairingTx(): Promise<void> {
|
export async function prepareAndSendPairingTx(): Promise<void> {
|
||||||
const service = await Services.getInstance();
|
const service = await Services.getInstance();
|
||||||
|
|
||||||
try {
|
|
||||||
await service.checkConnections([]);
|
|
||||||
} catch (e) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const relayAddress = service.getAllRelays();
|
const relayAddress = service.getAllRelays();
|
||||||
const createPairingProcessReturn = await service.createPairingProcess(
|
const createPairingProcessReturn = await service.createPairingProcess(
|
||||||
@ -179,9 +173,26 @@ export async function prepareAndSendPairingTx(): Promise<void> {
|
|||||||
throw new Error('createPairingProcess returned an empty new process');
|
throw new Error('createPairingProcess returned an empty new process');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await service.checkConnections(createPairingProcessReturn.updated_process.current_process, createPairingProcessReturn.updated_process.current_process.states[0].state_id);
|
||||||
|
} catch (e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
service.setProcessId(createPairingProcessReturn.updated_process.process_id);
|
service.setProcessId(createPairingProcessReturn.updated_process.process_id);
|
||||||
service.setStateId(createPairingProcessReturn.updated_process.current_process.states[0].state_id);
|
service.setStateId(createPairingProcessReturn.updated_process.current_process.states[0].state_id);
|
||||||
|
|
||||||
|
// Update device.pairing_process_commitment with the process_id
|
||||||
|
try {
|
||||||
|
const currentDevice = await service.getDeviceFromDatabase();
|
||||||
|
if (currentDevice) {
|
||||||
|
currentDevice.pairing_process_commitment = createPairingProcessReturn.updated_process.process_id;
|
||||||
|
await service.saveDeviceInDatabase(currentDevice);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to update device pairing_process_commitment:', err);
|
||||||
|
}
|
||||||
|
|
||||||
await service.handleApiReturn(createPairingProcessReturn);
|
await service.handleApiReturn(createPairingProcessReturn);
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user