feat: 111125/logger
This commit is contained in:
parent
80babfd455
commit
cb67afb1a5
@ -2,6 +2,7 @@ import { ipcMain, dialog, app } from 'electron'
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { encrypt, fromEncryptedJson } from './utils/keystore'
|
||||
import logger from './logger'
|
||||
|
||||
const neptuneNative = require('@neptune/native')
|
||||
|
||||
@ -13,15 +14,14 @@ ipcMain.handle('wallet:createKeystore', async (_event, seed, password) => {
|
||||
const savePath = path.join(process.cwd(), 'wallets')
|
||||
fs.mkdirSync(savePath, { recursive: true })
|
||||
|
||||
// Use timestamp for filename
|
||||
const timestamp = Date.now()
|
||||
const fileName = `neptune-wallet-${timestamp}.json`
|
||||
const filePath = path.join(savePath, fileName)
|
||||
fs.writeFileSync(filePath, keystore)
|
||||
|
||||
return { filePath }
|
||||
} catch (error) {
|
||||
console.error('Error creating keystore:', error)
|
||||
} catch (error: any) {
|
||||
logger.error('Error creating keystore:', error.message)
|
||||
throw error
|
||||
}
|
||||
})
|
||||
@ -46,8 +46,8 @@ ipcMain.handle('wallet:saveKeystoreAs', async (_event, seed: string, password: s
|
||||
fs.writeFileSync(filePath, keystore)
|
||||
|
||||
return { filePath }
|
||||
} catch (error) {
|
||||
console.error('Error saving keystore (Save As):', error)
|
||||
} catch (error: any) {
|
||||
logger.error('Error saving keystore (Save As):', error.message)
|
||||
throw error
|
||||
}
|
||||
})
|
||||
@ -58,8 +58,8 @@ ipcMain.handle('wallet:decryptKeystore', async (_event, filePath, password) => {
|
||||
const phrase = await fromEncryptedJson(json, password)
|
||||
|
||||
return { phrase }
|
||||
} catch (error) {
|
||||
console.error('Error decrypting keystore ipc:', error)
|
||||
} catch (error: any) {
|
||||
logger.error('Error decrypting keystore ipc:', error.message)
|
||||
throw error
|
||||
}
|
||||
})
|
||||
@ -91,14 +91,14 @@ ipcMain.handle('wallet:checkKeystore', async () => {
|
||||
if (typeof height === 'number' && Number.isFinite(height)) {
|
||||
minBlockHeight = height
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Unable to read minBlockHeight from keystore:', error)
|
||||
} catch (error: any) {
|
||||
logger.warn('Unable to read minBlockHeight from keystore:', error.message)
|
||||
}
|
||||
|
||||
return { exists: true, filePath: resolvedPath, minBlockHeight }
|
||||
} catch (error) {
|
||||
console.error('Error checking keystore ipc:', error)
|
||||
return { exists: false, filePath: null, minBlockHeight: null, error: String(error) }
|
||||
} catch (error: any) {
|
||||
logger.error('Error checking keystore ipc:', error.message)
|
||||
return { exists: false, filePath: null, minBlockHeight: null, error: error.message }
|
||||
}
|
||||
})
|
||||
|
||||
@ -130,9 +130,9 @@ ipcMain.handle(
|
||||
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) }
|
||||
} catch (error: any) {
|
||||
logger.error('Error updating min block height:', error.message)
|
||||
return { success: false, error: error.message }
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -162,9 +162,9 @@ ipcMain.handle(
|
||||
}
|
||||
|
||||
return { success: true, minBlockHeight: null }
|
||||
} catch (error) {
|
||||
console.error('Error reading min block height:', error)
|
||||
return { success: false, error: String(error), minBlockHeight: null }
|
||||
} catch (error: any) {
|
||||
logger.error('Error reading min block height:', error.message)
|
||||
return { success: false, error: error.message, minBlockHeight: null }
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -173,8 +173,8 @@ ipcMain.handle('wallet:generateKeysFromSeed', async (_event, seedPhrase: string[
|
||||
try {
|
||||
const wallet = new neptuneNative.WalletManager()
|
||||
return wallet.generateKeysFromSeed(seedPhrase)
|
||||
} catch (error) {
|
||||
console.error('Error generating keys from seed ipc:', error)
|
||||
} catch (error: any) {
|
||||
logger.error('Error generating keys from seed ipc:', error.message)
|
||||
throw error
|
||||
}
|
||||
})
|
||||
@ -188,7 +188,6 @@ ipcMain.handle('wallet:buildTransaction', async (_event, args) => {
|
||||
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,
|
||||
@ -197,8 +196,12 @@ ipcMain.handle('wallet:buildTransaction', async (_event, args) => {
|
||||
fee
|
||||
)
|
||||
return JSON.parse(result)
|
||||
} catch (error) {
|
||||
console.error('Error building transaction with primitive proof ipc:', error)
|
||||
} catch (error: any) {
|
||||
logger.error('Error building transaction with primitive proof ipc:', error.message)
|
||||
throw error
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('log:info', (_, msg: string) => logger.info(msg))
|
||||
ipcMain.on('log:warn', (_, msg: string) => logger.warn(msg))
|
||||
ipcMain.on('log:error', (_, msg: string) => logger.error(msg))
|
||||
|
||||
33
electron/logger.ts
Normal file
33
electron/logger.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { app } from 'electron'
|
||||
import log from 'electron-log'
|
||||
|
||||
const isDev = app.isPackaged
|
||||
|
||||
console.log('isDev :>> ', isDev);
|
||||
|
||||
if (!isDev) {
|
||||
log.transports.file.level = 'info'
|
||||
log.transports.console.level = false
|
||||
log.transports.file.format = '{y}-{m}-{d} {h}:{i}:{s} [{level}] {text}'
|
||||
}
|
||||
|
||||
export const logger = {
|
||||
info: (...args: any[]) => {
|
||||
if (isDev) console.log('[INFO]', ...args)
|
||||
else log.info(...args)
|
||||
},
|
||||
warn: (...args: any[]) => {
|
||||
if (isDev) console.warn('[WARN]', ...args)
|
||||
else log.warn(...args)
|
||||
},
|
||||
error: (...args: any[]) => {
|
||||
if (isDev) console.error('[ERROR]', ...args)
|
||||
else log.error(...args)
|
||||
},
|
||||
debug: (...args: any[]) => {
|
||||
if (isDev) console.debug('[DEBUG]', ...args)
|
||||
else log.debug(...args)
|
||||
},
|
||||
}
|
||||
|
||||
export default logger
|
||||
@ -2,12 +2,14 @@ import { app, BrowserWindow } from 'electron'
|
||||
import path from 'node:path'
|
||||
import started from 'electron-squirrel-startup'
|
||||
import './ipcHandlers'
|
||||
import logger from './logger'
|
||||
|
||||
if (started) {
|
||||
app.quit()
|
||||
}
|
||||
|
||||
const createWindow = () => {
|
||||
logger.info('App started')
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 800,
|
||||
@ -38,6 +40,7 @@ app.on('ready', createWindow)
|
||||
// for applications and their menu bar to stay active until the user quits
|
||||
// explicitly with Cmd + Q.
|
||||
app.on('window-all-closed', () => {
|
||||
logger.info('App closed')
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
|
||||
@ -18,3 +18,9 @@ contextBridge.exposeInMainWorld('walletApi', {
|
||||
getMinBlockHeight: (filePath: string | null) =>
|
||||
ipcRenderer.invoke('wallet:getMinBlockHeight', filePath),
|
||||
})
|
||||
|
||||
contextBridge.exposeInMainWorld('logger', {
|
||||
info: (msg: string) => ipcRenderer.send('log:info', msg),
|
||||
warn: (msg: string) => ipcRenderer.send('log:warn', msg),
|
||||
error: (msg: string) => ipcRenderer.send('log:error', msg),
|
||||
})
|
||||
|
||||
10
package-lock.json
generated
10
package-lock.json
generated
@ -16,6 +16,7 @@
|
||||
"ant-design-vue": "^4.2.6",
|
||||
"axios": "^1.6.8",
|
||||
"crypto": "^1.0.1",
|
||||
"electron-log": "^5.4.3",
|
||||
"electron-squirrel-startup": "^1.0.1",
|
||||
"pinia": "^2.1.7",
|
||||
"vue": "^3.4.21",
|
||||
@ -5807,6 +5808,15 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-log": {
|
||||
"version": "5.4.3",
|
||||
"resolved": "https://registry.npmjs.org/electron-log/-/electron-log-5.4.3.tgz",
|
||||
"integrity": "sha512-sOUsM3LjZdugatazSQ/XTyNcw8dfvH1SYhXWiJyfYodAAKOZdHs0txPiLDXFzOZbhXgAgshQkshH2ccq0feyLQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-squirrel-startup": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/electron-squirrel-startup/-/electron-squirrel-startup-1.0.1.tgz",
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
"ant-design-vue": "^4.2.6",
|
||||
"axios": "^1.6.8",
|
||||
"crypto": "^1.0.1",
|
||||
"electron-log": "^5.4.3",
|
||||
"electron-squirrel-startup": "^1.0.1",
|
||||
"pinia": "^2.1.7",
|
||||
"vue": "^3.4.21",
|
||||
|
||||
@ -30,11 +30,10 @@ export function useNeptuneWallet() {
|
||||
await initWasm()
|
||||
|
||||
wasmInitialized = true
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
wasmInitialized = false
|
||||
const errorMsg = 'Failed to initialize Neptune WASM'
|
||||
console.error('WASM init error:', err)
|
||||
throw new Error(errorMsg)
|
||||
await (window as any).logger.error('WASM init error:', err.message)
|
||||
throw new Error('Failed to initialize Neptune WASM')
|
||||
}
|
||||
})()
|
||||
|
||||
@ -59,8 +58,8 @@ export function useNeptuneWallet() {
|
||||
store.setAddress(addressResult)
|
||||
|
||||
return result
|
||||
} catch (err) {
|
||||
console.error('Error generating wallet:', err)
|
||||
} catch (err: any) {
|
||||
await (window as any).logger.error('Error generating wallet:', err.message)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@ -93,8 +92,8 @@ export function useNeptuneWallet() {
|
||||
spendingKey: result.spending_key_hex,
|
||||
address: addressResult,
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error recovering wallet from seed:', err)
|
||||
} catch (err: any) {
|
||||
await (window as any).logger.error('Error recovering wallet from seed:', err.message)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@ -128,14 +127,14 @@ export function useNeptuneWallet() {
|
||||
store.setAddress(addressResult)
|
||||
|
||||
await loadMinBlockHeightFromKeystore()
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
if (
|
||||
err instanceof Error &&
|
||||
(err.message.includes('Unsupported state') ||
|
||||
err.message.includes('unable to authenticate'))
|
||||
) {
|
||||
console.error('Invalid password')
|
||||
} else console.error('Error decrypting keystore:', err)
|
||||
await (window as any).logger.error('Invalid password')
|
||||
} else await (window as any).logger.error('Error decrypting keystore:', err.message)
|
||||
|
||||
throw err
|
||||
}
|
||||
@ -147,8 +146,8 @@ export function useNeptuneWallet() {
|
||||
store.setKeystorePath(result.filePath)
|
||||
store.setMinBlockHeight(null)
|
||||
return result.filePath
|
||||
} catch (err) {
|
||||
console.error('Error creating keystore:', err)
|
||||
} catch (err: any) {
|
||||
await (window as any).logger.error('Error creating keystore:', err.message)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@ -158,8 +157,8 @@ export function useNeptuneWallet() {
|
||||
const result = await (window as any).walletApi.saveKeystoreAs(seed, password)
|
||||
if (!result.filePath) throw new Error('User canceled')
|
||||
return result.filePath
|
||||
} catch (err) {
|
||||
console.error('Error saving keystore:', err)
|
||||
} catch (err: any) {
|
||||
await (window as any).logger.error('Error saving keystore:', err.message)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@ -175,8 +174,8 @@ export function useNeptuneWallet() {
|
||||
store.setMinBlockHeight(toFiniteNumber(height))
|
||||
}
|
||||
return true
|
||||
} catch (err) {
|
||||
console.error('Error checking keystore:', err)
|
||||
} catch (err: any) {
|
||||
await (window as any).logger.error('Error checking keystore:', err.message)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@ -202,8 +201,8 @@ export function useNeptuneWallet() {
|
||||
)
|
||||
if (!response.success) throw new Error('Failed to update min block height')
|
||||
store.setMinBlockHeight(minBlockHeight)
|
||||
} catch (err) {
|
||||
console.error('Error saving min block height:', err)
|
||||
} catch (err: any) {
|
||||
await (window as any).logger.error('Error saving min block height:', err.message)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@ -220,8 +219,8 @@ export function useNeptuneWallet() {
|
||||
|
||||
store.setMinBlockHeight(minBlockHeight)
|
||||
return minBlockHeight
|
||||
} catch (err) {
|
||||
console.error('Error loading min block height:', err)
|
||||
} catch (err: any) {
|
||||
await (window as any).logger.error('Error loading min block height:', err.message)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@ -249,8 +248,8 @@ export function useNeptuneWallet() {
|
||||
|
||||
await persistMinBlockHeight(utxoList)
|
||||
return result
|
||||
} catch (err) {
|
||||
console.error('Error getting UTXOs:', err)
|
||||
} catch (err: any) {
|
||||
await (window as any).logger.error('Error getting UTXOs:', err.message)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@ -275,8 +274,8 @@ export function useNeptuneWallet() {
|
||||
balance: result?.balance || result,
|
||||
pendingBalance: result?.pendingBalance || result,
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error getting balance:', err)
|
||||
} catch (err: any) {
|
||||
await (window as any).logger.error('Error getting balance:', err.message)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@ -286,8 +285,8 @@ export function useNeptuneWallet() {
|
||||
const response = await API.getBlockHeight()
|
||||
const result = response?.result || response
|
||||
return result?.height || result
|
||||
} catch (err) {
|
||||
console.error('Error getting block height:', err)
|
||||
} catch (err: any) {
|
||||
await (window as any).logger.error('Error getting block height:', err.message)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@ -299,8 +298,8 @@ export function useNeptuneWallet() {
|
||||
store.setNetwork((result.network + 'net') as 'mainnet' | 'testnet')
|
||||
|
||||
return result
|
||||
} catch (err) {
|
||||
console.error('Error getting network info:', err)
|
||||
} catch (err: any) {
|
||||
await (window as any).logger.error('Error getting network info:', err.message)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@ -327,8 +326,8 @@ export function useNeptuneWallet() {
|
||||
const response = await API.broadcastSignedTransaction(transactionHex)
|
||||
const result = response?.result || response
|
||||
return result
|
||||
} catch (err) {
|
||||
console.error('Error sending transaction:', err)
|
||||
} catch (err: any) {
|
||||
await (window as any).logger.error('Error sending transaction:', err.message)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@ -345,8 +344,8 @@ export function useNeptuneWallet() {
|
||||
const addressResult = await getAddressFromSeed(store.getSeedPhrase)
|
||||
store.setAddress(addressResult)
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error setting network:', err)
|
||||
} catch (err: any) {
|
||||
await (window as any).logger.error('Error setting network:', err.message)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,7 +32,6 @@ const loadUtxos = async () => {
|
||||
loading.value = true
|
||||
const result = await getUtxos()
|
||||
if (result.error) {
|
||||
console.error(result.error.message)
|
||||
message.error('Failed to load UTXOs')
|
||||
loading.value = false
|
||||
return
|
||||
@ -40,7 +39,6 @@ const loadUtxos = async () => {
|
||||
loading.value = false
|
||||
} catch (err) {
|
||||
message.error('Failed to load UTXOs')
|
||||
console.error('Error loading UTXOs:', err)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
@ -63,8 +61,8 @@ watch(
|
||||
<div class="debug-header">
|
||||
<h3 class="debug-title">IN USE UTXOS</h3>
|
||||
<div class="debug-info">
|
||||
<p><span>COUNT</span> {{ inUseUtxosCount }}</p>
|
||||
<p><span>AMOUNT</span> {{ inUseUtxosAmount }} <strong>NPT</strong></p>
|
||||
<p><span>COUNT</span> <strong>{{ inUseUtxosCount }}</strong></p>
|
||||
<p><span>AMOUNT</span> <strong>{{ inUseUtxosAmount }}</strong> <strong>NPT</strong></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -116,6 +114,10 @@ watch(
|
||||
font-weight: var(--font-bold);
|
||||
margin-right: var(--spacing-sm);
|
||||
}
|
||||
|
||||
strong {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,9 +158,11 @@ const displayAddress = computed(() => {
|
||||
<div class="amount-row">
|
||||
<div class="amount-field">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
Amount <span class="required">*</span>
|
||||
<span class="balance-info">Available: {{ availableBalance }} NPT</span>
|
||||
<label class="form-label-extra">
|
||||
<span class="form-label"> Amount <span class="required">*</span> </span>
|
||||
<span class="balance-info"
|
||||
>Available: <strong>{{ availableBalance }}</strong> NPT</span
|
||||
>
|
||||
</label>
|
||||
<input
|
||||
v-model="outputAmounts"
|
||||
@ -285,12 +287,17 @@ const displayAddress = computed(() => {
|
||||
gap: var(--spacing-xs);
|
||||
}
|
||||
|
||||
.form-label-extra {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
font-size: var(--font-sm);
|
||||
font-weight: var(--font-medium);
|
||||
color: var(--text-primary);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.required {
|
||||
|
||||
@ -21,6 +21,7 @@ const activeTabKey = inject<ComputedRef<string>>('activeTabKey')
|
||||
const availableBalance = ref<string>('0.00000000')
|
||||
const pendingBalance = ref<string>('0.00000000')
|
||||
const loading = ref(false)
|
||||
const sendingLoading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
const showSeedModal = ref(false)
|
||||
const isSendingMode = ref(false)
|
||||
@ -63,7 +64,7 @@ const handleSendTransaction = async (data: {
|
||||
fee: string
|
||||
}) => {
|
||||
try {
|
||||
loading.value = true
|
||||
sendingLoading.value = true
|
||||
const payload = {
|
||||
spendingKeyHex: neptuneStore.getSpendingKey || '',
|
||||
inputAdditionRecords: neptuneStore.getUtxos?.map((utxo: Utxo) => utxo.additionRecord),
|
||||
@ -89,7 +90,7 @@ const handleSendTransaction = async (data: {
|
||||
} catch (error) {
|
||||
message.error('Failed to send transaction')
|
||||
} finally {
|
||||
loading.value = false
|
||||
sendingLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,14 +236,14 @@ watch(
|
||||
<!-- Send Transaction View -->
|
||||
<div v-else-if="isSendingMode" class="send-transaction-wrapper">
|
||||
<SendTransactionComponent
|
||||
:is-loading="loading"
|
||||
:is-loading="sendingLoading"
|
||||
:available-balance="availableBalance"
|
||||
@cancel="handleCancelSend"
|
||||
@send="handleSendTransaction"
|
||||
/>
|
||||
|
||||
<!-- Loading Overlay -->
|
||||
<div v-if="loading" class="sending-overlay">
|
||||
<div v-if="sendingLoading" class="sending-overlay">
|
||||
<div class="sending-content">
|
||||
<SpinnerCommon size="large" />
|
||||
<p class="sending-text">Sending...</p>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user