diff --git a/src/router.ts b/src/router.ts index a750915..33b655a 100755 --- a/src/router.ts +++ b/src/router.ts @@ -156,13 +156,15 @@ export async function init(): Promise { // We connect to all relays now await services.connectAllRelays(); + await services.updateDeviceBlockHeight(); + // We register all the event listeners if we run in an iframe if (window.self !== window.top) { await registerAllListeners(); } if (services.isPaired()) { - await navigate('account'); + await navigate('process'); } else { await navigate('home'); } diff --git a/src/services/service.ts b/src/services/service.ts index 8bef331..03beb9a 100755 --- a/src/services/service.ts +++ b/src/services/service.ts @@ -1,7 +1,7 @@ import { INotification } from '~/models/notification.model'; import { IProcess } from '~/models/process.model'; import { initWebsocket, sendMessage } from '../websockets'; -import { ApiReturn, Device, HandshakeMessage, Member, MerkleProofResult, OutPointProcessMap, Process, ProcessState, RoleDefinition, SecretsStore, UserDiff } from '../../pkg/sdk_client'; +import { ApiReturn, Device, HandshakeMessage, Member, MerkleProofResult, NewTxMessage, OutPointProcessMap, Process, ProcessState, RoleDefinition, SecretsStore, UserDiff } from '../../pkg/sdk_client'; import ModalService from './modal.service'; import Database from './database.service'; import { navigate } from '../router'; @@ -10,9 +10,10 @@ import { BackUp } from '~/models/backup.model'; export const U32_MAX = 4294967295; -const BASEURL = `https://demo.4nkweb.com`; -const BOOTSTRAPURL = [`${BASEURL}/ws/`]; -const STORAGEURL = `${BASEURL}/storage` +const BASEURL = `http://localhost`; +const BOOTSTRAPURL = [`${BASEURL}:8090`]; +const STORAGEURL = `${BASEURL}:8081` +const BLINDBITURL = `${BASEURL}:8000` const DEFAULTAMOUNT = 1000n; const EMPTY32BYTES = String('').padStart(64, '0'); @@ -30,6 +31,7 @@ export default class Services { private routingInstance!: ModalService; private relayAddresses: { [wsurl: string]: string } = {}; private membersList: Record = {}; + private currentBlockHeight: number = -1; // Private constructor to prevent direct instantiation from outside private constructor() {} @@ -559,7 +561,7 @@ export default class Services { const newTip = this.sdkClient.get_txid(parsedMsg.transaction); console.log('Transaction', newTip, 'spends the tip of process', processId); // We take the data out of the output - const newStateId = this.sdkClient.get_new_state_id(parsedMsg.transaction); + const newStateId = this.sdkClient.get_opreturn(parsedMsg.transaction); console.log('newStateId:', newStateId); // We update the relevant process const updatedProcess = this.sdkClient.process_commit_new_state(process, newStateId, newTip); @@ -573,7 +575,7 @@ export default class Services { } try { - const parsedTx = this.sdkClient.parse_new_tx(parsedMsg.transaction, 0, membersList); + const parsedTx = this.sdkClient.parse_new_tx(newTxMsg, 0, membersList); if (parsedTx) { try { await this.handleApiReturn(parsedTx); @@ -933,6 +935,7 @@ export default class Services { async createNewDevice() { let spAddress = ''; try { + // We set birthday later when we have the chain tip from relay spAddress = await this.sdkClient.create_new_device(0, 'signet'); const device = this.dumpDeviceFromMemory(); await this.saveDeviceInDatabase(device); @@ -951,6 +954,61 @@ export default class Services { } } + public async updateDeviceBlockHeight(): Promise { + if (this.currentBlockHeight === -1) { + throw new Error('Current block height not set'); + } + + let device: Device | null = null; + try { + device = await this.getDeviceFromDatabase(); + } catch (e) { + throw new Error(`Failed to get device from database: ${e}`); + } + + if (!device) { + throw new Error('Device not found'); + } + + const birthday = device.sp_wallet.birthday; + if (birthday === undefined || birthday === null) { + throw new Error('Birthday not found'); + } + + if (birthday === 0) { + // This is a new device, so current chain tip is its birthday + device.sp_wallet.birthday = this.currentBlockHeight; + // We also set last_scan, impossible that we need to scan earlier than this + device.sp_wallet.last_scan = this.currentBlockHeight; + try { + // First set the updated device in memory + this.sdkClient.restore_device(device); + // Then save it to database + await this.saveDeviceInDatabase(device); + } catch (e) { + throw new Error(`Failed to save updated device: ${e}`); + } + } else { + // For testing, set last_scan and birthday a few blocks ago + device.sp_wallet.last_scan = this.currentBlockHeight - 10; + device.sp_wallet.birthday = this.currentBlockHeight - 10; + try { + this.sdkClient.restore_device(device); + } catch (e) { + throw new Error(`Failed to restore device: ${e}`); + } + await this.saveDeviceInDatabase(device); + // 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) { + // We need to catch up + await this.sdkClient.scan_blocks(this.currentBlockHeight, BLINDBITURL); + } else { + // Up to date, just returns + return; + } + } + } + private async removeProcess(processId: string): Promise { const db = await Database.getInstance(); const storeName = 'processes'; @@ -1321,6 +1379,7 @@ export default class Services { try { const handshakeMsg: HandshakeMessage = JSON.parse(parsedMsg); this.updateRelay(url, handshakeMsg.sp_address); + this.currentBlockHeight = handshakeMsg.chain_tip; if (this.membersList && Object.keys(this.membersList).length === 0) { // We start from an empty list, just copy it over this.membersList = handshakeMsg.peers_list;