Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sharing Window among other module components #2490

Merged
merged 1 commit into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion packages/main/src/App.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@ import {platform} from 'node:process';
import updater from 'electron-updater';

import Window from './modules/UI/Window';
import Game from './modules/Game/Game';
import Keystore from './modules/Keystore/Keystore';
import Remote from './modules/Remote/Remote';

export default class App {
window: Window;
private window!: Window;
private game!: Game;
private keystore!: Keystore;
private remote!: Remote;
// Module Components are initialized in ready, if not. app must print error
constructor() {
/**
* Prevent electron from running multiple instances.
Expand All @@ -32,7 +39,11 @@ export default class App {
this.window.restoreOrCreateWindow();
} catch (e) {
console.error('Failed create window:', e);
//display dialog failed to create window
}
this.game = new Game(this.window.window);
this.keystore = new Keystore(this.window.window);
this.remote = new Remote(this.window.window);
};

private windowAllClosed = (): void => {
Expand Down
3 changes: 1 addition & 2 deletions packages/main/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import App from './App.js';
import Window from './modules/UI/Window.js';
import App from './App';

new App();
76 changes: 32 additions & 44 deletions packages/main/src/modules/Keystore/Keystore.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,32 @@
import {
Address,
ExportableAccount,
PublicKey,
RawPrivateKey,
} from "@planetarium/account";
import {Address, ExportableAccount, PublicKey, RawPrivateKey} from '@planetarium/account';
import {
KeyId,
PassphraseEntry,
Web3Account,
Web3KeyStore,
} from "@planetarium/account-web3-secret-storage";
import fs from "fs";
import path from "path";
import { getKeyStorePath } from "src/constants/os";
} from '@planetarium/account-web3-secret-storage';
import fs from 'fs';
import path from 'path';
import {getKeyStorePath} from '/@/constants/os';
import {BrowserWindow} from 'electron/main';

export interface ILoginSession {
address: Address;
publicKey: PublicKey;
privateKey: RawPrivateKey;
}

export default class Account {
export default class Keystore {
private _hasLoginSession: boolean = false;
private _addresses: Address[] = [];
private _account: ExportableAccount | null = null;
private _window: BrowserWindow;
public loginSession: ILoginSession | null = null;
public isKeystoreInitialized: boolean = false;

constructor() {
this.getKeyStore(undefined).then(async (keyStore) => {
constructor(window: BrowserWindow) {
this._window = window;
this.getKeyStore(undefined).then(async keyStore => {
for await (const keyMetadata of keyStore.list()) {
const address = keyMetadata.metadata.address;
if (address == null) continue;
Expand All @@ -38,17 +36,15 @@ export default class Account {
});
}

private async getKeyStore(
passphrase: string | undefined,
): Promise<Web3KeyStore> {
private async getKeyStore(passphrase: string | undefined): Promise<Web3KeyStore> {
const passphraseEntry: PassphraseEntry = {
authenticate(keyId: string, firstAttempt: boolean): Promise<string> {
if (passphrase === undefined) throw new Error("No passphrase given.");
if (passphrase === undefined) throw new Error('No passphrase given.');
if (firstAttempt) return Promise.resolve(passphrase);
throw new Error("Incorrect passphrase.");
throw new Error('Incorrect passphrase.');
},
configurePassphrase(): Promise<string> {
if (passphrase === undefined) throw new Error("No passphrase given.");
if (passphrase === undefined) throw new Error('No passphrase given.');
return Promise.resolve(passphrase);
},
};
Expand All @@ -67,8 +63,8 @@ export default class Account {
if (keyId == null) return undefined;
const keyStore = await this.getKeyStore(passphrase);
const result = await keyStore.get(keyId);
if (result.result === "keyNotFound") return undefined;
else if (result.result === "error") {
if (result.result === 'keyNotFound') return undefined;
else if (result.result === 'error') {
console.error(result.message);
return undefined;
}
Expand All @@ -78,7 +74,7 @@ export default class Account {
public async login() {
try {
if (this._account == null) {
throw new Error("Account not found.");
throw new Error('Account not found.');
}
const privateKey = await this._account.exportPrivateKey();
const publicKey = await this._account.getPublicKey();
Expand All @@ -90,14 +86,12 @@ export default class Account {
address,
};
} catch (error) {
console.error("Login failed:", error);
console.error('Login failed:', error);
}
}

public findKeyIdByAddress = async (
address: string | Address,
): Promise<KeyId | undefined> => {
if (typeof address === "string") {
public findKeyIdByAddress = async (address: string | Address): Promise<KeyId | undefined> => {
if (typeof address === 'string') {
try {
address = Address.fromHex(address, true);
} catch (e) {
Expand All @@ -117,7 +111,7 @@ export default class Account {
if (keyId != null) {
const keyStore = await this.getKeyStore(undefined);
await keyStore.delete(keyId);
this._addresses = this._addresses.filter((a) => !a.equals(address));
this._addresses = this._addresses.filter(a => !a.equals(address));
}
};

Expand All @@ -129,20 +123,16 @@ export default class Account {
): Promise<Web3Account> => {
const keyStore = await this.getKeyStore(passphrase);
const privateKey =
typeof privateKeyHex === "string"
? RawPrivateKey.fromHex(privateKeyHex)
: privateKeyHex;
typeof privateKeyHex === 'string' ? RawPrivateKey.fromHex(privateKeyHex) : privateKeyHex;
const result = await keyStore.import(privateKey);
if (result.result === "error") {
if (result.result === 'error') {
throw new Error(result.message);
}
const account = await keyStore.get(result.keyId);
if (account.result !== "success") {
if (account.result !== 'success') {
// Must be unreachable
throw new Error(
account.result === "error"
? account.message
: "Key not found; something went wrong",
account.result === 'error' ? account.message : 'Key not found; something went wrong',
);
}
this._addresses.push(await account.account.getAddress());
Expand All @@ -155,26 +145,24 @@ export default class Account {
const keyId = await this.findKeyIdByAddress(address);
const dir = await getKeyStorePath();
try {
if (typeof keyId !== "string") {
throw Error("Failed to get keyId from address");
if (typeof keyId !== 'string') {
throw Error('Failed to get keyId from address');
}
const files = await fs.promises.readdir(dir);

for (const file of files) {
if (file.includes(keyId)) {
const filePath = path.join(dir, file);
const data = JSON.stringify(
JSON.parse(await fs.promises.readFile(filePath, "ascii")),
); // parse -> stringify trip to minimize.
const data = JSON.stringify(JSON.parse(await fs.promises.readFile(filePath, 'ascii'))); // parse -> stringify trip to minimize.
return data;
}
}
throw Error("No matching keyFile exists in keystore.");
throw Error('No matching keyFile exists in keystore.');
} catch (err) {
console.error("Failed to load Web3 Secret Storage: ", err);
console.error('Failed to load Web3 Secret Storage: ', err);
}
} else {
console.error("Not logged in.");
console.error('Not logged in.');
}
};

Expand Down
6 changes: 4 additions & 2 deletions packages/main/src/modules/Remote/Remote.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import {z} from 'zod';
import {PLANET_REGISTRY} from '/@/constants';
import {Planet, PlanetArraySchema} from '/@/types/registry';
import { BrowserWindow } from 'electron';

export default class Remote {
private _planetRegistry: Planet[] | null = null;
private _isChangingPlanet: boolean = false;
private _window: BrowserWindow;

constructor() {
this.init();
constructor(window: BrowserWindow) {
this._window = window;
this.registerEvents();
// isOnline Tracker
}
Expand Down
10 changes: 5 additions & 5 deletions packages/main/src/modules/UI/Window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import {join} from 'node:path';
import {fileURLToPath} from 'node:url';

export default class Window {
private window!: BrowserWindow;
public window!: BrowserWindow;

constructor() {}

private async createWindow() {
private createWindow() {
this.window = new BrowserWindow({
show: false, // Use the 'ready-to-show' event to show the instantiated BrowserWindow.
webPreferences: {
Expand All @@ -28,7 +28,7 @@ export default class Window {
/**
* Load from the Vite dev server for development.
*/
await this.window.loadURL(import.meta.env.VITE_DEV_SERVER_URL);
this.window.loadURL(import.meta.env.VITE_DEV_SERVER_URL);
} else {
/**
* Load from the local file system for production and test.
Expand All @@ -39,15 +39,15 @@ export default class Window {
* @see https://github.com/nodejs/node/issues/12682
* @see https://github.com/electron/electron/issues/6869
*/
await this.window.loadFile(
this.window.loadFile(
fileURLToPath(new URL('./../../renderer/dist/index.html', import.meta.url)),
);
}
}
/**
* Restore an existing BrowserWindow or Create a new BrowserWindow.
*/
public async restoreOrCreateWindow() {
public restoreOrCreateWindow() {
const window = BrowserWindow.getAllWindows().find(w => !w.isDestroyed());

if (window === undefined) {
Expand Down
Loading