diff --git a/electron/ipcHandlers.ts b/electron/ipcHandlers.ts index 3f17a12..4ea0842 100644 --- a/electron/ipcHandlers.ts +++ b/electron/ipcHandlers.ts @@ -80,13 +80,95 @@ ipcMain.handle('wallet:checkKeystore', async () => { if (!newestFile) return { exists: false, filePath: null } - return { exists: true, filePath: path.join(walletDir, newestFile) } + const resolvedPath = path.join(walletDir, newestFile) + let minBlockHeight: number | null = null + + try { + const json = fs.readFileSync(resolvedPath, 'utf-8') + const data = JSON.parse(json) + const height = data?.minBlockHeight + + if (typeof height === 'number' && Number.isFinite(height)) { + minBlockHeight = height + } + } catch (error) { + console.warn('Unable to read minBlockHeight from keystore:', error) + } + + return { exists: true, filePath: resolvedPath, minBlockHeight } } catch (error) { console.error('Error checking keystore ipc:', error) - return { exists: false, filePath: null, error: String(error) } + return { exists: false, filePath: null, minBlockHeight: null, error: String(error) } } }) +ipcMain.handle( + 'wallet:updateMinBlockHeight', + async (_event, filePath: string | null, minBlockHeight: number | null) => { + if (!filePath) { + return { success: false, error: 'No keystore file path provided.' } + } + + try { + const normalizedPath = path.isAbsolute(filePath) + ? filePath + : path.join(process.cwd(), filePath) + + if (!fs.existsSync(normalizedPath)) { + return { success: false, error: 'Keystore file not found.' } + } + + const fileContents = fs.readFileSync(normalizedPath, 'utf-8') + const walletJson = JSON.parse(fileContents) + + if (minBlockHeight === null || Number.isNaN(minBlockHeight)) { + walletJson.minBlockHeight = null + } else { + walletJson.minBlockHeight = minBlockHeight + } + + fs.writeFileSync(normalizedPath, JSON.stringify(walletJson, null, 2), 'utf-8') + + return { success: true, minBlockHeight } + } catch (error) { + console.error('Error updating min block height:', error) + return { success: false, error: String(error) } + } + } +) + +ipcMain.handle( + 'wallet:getMinBlockHeight', + async (_event, filePath: string | null) => { + if (!filePath) { + return { success: false, error: 'No keystore file path provided.', minBlockHeight: null } + } + + try { + const normalizedPath = path.isAbsolute(filePath) + ? filePath + : path.join(process.cwd(), filePath) + + if (!fs.existsSync(normalizedPath)) { + return { success: false, error: 'Keystore file not found.', minBlockHeight: null } + } + + const fileContents = fs.readFileSync(normalizedPath, 'utf-8') + const walletJson = JSON.parse(fileContents) + const height = walletJson?.minBlockHeight + + if (typeof height === 'number' && Number.isFinite(height)) { + return { success: true, minBlockHeight: height } + } + + return { success: true, minBlockHeight: null } + } catch (error) { + console.error('Error reading min block height:', error) + return { success: false, error: String(error), minBlockHeight: null } + } + } +) + ipcMain.handle('wallet:generateKeysFromSeed', async (_event, seedPhrase: string[]) => { try { const wallet = new neptuneNative.WalletManager() @@ -97,15 +179,19 @@ ipcMain.handle('wallet:generateKeysFromSeed', async (_event, seedPhrase: string[ } }) -ipcMain.handle('wallet:buildTransactionWithPrimitiveProof', async (_event, args) => { +ipcMain.handle('wallet:buildTransaction', async (_event, args) => { const { spendingKeyHex, inputAdditionRecords, outputAddresses, outputAmounts, fee } = args try { const builder = new neptuneNative.SimpleTransactionBuilder() - const result = await builder.buildTransactionWithPrimitiveProof( + const result = await builder.buildTransaction( import.meta.env.VITE_APP_API, spendingKeyHex, inputAdditionRecords, + // pass minBlockHeight from args if provided, default 0 + typeof args?.minBlockHeight === 'number' && Number.isFinite(args.minBlockHeight) + ? args.minBlockHeight + : 0, outputAddresses, outputAmounts, fee diff --git a/electron/preload.ts b/electron/preload.ts index 4b791e0..817977c 100644 --- a/electron/preload.ts +++ b/electron/preload.ts @@ -12,6 +12,9 @@ contextBridge.exposeInMainWorld('walletApi', { checkKeystore: () => ipcRenderer.invoke('wallet:checkKeystore'), generateKeysFromSeed: (seedPhrase: string[]) => ipcRenderer.invoke('wallet:generateKeysFromSeed', seedPhrase), - buildTransactionWithPrimitiveProof: (args: any) => - ipcRenderer.invoke('wallet:buildTransactionWithPrimitiveProof', args), + buildTransaction: (args: any) => ipcRenderer.invoke('wallet:buildTransaction', args), + updateMinBlockHeight: (filePath: string | null, minBlockHeight: number | null) => + ipcRenderer.invoke('wallet:updateMinBlockHeight', filePath, minBlockHeight), + getMinBlockHeight: (filePath: string | null) => + ipcRenderer.invoke('wallet:getMinBlockHeight', filePath), }) diff --git a/electron/utils/keystore.ts b/electron/utils/keystore.ts index ec17d98..aef9d3e 100644 --- a/electron/utils/keystore.ts +++ b/electron/utils/keystore.ts @@ -4,7 +4,6 @@ export async function encrypt(seed: string, password: string) { const salt = crypto.randomBytes(16) const iv = crypto.randomBytes(12) - // derive 32-byte key từ password const key = await new Promise((resolve, reject) => { crypto.scrypt(password, salt, 32, { N: 16384, r: 8, p: 1 }, (err, derivedKey) => { if (err) reject(err) diff --git a/env.d.ts b/env.d.ts index d687c0a..7d16d80 100644 --- a/env.d.ts +++ b/env.d.ts @@ -2,3 +2,12 @@ declare const MAIN_WINDOW_VITE_DEV_SERVER_URL: string | undefined; declare const MAIN_WINDOW_VITE_NAME: string | undefined; + +interface ImportMetaEnv { + readonly VITE_APP_API: string + readonly VITE_NODE_NETWORK?: 'mainnet' | 'testnet' +} + +interface ImportMeta { + readonly env: ImportMetaEnv +} diff --git a/packages/neptune-native-0.1.0.tgz b/packages/neptune-native-0.1.0.tgz deleted file mode 100644 index 7089c75..0000000 Binary files a/packages/neptune-native-0.1.0.tgz and /dev/null differ diff --git a/packages/neptune-native/index.d.ts b/packages/neptune-native/index.d.ts index a5d663b..c59ff10 100644 --- a/packages/neptune-native/index.d.ts +++ b/packages/neptune-native/index.d.ts @@ -3,12 +3,9 @@ /* auto-generated by NAPI-RS */ -/** Module initialization */ export declare function initNativeModule(): string -/** Quick VM test (can call immediately) */ export declare function quickVmTest(): string export declare function getVersion(): string -/** Wallet manager for key generation and transaction signing */ export declare class WalletManager { constructor() /** @@ -64,7 +61,7 @@ export declare class WalletManager { getStateCall(rpcUrl: string): Promise /** Call mempool_submitTransaction to broadcast a pre-built transaction */ submitTransactionCall(rpcUrl: string, transactionHex: string): Promise - getUtxosFromViewKeyCall(rpcUrl: string, viewKeyHex: string, startBlock: number, endBlock: number, maxSearchDepth?: number | undefined | null): Promise + getUtxosFromViewKeyCall(rpcUrl: string, viewKeyHex: string, startBlock: number, maxSearchDepth?: number | undefined | null): Promise getArchivalMutatorSet(rpcUrl: string): Promise /** * Build JSON-RPC request to find the canonical block that created a UTXO (by addition_record) @@ -78,5 +75,5 @@ export declare class WalletManager { } export declare class SimpleTransactionBuilder { constructor() - buildTransactionWithPrimitiveProof(rpcUrl: string, spendingKeyHex: string, inputAdditionRecords: Array, outputAddresses: Array, outputAmounts: Array, fee: string): Promise + buildTransaction(rpcUrl: string, spendingKeyHex: string, inputAdditionRecords: Array, minBlockHeight: number, outputAddresses: Array, outputAmounts: Array, fee: string): Promise } diff --git a/packages/neptune-native/neptune-native.darwin-arm64.node b/packages/neptune-native/neptune-native.darwin-arm64.node new file mode 100755 index 0000000..46809d2 Binary files /dev/null and b/packages/neptune-native/neptune-native.darwin-arm64.node differ diff --git a/packages/neptune-native/neptune-native.linux-x64-gnu.node b/packages/neptune-native/neptune-native.linux-x64-gnu.node new file mode 100755 index 0000000..8906209 Binary files /dev/null and b/packages/neptune-native/neptune-native.linux-x64-gnu.node differ diff --git a/packages/neptune-native/neptune-native.win32-x64-msvc.node b/packages/neptune-native/neptune-native.win32-x64-msvc.node index 2ec83cf..c6188c4 100644 Binary files a/packages/neptune-native/neptune-native.win32-x64-msvc.node and b/packages/neptune-native/neptune-native.win32-x64-msvc.node differ diff --git a/src/App.vue b/src/App.vue index a06885c..66a2a72 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,6 +1,4 @@