141125/fix_audit_clear_seed_password_from_store_&_no_traversal_filpath_&_CSP
This commit is contained in:
parent
cb67afb1a5
commit
dc77890692
@ -6,32 +6,44 @@ import logger from './logger'
|
|||||||
|
|
||||||
const neptuneNative = require('@neptune/native')
|
const neptuneNative = require('@neptune/native')
|
||||||
|
|
||||||
// Create keystore into default wallets directory
|
const WALLETS_DIR = path.resolve(app.getPath('userData'), 'wallets')
|
||||||
|
fs.mkdirSync(WALLETS_DIR, { recursive: true })
|
||||||
|
|
||||||
|
function assertBasename(name: string) {
|
||||||
|
if (!name || name !== path.basename(name)) {
|
||||||
|
throw new Error('Invalid file name')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function safeResolvePath(fileName: string) {
|
||||||
|
assertBasename(fileName)
|
||||||
|
const candidate = path.join(WALLETS_DIR, fileName)
|
||||||
|
const realBase = fs.realpathSync(WALLETS_DIR)
|
||||||
|
const realCandidate = fs.existsSync(candidate) ? fs.realpathSync(candidate) : candidate
|
||||||
|
if (!(realCandidate === realBase || realCandidate.startsWith(realBase + path.sep))) {
|
||||||
|
throw new Error('Access denied')
|
||||||
|
}
|
||||||
|
return realCandidate
|
||||||
|
}
|
||||||
|
|
||||||
ipcMain.handle('wallet:createKeystore', async (_event, seed, password) => {
|
ipcMain.handle('wallet:createKeystore', async (_event, seed, password) => {
|
||||||
try {
|
try {
|
||||||
const keystore = await encrypt(seed, password)
|
const keystore = await encrypt(seed, password)
|
||||||
|
|
||||||
const savePath = path.join(process.cwd(), 'wallets')
|
|
||||||
fs.mkdirSync(savePath, { recursive: true })
|
|
||||||
|
|
||||||
const timestamp = Date.now()
|
const timestamp = Date.now()
|
||||||
const fileName = `neptune-wallet-${timestamp}.json`
|
const fileName = `neptune-wallet-${timestamp}.json`
|
||||||
const filePath = path.join(savePath, fileName)
|
const filePath = path.join(WALLETS_DIR, fileName)
|
||||||
fs.writeFileSync(filePath, keystore)
|
fs.writeFileSync(filePath, keystore, 'utf-8')
|
||||||
|
return { success: true, fileName }
|
||||||
return { filePath }
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
logger.error('Error creating keystore:', error.message)
|
logger.error('Error creating keystore:', error.message)
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// New handler: let user choose folder and filename to save keystore
|
ipcMain.handle('wallet:saveKeystoreAs', async (_event, fileName: string) => {
|
||||||
ipcMain.handle('wallet:saveKeystoreAs', async (_event, seed: string, password: string) => {
|
|
||||||
try {
|
try {
|
||||||
const keystore = await encrypt(seed, password)
|
const pathToFileName = safeResolvePath(fileName)
|
||||||
|
const keystore = fs.readFileSync(pathToFileName, 'utf-8')
|
||||||
// Use timestamp for default filename
|
|
||||||
const timestamp = Date.now()
|
const timestamp = Date.now()
|
||||||
const defaultName = `neptune-wallet-${timestamp}.json`
|
const defaultName = `neptune-wallet-${timestamp}.json`
|
||||||
const { canceled, filePath } = await dialog.showSaveDialog({
|
const { canceled, filePath } = await dialog.showSaveDialog({
|
||||||
@ -40,23 +52,25 @@ ipcMain.handle('wallet:saveKeystoreAs', async (_event, seed: string, password: s
|
|||||||
filters: [{ name: 'JSON', extensions: ['json'] }],
|
filters: [{ name: 'JSON', extensions: ['json'] }],
|
||||||
})
|
})
|
||||||
|
|
||||||
if (canceled || !filePath) return { filePath: null }
|
if (canceled || !filePath) return { success: false, filePath: null }
|
||||||
|
if (path.extname(filePath).toLowerCase() !== '.json') {
|
||||||
|
throw new Error('Invalid file extension. Please save as a .json file.')
|
||||||
|
}
|
||||||
|
|
||||||
fs.mkdirSync(path.dirname(filePath), { recursive: true })
|
fs.mkdirSync(path.dirname(filePath), { recursive: true })
|
||||||
fs.writeFileSync(filePath, keystore)
|
fs.writeFileSync(filePath, keystore, 'utf-8')
|
||||||
|
return { success: true, filePath }
|
||||||
return { filePath }
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
logger.error('Error saving keystore (Save As):', error.message)
|
logger.error('Error saving keystore (Save As):', error.message)
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.handle('wallet:decryptKeystore', async (_event, filePath, password) => {
|
ipcMain.handle('wallet:decryptKeystore', async (_event, fileName: string, password: string) => {
|
||||||
try {
|
try {
|
||||||
|
const filePath = safeResolvePath(fileName)
|
||||||
const json = fs.readFileSync(filePath, 'utf-8')
|
const json = fs.readFileSync(filePath, 'utf-8')
|
||||||
const phrase = await fromEncryptedJson(json, password)
|
const phrase = await fromEncryptedJson(json, password)
|
||||||
|
|
||||||
return { phrase }
|
return { phrase }
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
logger.error('Error decrypting keystore ipc:', error.message)
|
logger.error('Error decrypting keystore ipc:', error.message)
|
||||||
@ -66,69 +80,49 @@ ipcMain.handle('wallet:decryptKeystore', async (_event, filePath, password) => {
|
|||||||
|
|
||||||
ipcMain.handle('wallet:checkKeystore', async () => {
|
ipcMain.handle('wallet:checkKeystore', async () => {
|
||||||
try {
|
try {
|
||||||
const walletDir = path.join(process.cwd(), 'wallets')
|
if (!fs.existsSync(WALLETS_DIR)) return { exists: false, fileName: null }
|
||||||
if (!fs.existsSync(walletDir)) return { exists: false, filePath: null }
|
|
||||||
|
|
||||||
const newestFile = fs
|
const newestFile = fs
|
||||||
.readdirSync(walletDir)
|
.readdirSync(WALLETS_DIR)
|
||||||
.filter((f) => f.endsWith('.json'))
|
.filter((f) => f.endsWith('.json'))
|
||||||
.sort(
|
.sort(
|
||||||
(a, b) =>
|
(a, b) =>
|
||||||
fs.statSync(path.join(walletDir, b)).mtime.getTime() -
|
fs.statSync(path.join(WALLETS_DIR, b)).mtime.getTime() -
|
||||||
fs.statSync(path.join(walletDir, a)).mtime.getTime()
|
fs.statSync(path.join(WALLETS_DIR, a)).mtime.getTime()
|
||||||
)[0]
|
)[0]
|
||||||
|
|
||||||
if (!newestFile) return { exists: false, filePath: null }
|
if (!newestFile) return { exists: false, fileName: null }
|
||||||
|
const resolvedPath = safeResolvePath(newestFile)
|
||||||
const resolvedPath = path.join(walletDir, newestFile)
|
|
||||||
let minBlockHeight: number | null = null
|
let minBlockHeight: number | null = null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const json = fs.readFileSync(resolvedPath, 'utf-8')
|
const json = fs.readFileSync(resolvedPath, 'utf-8')
|
||||||
const data = JSON.parse(json)
|
const data = JSON.parse(json)
|
||||||
const height = data?.minBlockHeight
|
const height = data?.minBlockHeight
|
||||||
|
if (Number.isFinite(height)) minBlockHeight = height
|
||||||
if (typeof height === 'number' && Number.isFinite(height)) {
|
|
||||||
minBlockHeight = height
|
|
||||||
}
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
logger.warn('Unable to read minBlockHeight from keystore:', error.message)
|
logger.warn('Unable to read minBlockHeight from keystore:', error.message)
|
||||||
}
|
}
|
||||||
|
return { exists: true, fileName: newestFile, minBlockHeight }
|
||||||
return { exists: true, filePath: resolvedPath, minBlockHeight }
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
logger.error('Error checking keystore ipc:', error.message)
|
logger.error('Error checking keystore ipc:', error.message)
|
||||||
return { exists: false, filePath: null, minBlockHeight: null, error: error.message }
|
return { exists: false, fileName: null, minBlockHeight: null, error: error.message }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.handle(
|
ipcMain.handle(
|
||||||
'wallet:updateMinBlockHeight',
|
'wallet:updateMinBlockHeight',
|
||||||
async (_event, filePath: string | null, minBlockHeight: number | null) => {
|
async (_event, fileName: string | null, minBlockHeight: number | null) => {
|
||||||
if (!filePath) {
|
if (!fileName) {
|
||||||
return { success: false, error: 'No keystore file path provided.' }
|
return { success: false, error: 'No keystore file name provided.' }
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const normalizedPath = path.isAbsolute(filePath)
|
const filePath = safeResolvePath(fileName)
|
||||||
? filePath
|
if (!fs.existsSync(filePath)) {
|
||||||
: path.join(process.cwd(), filePath)
|
|
||||||
|
|
||||||
if (!fs.existsSync(normalizedPath)) {
|
|
||||||
return { success: false, error: 'Keystore file not found.' }
|
return { success: false, error: 'Keystore file not found.' }
|
||||||
}
|
}
|
||||||
|
const fileContents = fs.readFileSync(filePath, 'utf-8')
|
||||||
const fileContents = fs.readFileSync(normalizedPath, 'utf-8')
|
|
||||||
const walletJson = JSON.parse(fileContents)
|
const walletJson = JSON.parse(fileContents)
|
||||||
|
walletJson.minBlockHeight = Number.isFinite(minBlockHeight) ? minBlockHeight : null
|
||||||
if (minBlockHeight === null || Number.isNaN(minBlockHeight)) {
|
fs.writeFileSync(filePath, JSON.stringify(walletJson, null, 2), 'utf-8')
|
||||||
walletJson.minBlockHeight = null
|
|
||||||
} else {
|
|
||||||
walletJson.minBlockHeight = minBlockHeight
|
|
||||||
}
|
|
||||||
|
|
||||||
fs.writeFileSync(normalizedPath, JSON.stringify(walletJson, null, 2), 'utf-8')
|
|
||||||
|
|
||||||
return { success: true, minBlockHeight }
|
return { success: true, minBlockHeight }
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
logger.error('Error updating min block height:', error.message)
|
logger.error('Error updating min block height:', error.message)
|
||||||
@ -137,42 +131,32 @@ ipcMain.handle(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
ipcMain.handle(
|
ipcMain.handle('wallet:getMinBlockHeight', async (_event, fileName: string | null) => {
|
||||||
'wallet:getMinBlockHeight',
|
if (!fileName) {
|
||||||
async (_event, filePath: string | null) => {
|
return { success: false, error: 'No keystore file name provided.', minBlockHeight: 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: any) {
|
|
||||||
logger.error('Error reading min block height:', error.message)
|
|
||||||
return { success: false, error: error.message, minBlockHeight: null }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
try {
|
||||||
|
const filePath = safeResolvePath(fileName)
|
||||||
|
if (!fs.existsSync(filePath)) {
|
||||||
|
return { success: false, error: 'Keystore file not found.', minBlockHeight: null }
|
||||||
|
}
|
||||||
|
const fileContents = fs.readFileSync(filePath, 'utf-8')
|
||||||
|
const walletJson = JSON.parse(fileContents)
|
||||||
|
const height = walletJson?.minBlockHeight
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
minBlockHeight: Number.isFinite(height) ? height : null,
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
logger.error('Error reading min block height:', error.message)
|
||||||
|
return { success: false, error: error.message, minBlockHeight: null }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
ipcMain.handle('wallet:generateKeysFromSeed', async (_event, seedPhrase: string[]) => {
|
ipcMain.handle('wallet:generateKeysFromSeed', async (_event, seedPhrase: string[]) => {
|
||||||
try {
|
try {
|
||||||
const wallet = new neptuneNative.WalletManager()
|
const wallet = new neptuneNative.WalletManager()
|
||||||
return wallet.generateKeysFromSeed(seedPhrase)
|
return JSON.parse(wallet.generateKeysFromSeed(seedPhrase))
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
logger.error('Error generating keys from seed ipc:', error.message)
|
logger.error('Error generating keys from seed ipc:', error.message)
|
||||||
throw error
|
throw error
|
||||||
@ -181,8 +165,36 @@ ipcMain.handle('wallet:generateKeysFromSeed', async (_event, seedPhrase: string[
|
|||||||
|
|
||||||
ipcMain.handle('wallet:buildTransaction', async (_event, args) => {
|
ipcMain.handle('wallet:buildTransaction', async (_event, args) => {
|
||||||
const { spendingKeyHex, inputAdditionRecords, outputAddresses, outputAmounts, fee } = args
|
const { spendingKeyHex, inputAdditionRecords, outputAddresses, outputAmounts, fee } = args
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (typeof spendingKeyHex !== 'string' || !/^(0x)?[0-9a-fA-F]+$/.test(spendingKeyHex)) {
|
||||||
|
throw new Error('Invalid spending key')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!Array.isArray(inputAdditionRecords) ||
|
||||||
|
!inputAdditionRecords.every((r) => typeof r === 'string')
|
||||||
|
) {
|
||||||
|
throw new Error('Invalid inputAdditionRecords')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!Array.isArray(outputAddresses) ||
|
||||||
|
!outputAddresses.every((a) => typeof a === 'string')
|
||||||
|
) {
|
||||||
|
throw new Error('Invalid outputAddresses')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!Array.isArray(outputAmounts) ||
|
||||||
|
!outputAmounts.every((a) => typeof a === 'string' && /^\d+(\.\d+)?$/.test(a))
|
||||||
|
) {
|
||||||
|
throw new Error('Invalid outputAmounts')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof fee !== 'string' || !/^\d+(\.\d+)?$/.test(fee)) {
|
||||||
|
throw new Error('Invalid fee')
|
||||||
|
}
|
||||||
|
|
||||||
const builder = new neptuneNative.SimpleTransactionBuilder()
|
const builder = new neptuneNative.SimpleTransactionBuilder()
|
||||||
const result = await builder.buildTransaction(
|
const result = await builder.buildTransaction(
|
||||||
import.meta.env.VITE_APP_API,
|
import.meta.env.VITE_APP_API,
|
||||||
@ -197,11 +209,11 @@ ipcMain.handle('wallet:buildTransaction', async (_event, args) => {
|
|||||||
)
|
)
|
||||||
return JSON.parse(result)
|
return JSON.parse(result)
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
logger.error('Error building transaction with primitive proof ipc:', error.message)
|
logger.error('Error building transaction ipc:', error.message)
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.on('log:info', (_, msg: string) => logger.info(msg))
|
ipcMain.on('log:info', (_, ...msg: string[]) => logger.info(...msg))
|
||||||
ipcMain.on('log:warn', (_, msg: string) => logger.warn(msg))
|
ipcMain.on('log:warn', (_, ...msg: string[]) => logger.warn(...msg))
|
||||||
ipcMain.on('log:error', (_, msg: string) => logger.error(msg))
|
ipcMain.on('log:error', (_, ...msg: string[]) => logger.error(...msg))
|
||||||
|
|||||||
@ -3,8 +3,6 @@ import log from 'electron-log'
|
|||||||
|
|
||||||
const isDev = app.isPackaged
|
const isDev = app.isPackaged
|
||||||
|
|
||||||
console.log('isDev :>> ', isDev);
|
|
||||||
|
|
||||||
if (!isDev) {
|
if (!isDev) {
|
||||||
log.transports.file.level = 'info'
|
log.transports.file.level = 'info'
|
||||||
log.transports.console.level = false
|
log.transports.console.level = false
|
||||||
@ -12,21 +10,17 @@ if (!isDev) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const logger = {
|
export const logger = {
|
||||||
info: (...args: any[]) => {
|
info: (...args: string[]) => {
|
||||||
if (isDev) console.log('[INFO]', ...args)
|
if (!isDev) log.info(...args)
|
||||||
else log.info(...args)
|
|
||||||
},
|
},
|
||||||
warn: (...args: any[]) => {
|
warn: (...args: string[]) => {
|
||||||
if (isDev) console.warn('[WARN]', ...args)
|
if (!isDev) log.warn(...args)
|
||||||
else log.warn(...args)
|
|
||||||
},
|
},
|
||||||
error: (...args: any[]) => {
|
error: (...args: string[]) => {
|
||||||
if (isDev) console.error('[ERROR]', ...args)
|
if (!isDev) log.error(...args)
|
||||||
else log.error(...args)
|
|
||||||
},
|
},
|
||||||
debug: (...args: any[]) => {
|
debug: (...args: string[]) => {
|
||||||
if (isDev) console.debug('[DEBUG]', ...args)
|
if (!isDev) log.debug(...args)
|
||||||
else log.debug(...args)
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,10 +4,25 @@ import started from 'electron-squirrel-startup'
|
|||||||
import './ipcHandlers'
|
import './ipcHandlers'
|
||||||
import logger from './logger'
|
import logger from './logger'
|
||||||
|
|
||||||
|
const isDev = !app.isPackaged
|
||||||
|
|
||||||
if (started) {
|
if (started) {
|
||||||
app.quit()
|
app.quit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Security: Handle certificate errors - reject invalid certificates to prevent phishing
|
||||||
|
app.on('certificate-error', (event, webContents, url, error, certificate, callback) => {
|
||||||
|
if (isDev && (url.startsWith('http://localhost') || url.startsWith('http://127.0.0.1'))) {
|
||||||
|
event.preventDefault()
|
||||||
|
callback(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.warn(`Certificate error for ${url}: ${error}`)
|
||||||
|
event.preventDefault()
|
||||||
|
callback(false)
|
||||||
|
})
|
||||||
|
|
||||||
const createWindow = () => {
|
const createWindow = () => {
|
||||||
logger.info('App started')
|
logger.info('App started')
|
||||||
const mainWindow = new BrowserWindow({
|
const mainWindow = new BrowserWindow({
|
||||||
@ -20,6 +35,8 @@ const createWindow = () => {
|
|||||||
preload: path.join(__dirname, 'preload.js'),
|
preload: path.join(__dirname, 'preload.js'),
|
||||||
contextIsolation: true,
|
contextIsolation: true,
|
||||||
nodeIntegration: false,
|
nodeIntegration: false,
|
||||||
|
devTools: isDev,
|
||||||
|
sandbox: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {
|
if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {
|
||||||
@ -28,7 +45,58 @@ const createWindow = () => {
|
|||||||
mainWindow.loadFile(path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`))
|
mainWindow.loadFile(path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`))
|
||||||
}
|
}
|
||||||
|
|
||||||
mainWindow.webContents.openDevTools()
|
// Security: Prevent opening new windows - block all window.open() calls
|
||||||
|
mainWindow.webContents.setWindowOpenHandler(() => {
|
||||||
|
logger.warn('Blocked attempt to open new window')
|
||||||
|
return { action: 'deny' }
|
||||||
|
})
|
||||||
|
|
||||||
|
// Security: Control file downloads - validate and log all downloads
|
||||||
|
mainWindow.webContents.session.on('will-download', (event, item) => {
|
||||||
|
const fileName = item.getFilename()
|
||||||
|
const totalBytes = item.getTotalBytes()
|
||||||
|
|
||||||
|
logger.info(`Download started: ${fileName} (${totalBytes} bytes)`)
|
||||||
|
|
||||||
|
// Validate file extension - only allow safe file types
|
||||||
|
const allowedExtensions = ['.json', '.txt', '.csv']
|
||||||
|
const fileExt = path.extname(fileName).toLowerCase()
|
||||||
|
|
||||||
|
if (!allowedExtensions.includes(fileExt)) {
|
||||||
|
logger.warn(`Blocked download of potentially unsafe file: ${fileName}`)
|
||||||
|
item.cancel()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log download progress
|
||||||
|
item.on('updated', () => {
|
||||||
|
logger.info(
|
||||||
|
`Download progress: ${fileName} - ${item.getReceivedBytes()}/${totalBytes} bytes`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
item.on('done', (event, state) => {
|
||||||
|
if (state === 'completed') {
|
||||||
|
logger.info(`Download completed: ${fileName}`)
|
||||||
|
} else if (state === 'cancelled') {
|
||||||
|
logger.warn(`Download cancelled: ${fileName}`)
|
||||||
|
} else {
|
||||||
|
logger.error(`Download interrupted: ${fileName} - ${state}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!isDev) {
|
||||||
|
mainWindow.removeMenu()
|
||||||
|
mainWindow.webContents.on('before-input-event', (event, input) => {
|
||||||
|
if (input.control && input.shift && input.key.toLowerCase() === 'i') {
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
mainWindow.webContents.on('devtools-opened', () => {
|
||||||
|
if (!isDev) mainWindow.webContents.closeDevTools()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method will be called when Electron has finished
|
// This method will be called when Electron has finished
|
||||||
|
|||||||
@ -5,22 +5,21 @@ import { contextBridge, ipcRenderer } from 'electron'
|
|||||||
contextBridge.exposeInMainWorld('walletApi', {
|
contextBridge.exposeInMainWorld('walletApi', {
|
||||||
createKeystore: (seed: string, password: string) =>
|
createKeystore: (seed: string, password: string) =>
|
||||||
ipcRenderer.invoke('wallet:createKeystore', seed, password),
|
ipcRenderer.invoke('wallet:createKeystore', seed, password),
|
||||||
saveKeystoreAs: (seed: string, password: string) =>
|
saveKeystoreAs: (fileName: string) => ipcRenderer.invoke('wallet:saveKeystoreAs', fileName),
|
||||||
ipcRenderer.invoke('wallet:saveKeystoreAs', seed, password),
|
decryptKeystore: (fileName: string, password: string) =>
|
||||||
decryptKeystore: (filePath: string, password: string) =>
|
ipcRenderer.invoke('wallet:decryptKeystore', fileName, password),
|
||||||
ipcRenderer.invoke('wallet:decryptKeystore', filePath, password),
|
|
||||||
checkKeystore: () => ipcRenderer.invoke('wallet:checkKeystore'),
|
checkKeystore: () => ipcRenderer.invoke('wallet:checkKeystore'),
|
||||||
generateKeysFromSeed: (seedPhrase: string[]) =>
|
generateKeysFromSeed: (seedPhrase: string[]) =>
|
||||||
ipcRenderer.invoke('wallet:generateKeysFromSeed', seedPhrase),
|
ipcRenderer.invoke('wallet:generateKeysFromSeed', seedPhrase),
|
||||||
buildTransaction: (args: any) => ipcRenderer.invoke('wallet:buildTransaction', args),
|
buildTransaction: (args: any) => ipcRenderer.invoke('wallet:buildTransaction', args),
|
||||||
updateMinBlockHeight: (filePath: string | null, minBlockHeight: number | null) =>
|
updateMinBlockHeight: (fileName: string | null, minBlockHeight: number | null) =>
|
||||||
ipcRenderer.invoke('wallet:updateMinBlockHeight', filePath, minBlockHeight),
|
ipcRenderer.invoke('wallet:updateMinBlockHeight', fileName, minBlockHeight),
|
||||||
getMinBlockHeight: (filePath: string | null) =>
|
getMinBlockHeight: (fileName: string | null) =>
|
||||||
ipcRenderer.invoke('wallet:getMinBlockHeight', filePath),
|
ipcRenderer.invoke('wallet:getMinBlockHeight', fileName),
|
||||||
})
|
})
|
||||||
|
|
||||||
contextBridge.exposeInMainWorld('logger', {
|
contextBridge.exposeInMainWorld('logger', {
|
||||||
info: (msg: string) => ipcRenderer.send('log:info', msg),
|
info: (...msg: any[]) => ipcRenderer.send('log:info', ...msg),
|
||||||
warn: (msg: string) => ipcRenderer.send('log:warn', msg),
|
warn: (...msg: any[]) => ipcRenderer.send('log:warn', ...msg),
|
||||||
error: (msg: string) => ipcRenderer.send('log:error', msg),
|
error: (...msg: any[]) => ipcRenderer.send('log:error', ...msg),
|
||||||
})
|
})
|
||||||
|
|||||||
@ -4,6 +4,15 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.png" />
|
<link rel="icon" type="image/svg+xml" href="/favicon.png" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta
|
||||||
|
http-equiv="Content-Security-Policy"
|
||||||
|
content="default-src 'self';
|
||||||
|
script-src 'self';
|
||||||
|
style-src 'self';
|
||||||
|
connect-src 'self' ;
|
||||||
|
img-src 'self' data:;"
|
||||||
|
/>
|
||||||
|
|
||||||
<title>Neptune Web Wallet</title>
|
<title>Neptune Web Wallet</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
473
package-lock.json
generated
473
package-lock.json
generated
@ -15,11 +15,10 @@
|
|||||||
"@neptune/wasm": "file:./packages/neptune-wasm",
|
"@neptune/wasm": "file:./packages/neptune-wasm",
|
||||||
"ant-design-vue": "^4.2.6",
|
"ant-design-vue": "^4.2.6",
|
||||||
"axios": "^1.6.8",
|
"axios": "^1.6.8",
|
||||||
"crypto": "^1.0.1",
|
|
||||||
"electron-log": "^5.4.3",
|
"electron-log": "^5.4.3",
|
||||||
"electron-squirrel-startup": "^1.0.1",
|
"electron-squirrel-startup": "^1.0.1",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"vue": "^3.4.21",
|
"vue": "^3.5.24",
|
||||||
"vue-router": "^4.3.0",
|
"vue-router": "^4.3.0",
|
||||||
"vue3-i18n": "^1.1.5"
|
"vue3-i18n": "^1.1.5"
|
||||||
},
|
},
|
||||||
@ -33,12 +32,12 @@
|
|||||||
"@electron-forge/plugin-fuses": "^7.10.2",
|
"@electron-forge/plugin-fuses": "^7.10.2",
|
||||||
"@electron-forge/plugin-vite": "^7.10.2",
|
"@electron-forge/plugin-vite": "^7.10.2",
|
||||||
"@electron/fuses": "^1.8.0",
|
"@electron/fuses": "^1.8.0",
|
||||||
"@rushstack/eslint-patch": "^1.8.0",
|
"@rushstack/eslint-patch": "^1.15.0",
|
||||||
"@tsconfig/node20": "^20.1.4",
|
"@tsconfig/node20": "^20.1.4",
|
||||||
"@types/electron-squirrel-startup": "^1.0.2",
|
"@types/electron-squirrel-startup": "^1.0.2",
|
||||||
"@types/node": "^20.12.5",
|
"@types/node": "^20.19.25",
|
||||||
"@vitejs/plugin-vue": "^5.0.4",
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
"@vitejs/plugin-vue-jsx": "^5.1.1",
|
||||||
"@vue/eslint-config-prettier": "^9.0.0",
|
"@vue/eslint-config-prettier": "^9.0.0",
|
||||||
"@vue/eslint-config-typescript": "^13.0.0",
|
"@vue/eslint-config-typescript": "^13.0.0",
|
||||||
"@vue/tsconfig": "^0.5.1",
|
"@vue/tsconfig": "^0.5.1",
|
||||||
@ -47,11 +46,11 @@
|
|||||||
"eslint-plugin-vue": "^9.23.0",
|
"eslint-plugin-vue": "^9.23.0",
|
||||||
"npm-run-all2": "^6.1.2",
|
"npm-run-all2": "^6.1.2",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"sass": "^1.75.0",
|
"sass": "^1.94.0",
|
||||||
"typescript": "~5.4.0",
|
"typescript": "~5.4.0",
|
||||||
"unplugin-auto-import": "^20.2.0",
|
"unplugin-auto-import": "^20.2.0",
|
||||||
"unplugin-vue-components": "^30.0.0",
|
"unplugin-vue-components": "^30.0.0",
|
||||||
"vite": "^5.2.8",
|
"vite": "^5.4.21",
|
||||||
"vite-plugin-vue-devtools": "^7.0.25",
|
"vite-plugin-vue-devtools": "^7.0.25",
|
||||||
"vue-tsc": "^2.0.11"
|
"vue-tsc": "^2.0.11"
|
||||||
}
|
}
|
||||||
@ -1977,9 +1976,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@inquirer/core/node_modules/@types/node": {
|
"node_modules/@inquirer/core/node_modules/@types/node": {
|
||||||
"version": "22.19.0",
|
"version": "22.19.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.1.tgz",
|
||||||
"integrity": "sha512-xpr/lmLPQEj+TUnHmR+Ab91/glhJvsqcjB+yY0Ix9GO70H6Lb4FHH5GeqdOE5btAx7eIMwuHkp4H2MSkLcqWbA==",
|
"integrity": "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -2017,9 +2016,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@inquirer/figures": {
|
"node_modules/@inquirer/figures": {
|
||||||
"version": "1.0.14",
|
"version": "1.0.15",
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.14.tgz",
|
"resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz",
|
||||||
"integrity": "sha512-DbFgdt+9/OZYFM+19dbpXOSeAstPy884FPy1KjDu4anWwymZeOYhMY1mdFri172htv6mvc/uvIAAi7b7tvjJBQ==",
|
"integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -2700,6 +2699,13 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@rolldown/pluginutils": {
|
||||||
|
"version": "1.0.0-beta.50",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.50.tgz",
|
||||||
|
"integrity": "sha512-5e76wQiQVeL1ICOZVUg4LSOVYg9jyhGCin+icYozhsUzM+fHE7kddi1bdiE0jwVqTfkjba3jUFbEkoC9WkdvyA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@rollup/pluginutils": {
|
"node_modules/@rollup/pluginutils": {
|
||||||
"version": "5.3.0",
|
"version": "5.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz",
|
||||||
@ -2737,9 +2743,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.2.tgz",
|
||||||
"integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==",
|
"integrity": "sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@ -2751,9 +2757,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm64": {
|
"node_modules/@rollup/rollup-android-arm64": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.2.tgz",
|
||||||
"integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==",
|
"integrity": "sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -2765,9 +2771,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.2.tgz",
|
||||||
"integrity": "sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==",
|
"integrity": "sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -2779,9 +2785,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-darwin-x64": {
|
"node_modules/@rollup/rollup-darwin-x64": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.2.tgz",
|
||||||
"integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==",
|
"integrity": "sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -2793,9 +2799,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.2.tgz",
|
||||||
"integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==",
|
"integrity": "sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -2807,9 +2813,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.2.tgz",
|
||||||
"integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==",
|
"integrity": "sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -2821,9 +2827,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.2.tgz",
|
||||||
"integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==",
|
"integrity": "sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@ -2835,9 +2841,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.2.tgz",
|
||||||
"integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==",
|
"integrity": "sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@ -2849,9 +2855,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.2.tgz",
|
||||||
"integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==",
|
"integrity": "sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -2863,9 +2869,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.2.tgz",
|
||||||
"integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==",
|
"integrity": "sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -2877,9 +2883,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-loong64-gnu": {
|
"node_modules/@rollup/rollup-linux-loong64-gnu": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.2.tgz",
|
||||||
"integrity": "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==",
|
"integrity": "sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"loong64"
|
"loong64"
|
||||||
],
|
],
|
||||||
@ -2891,9 +2897,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.2.tgz",
|
||||||
"integrity": "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==",
|
"integrity": "sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
@ -2905,9 +2911,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.2.tgz",
|
||||||
"integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==",
|
"integrity": "sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
@ -2919,9 +2925,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.2.tgz",
|
||||||
"integrity": "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==",
|
"integrity": "sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
@ -2933,9 +2939,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.2.tgz",
|
||||||
"integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==",
|
"integrity": "sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"s390x"
|
"s390x"
|
||||||
],
|
],
|
||||||
@ -2947,9 +2953,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.2.tgz",
|
||||||
"integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==",
|
"integrity": "sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -2961,9 +2967,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.2.tgz",
|
||||||
"integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==",
|
"integrity": "sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -2975,9 +2981,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-openharmony-arm64": {
|
"node_modules/@rollup/rollup-openharmony-arm64": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.2.tgz",
|
||||||
"integrity": "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==",
|
"integrity": "sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -2989,9 +2995,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.2.tgz",
|
||||||
"integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==",
|
"integrity": "sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -3003,9 +3009,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.2.tgz",
|
||||||
"integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==",
|
"integrity": "sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
@ -3017,9 +3023,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-x64-gnu": {
|
"node_modules/@rollup/rollup-win32-x64-gnu": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.2.tgz",
|
||||||
"integrity": "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==",
|
"integrity": "sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -3031,9 +3037,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.2.tgz",
|
||||||
"integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==",
|
"integrity": "sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -3045,9 +3051,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rushstack/eslint-patch": {
|
"node_modules/@rushstack/eslint-patch": {
|
||||||
"version": "1.14.1",
|
"version": "1.15.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.14.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.15.0.tgz",
|
||||||
"integrity": "sha512-jGTk8UD/RdjsNZW8qq10r0RBvxL8OWtoT+kImlzPDFilmozzM+9QmIJsmze9UiSBrFU45ZxhTYBypn9q9z/VfQ==",
|
"integrity": "sha512-ojSshQPKwVvSMR8yT2L/QtUkV5SXi/IfDiJ4/8d6UbTPjiHVmxZzUAzGD8Tzks1b9+qQkZa0isUOvYObedITaw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
@ -3118,9 +3124,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tsconfig/node20": {
|
"node_modules/@tsconfig/node20": {
|
||||||
"version": "20.1.6",
|
"version": "20.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.7.tgz",
|
||||||
"integrity": "sha512-sz+Hqx9zwZDpZIV871WSbUzSqNIsXzghZydypnfgzPKLltVJfkINfUeTct31n/tTSa9ZE1ZOfKdRre1uHHquYQ==",
|
"integrity": "sha512-Lt137u6AoCCJNNklpNtfGIYFEywma7Hd3B083jqMga37opSEVw7beWsD4OTXyzKS0I3G2kbQJVoZpOxy9GnxBQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
@ -3219,9 +3225,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "20.19.24",
|
"version": "20.19.25",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.24.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz",
|
||||||
"integrity": "sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA==",
|
"integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -3497,21 +3503,23 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitejs/plugin-vue-jsx": {
|
"node_modules/@vitejs/plugin-vue-jsx": {
|
||||||
"version": "3.1.0",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-5.1.1.tgz",
|
||||||
"integrity": "sha512-w9M6F3LSEU5kszVb9An2/MmXNxocAnUb3WhRr8bHlimhDrXNt6n6D2nJQR3UXpGlZHh/EsgouOHCsM8V3Ln+WA==",
|
"integrity": "sha512-uQkfxzlF8SGHJJVH966lFTdjM/lGcwJGzwAHpVqAPDD/QcsqoUGa+q31ox1BrUfi+FLP2ChVp7uLXE3DkHyDdQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.23.3",
|
"@babel/core": "^7.28.3",
|
||||||
"@babel/plugin-transform-typescript": "^7.23.3",
|
"@babel/plugin-syntax-typescript": "^7.27.1",
|
||||||
"@vue/babel-plugin-jsx": "^1.1.5"
|
"@babel/plugin-transform-typescript": "^7.28.0",
|
||||||
|
"@rolldown/pluginutils": "^1.0.0-beta.34",
|
||||||
|
"@vue/babel-plugin-jsx": "^1.5.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^14.18.0 || >=16.0.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vite": "^4.0.0 || ^5.0.0",
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
|
||||||
"vue": "^3.0.0"
|
"vue": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -3605,39 +3613,39 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-core": {
|
"node_modules/@vue/compiler-core": {
|
||||||
"version": "3.5.23",
|
"version": "3.5.24",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.23.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.24.tgz",
|
||||||
"integrity": "sha512-nW7THWj5HOp085ROk65LwaoxuzDsjIxr485F4iu63BoxsXoSqKqmsUUoP4A7Gl67DgIgi0zJ8JFgHfvny/74MA==",
|
"integrity": "sha512-eDl5H57AOpNakGNAkFDH+y7kTqrQpJkZFXhWZQGyx/5Wh7B1uQYvcWkvZi11BDhscPgj8N7XV3oRwiPnx1Vrig==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.28.5",
|
"@babel/parser": "^7.28.5",
|
||||||
"@vue/shared": "3.5.23",
|
"@vue/shared": "3.5.24",
|
||||||
"entities": "^4.5.0",
|
"entities": "^4.5.0",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"source-map-js": "^1.2.1"
|
"source-map-js": "^1.2.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-dom": {
|
"node_modules/@vue/compiler-dom": {
|
||||||
"version": "3.5.23",
|
"version": "3.5.24",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.23.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.24.tgz",
|
||||||
"integrity": "sha512-AT8RMw0vEzzzO0JU5gY0F6iCzaWUIh/aaRVordzMBKXRpoTllTT4kocHDssByPsvodNCfump/Lkdow2mT/O5KQ==",
|
"integrity": "sha512-1QHGAvs53gXkWdd3ZMGYuvQFXHW4ksKWPG8HP8/2BscrbZ0brw183q2oNWjMrSWImYLHxHrx1ItBQr50I/q2zw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-core": "3.5.23",
|
"@vue/compiler-core": "3.5.24",
|
||||||
"@vue/shared": "3.5.23"
|
"@vue/shared": "3.5.24"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-sfc": {
|
"node_modules/@vue/compiler-sfc": {
|
||||||
"version": "3.5.23",
|
"version": "3.5.24",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.23.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.24.tgz",
|
||||||
"integrity": "sha512-3QTEUo4qg7FtQwaDJa8ou1CUikx5WTtZlY61rRRDu3lK2ZKrGoAGG8mvDgOpDsQ4A1bez9s+WtBB6DS2KuFCPw==",
|
"integrity": "sha512-8EG5YPRgmTB+YxYBM3VXy8zHD9SWHUJLIGPhDovo3Z8VOgvP+O7UP5vl0J4BBPWYD9vxtBabzW1EuEZ+Cqs14g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.28.5",
|
"@babel/parser": "^7.28.5",
|
||||||
"@vue/compiler-core": "3.5.23",
|
"@vue/compiler-core": "3.5.24",
|
||||||
"@vue/compiler-dom": "3.5.23",
|
"@vue/compiler-dom": "3.5.24",
|
||||||
"@vue/compiler-ssr": "3.5.23",
|
"@vue/compiler-ssr": "3.5.24",
|
||||||
"@vue/shared": "3.5.23",
|
"@vue/shared": "3.5.24",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"magic-string": "^0.30.21",
|
"magic-string": "^0.30.21",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "^8.5.6",
|
||||||
@ -3645,13 +3653,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-ssr": {
|
"node_modules/@vue/compiler-ssr": {
|
||||||
"version": "3.5.23",
|
"version": "3.5.24",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.23.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.24.tgz",
|
||||||
"integrity": "sha512-Hld2xphbMjXs9Q9WKxPf2EqmE+Rq/FEDnK/wUBtmYq74HCV4XDdSCheAaB823OQXIIFGq9ig/RbAZkF9s4U0Ow==",
|
"integrity": "sha512-trOvMWNBMQ/odMRHW7Ae1CdfYx+7MuiQu62Jtu36gMLXcaoqKvAyh+P73sYG9ll+6jLB6QPovqoKGGZROzkFFg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.5.23",
|
"@vue/compiler-dom": "3.5.24",
|
||||||
"@vue/shared": "3.5.23"
|
"@vue/shared": "3.5.24"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-vue2": {
|
"node_modules/@vue/compiler-vue2": {
|
||||||
@ -3672,14 +3680,14 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@vue/devtools-core": {
|
"node_modules/@vue/devtools-core": {
|
||||||
"version": "7.7.7",
|
"version": "7.7.8",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-7.7.7.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-7.7.8.tgz",
|
||||||
"integrity": "sha512-9z9TLbfC+AjAi1PQyWX+OErjIaJmdFlbDHcD+cAMYKY6Bh5VlsAtCeGyRMrXwIlMEQPukvnWt3gZBLwTAIMKzQ==",
|
"integrity": "sha512-EVLQTYML/v77JFA3Q8zvVANCvEv1WtG0TMo+HQR5eZ7PpEzSmVbEcBp2C1/OXyn8EJO4mHEeParMLpp43prUOw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/devtools-kit": "^7.7.7",
|
"@vue/devtools-kit": "^7.7.8",
|
||||||
"@vue/devtools-shared": "^7.7.7",
|
"@vue/devtools-shared": "^7.7.8",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
"nanoid": "^5.1.0",
|
"nanoid": "^5.1.0",
|
||||||
"pathe": "^2.0.3",
|
"pathe": "^2.0.3",
|
||||||
@ -3709,13 +3717,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/devtools-kit": {
|
"node_modules/@vue/devtools-kit": {
|
||||||
"version": "7.7.7",
|
"version": "7.7.8",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.7.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.8.tgz",
|
||||||
"integrity": "sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==",
|
"integrity": "sha512-4Y8op+AoxOJhB9fpcEF6d5vcJXWKgHxC3B0ytUB8zz15KbP9g9WgVzral05xluxi2fOeAy6t140rdQ943GcLRQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/devtools-shared": "^7.7.7",
|
"@vue/devtools-shared": "^7.7.8",
|
||||||
"birpc": "^2.3.0",
|
"birpc": "^2.3.0",
|
||||||
"hookable": "^5.5.3",
|
"hookable": "^5.5.3",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
@ -3725,9 +3733,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/devtools-shared": {
|
"node_modules/@vue/devtools-shared": {
|
||||||
"version": "7.7.7",
|
"version": "7.7.8",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.7.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.8.tgz",
|
||||||
"integrity": "sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==",
|
"integrity": "sha512-XHpO3jC5nOgYr40M9p8Z4mmKfTvUxKyRcUnpBAYg11pE78eaRFBKb0kG5yKLroMuJeeNH9LWmKp2zMU5LUc7CA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -3826,53 +3834,53 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/reactivity": {
|
"node_modules/@vue/reactivity": {
|
||||||
"version": "3.5.23",
|
"version": "3.5.24",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.23.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.24.tgz",
|
||||||
"integrity": "sha512-ji5w0qvrPyBmBx5Ldv4QGNsw0phgRreEvjt0iUf1lei2Sm8//9ZAi78uM2ZjsT5gk0YZilLuoRCIMvtuZlHMJw==",
|
"integrity": "sha512-BM8kBhtlkkbnyl4q+HiF5R5BL0ycDPfihowulm02q3WYp2vxgPcJuZO866qa/0u3idbMntKEtVNuAUp5bw4teg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/shared": "3.5.23"
|
"@vue/shared": "3.5.24"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-core": {
|
"node_modules/@vue/runtime-core": {
|
||||||
"version": "3.5.23",
|
"version": "3.5.24",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.23.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.24.tgz",
|
||||||
"integrity": "sha512-LMB0S6/G7mFJcpQeQaZrbsthFbWrIX8FVTzu5x9U3Ec8YW5MY1CGAnBBHNj+TPOBu3pIbtPpjrXtcaN04X+aBw==",
|
"integrity": "sha512-RYP/byyKDgNIqfX/gNb2PB55dJmM97jc9wyF3jK7QUInYKypK2exmZMNwnjueWwGceEkP6NChd3D2ZVEp9undQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "3.5.23",
|
"@vue/reactivity": "3.5.24",
|
||||||
"@vue/shared": "3.5.23"
|
"@vue/shared": "3.5.24"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-dom": {
|
"node_modules/@vue/runtime-dom": {
|
||||||
"version": "3.5.23",
|
"version": "3.5.24",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.23.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.24.tgz",
|
||||||
"integrity": "sha512-r/PYc8W9THzEL0UExpTkV+d31zO+Jid/RMZIDG6aS/NekOEUHuCJkJgftySWZw7JTJO/+q9Kxkg8p+i7Q7Q+ew==",
|
"integrity": "sha512-Z8ANhr/i0XIluonHVjbUkjvn+CyrxbXRIxR7wn7+X7xlcb7dJsfITZbkVOeJZdP8VZwfrWRsWdShH6pngMxRjw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "3.5.23",
|
"@vue/reactivity": "3.5.24",
|
||||||
"@vue/runtime-core": "3.5.23",
|
"@vue/runtime-core": "3.5.24",
|
||||||
"@vue/shared": "3.5.23",
|
"@vue/shared": "3.5.24",
|
||||||
"csstype": "^3.1.3"
|
"csstype": "^3.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/server-renderer": {
|
"node_modules/@vue/server-renderer": {
|
||||||
"version": "3.5.23",
|
"version": "3.5.24",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.23.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.24.tgz",
|
||||||
"integrity": "sha512-NiWZsNCsXA20/VufcrW5u+Trt/PyFlpMmxaB2KERYM8eZgUoKUjXxJQb9ypq+LZ0Sp3XHJGNBR8DkhRnkKAMUw==",
|
"integrity": "sha512-Yh2j2Y4G/0/4z/xJ1Bad4mxaAk++C2v4kaa8oSYTMJBJ00/ndPuxCnWeot0/7/qafQFLh5pr6xeV6SdMcE/G1w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-ssr": "3.5.23",
|
"@vue/compiler-ssr": "3.5.24",
|
||||||
"@vue/shared": "3.5.23"
|
"@vue/shared": "3.5.24"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vue": "3.5.23"
|
"vue": "3.5.24"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/shared": {
|
"node_modules/@vue/shared": {
|
||||||
"version": "3.5.23",
|
"version": "3.5.24",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.23.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.24.tgz",
|
||||||
"integrity": "sha512-0YZ1DYuC5o/YJPf6pFdt2KYxVGDxkDbH/1NYJnVJWUkzr8ituBEmFVQRNX2gCaAsFEjEDnLkWpgqlZA7htgS/g==",
|
"integrity": "sha512-9cwHL2EsJBdi8NY22pngYYWzkTDhld6fAD6jlaeloNGciNSJL6bLpbxVgXl96X00Jtc6YWQv96YA/0sxex/k1A==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@vue/tsconfig": {
|
"node_modules/@vue/tsconfig": {
|
||||||
@ -4393,9 +4401,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/baseline-browser-mapping": {
|
"node_modules/baseline-browser-mapping": {
|
||||||
"version": "2.8.25",
|
"version": "2.8.27",
|
||||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.25.tgz",
|
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.27.tgz",
|
||||||
"integrity": "sha512-2NovHVesVF5TXefsGX1yzx1xgr7+m9JQenvz6FQY3qd+YXkKkYiv+vTCc7OriP9mcDZpTC5mAOYN4ocd29+erA==",
|
"integrity": "sha512-2CXFpkjVnY2FT+B6GrSYxzYf65BJWEqz5tIRHCvNsZZ2F3CmsCB37h8SpYgKG7y9C4YAeTipIPWG7EmFmhAeXA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
@ -4403,9 +4411,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/birpc": {
|
"node_modules/birpc": {
|
||||||
"version": "2.7.0",
|
"version": "2.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/birpc/-/birpc-2.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/birpc/-/birpc-2.8.0.tgz",
|
||||||
"integrity": "sha512-tub/wFGH49vNCm0xraykcY3TcRgX/3JsALYq/Lwrtti+bTyFHkCUAWF5wgYoie8P41wYwig2mIKiqoocr1EkEQ==",
|
"integrity": "sha512-Bz2a4qD/5GRhiHSwj30c/8kC8QGj12nNDwz3D4ErQ4Xhy35dsSDvF+RA/tWpjyU0pdGtSDiEk6B5fBGE1qNVhw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
@ -4472,9 +4480,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/browserslist": {
|
"node_modules/browserslist": {
|
||||||
"version": "4.27.0",
|
"version": "4.28.0",
|
||||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz",
|
||||||
"integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==",
|
"integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -4492,10 +4500,10 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"baseline-browser-mapping": "^2.8.19",
|
"baseline-browser-mapping": "^2.8.25",
|
||||||
"caniuse-lite": "^1.0.30001751",
|
"caniuse-lite": "^1.0.30001754",
|
||||||
"electron-to-chromium": "^1.5.238",
|
"electron-to-chromium": "^1.5.249",
|
||||||
"node-releases": "^2.0.26",
|
"node-releases": "^2.0.27",
|
||||||
"update-browserslist-db": "^1.1.4"
|
"update-browserslist-db": "^1.1.4"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@ -5093,13 +5101,6 @@
|
|||||||
"node": ">=12.10"
|
"node": ">=12.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/crypto": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==",
|
|
||||||
"deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in.",
|
|
||||||
"license": "ISC"
|
|
||||||
},
|
|
||||||
"node_modules/cssesc": {
|
"node_modules/cssesc": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||||
@ -5187,9 +5188,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/default-browser": {
|
"node_modules/default-browser": {
|
||||||
"version": "5.2.1",
|
"version": "5.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.3.0.tgz",
|
||||||
"integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==",
|
"integrity": "sha512-Qq68+VkJlc8tjnPV1i7HtbIn7ohmjZa88qUvHMIK0ZKUXMCuV45cT7cEXALPUmeXCe0q1DWQkQTemHVaLIFSrg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -5388,9 +5389,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/electron": {
|
"node_modules/electron": {
|
||||||
"version": "39.1.0",
|
"version": "39.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/electron/-/electron-39.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/electron/-/electron-39.1.2.tgz",
|
||||||
"integrity": "sha512-vPRbKKQUzKWZZX68fuYdz4iS/eavGcQkHOGK4ylv0YJLbBRxxUlflPRdqRGflFjwid+sja7gbNul2lArevYwrw==",
|
"integrity": "sha512-+/TwT9NWxyQGTm5WemJEJy+bWCpnKJ4PLPswI1yn1P63bzM0/8yAeG05yS+NfFaWH4yNQtGXZmAv87Bxa5RlLg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -5842,9 +5843,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.5.245",
|
"version": "1.5.250",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.245.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.250.tgz",
|
||||||
"integrity": "sha512-rdmGfW47ZhL/oWEJAY4qxRtdly2B98ooTJ0pdEI4jhVLZ6tNf8fPtov2wS1IRKwFJT92le3x4Knxiwzl7cPPpQ==",
|
"integrity": "sha512-/5UMj9IiGDMOFBnN4i7/Ry5onJrAGSbOGo3s9FEKmwobGq6xw832ccET0CE3CkkMBZ8GJSlUIesZofpyurqDXw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
@ -5931,9 +5932,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/electron/node_modules/@types/node": {
|
"node_modules/electron/node_modules/@types/node": {
|
||||||
"version": "22.19.0",
|
"version": "22.19.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.1.tgz",
|
||||||
"integrity": "sha512-xpr/lmLPQEj+TUnHmR+Ab91/glhJvsqcjB+yY0Ix9GO70H6Lb4FHH5GeqdOE5btAx7eIMwuHkp4H2MSkLcqWbA==",
|
"integrity": "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -6573,9 +6574,9 @@
|
|||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0"
|
||||||
},
|
},
|
||||||
"node_modules/exsolve": {
|
"node_modules/exsolve": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz",
|
||||||
"integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==",
|
"integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
@ -7575,9 +7576,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ip-address": {
|
"node_modules/ip-address": {
|
||||||
"version": "10.0.1",
|
"version": "10.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz",
|
||||||
"integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==",
|
"integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -7857,9 +7858,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/js-yaml": {
|
"node_modules/js-yaml": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
|
||||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -10095,9 +10096,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "4.52.5",
|
"version": "4.53.2",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.2.tgz",
|
||||||
"integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==",
|
"integrity": "sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -10111,28 +10112,28 @@
|
|||||||
"npm": ">=8.0.0"
|
"npm": ">=8.0.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@rollup/rollup-android-arm-eabi": "4.52.5",
|
"@rollup/rollup-android-arm-eabi": "4.53.2",
|
||||||
"@rollup/rollup-android-arm64": "4.52.5",
|
"@rollup/rollup-android-arm64": "4.53.2",
|
||||||
"@rollup/rollup-darwin-arm64": "4.52.5",
|
"@rollup/rollup-darwin-arm64": "4.53.2",
|
||||||
"@rollup/rollup-darwin-x64": "4.52.5",
|
"@rollup/rollup-darwin-x64": "4.53.2",
|
||||||
"@rollup/rollup-freebsd-arm64": "4.52.5",
|
"@rollup/rollup-freebsd-arm64": "4.53.2",
|
||||||
"@rollup/rollup-freebsd-x64": "4.52.5",
|
"@rollup/rollup-freebsd-x64": "4.53.2",
|
||||||
"@rollup/rollup-linux-arm-gnueabihf": "4.52.5",
|
"@rollup/rollup-linux-arm-gnueabihf": "4.53.2",
|
||||||
"@rollup/rollup-linux-arm-musleabihf": "4.52.5",
|
"@rollup/rollup-linux-arm-musleabihf": "4.53.2",
|
||||||
"@rollup/rollup-linux-arm64-gnu": "4.52.5",
|
"@rollup/rollup-linux-arm64-gnu": "4.53.2",
|
||||||
"@rollup/rollup-linux-arm64-musl": "4.52.5",
|
"@rollup/rollup-linux-arm64-musl": "4.53.2",
|
||||||
"@rollup/rollup-linux-loong64-gnu": "4.52.5",
|
"@rollup/rollup-linux-loong64-gnu": "4.53.2",
|
||||||
"@rollup/rollup-linux-ppc64-gnu": "4.52.5",
|
"@rollup/rollup-linux-ppc64-gnu": "4.53.2",
|
||||||
"@rollup/rollup-linux-riscv64-gnu": "4.52.5",
|
"@rollup/rollup-linux-riscv64-gnu": "4.53.2",
|
||||||
"@rollup/rollup-linux-riscv64-musl": "4.52.5",
|
"@rollup/rollup-linux-riscv64-musl": "4.53.2",
|
||||||
"@rollup/rollup-linux-s390x-gnu": "4.52.5",
|
"@rollup/rollup-linux-s390x-gnu": "4.53.2",
|
||||||
"@rollup/rollup-linux-x64-gnu": "4.52.5",
|
"@rollup/rollup-linux-x64-gnu": "4.53.2",
|
||||||
"@rollup/rollup-linux-x64-musl": "4.52.5",
|
"@rollup/rollup-linux-x64-musl": "4.53.2",
|
||||||
"@rollup/rollup-openharmony-arm64": "4.52.5",
|
"@rollup/rollup-openharmony-arm64": "4.53.2",
|
||||||
"@rollup/rollup-win32-arm64-msvc": "4.52.5",
|
"@rollup/rollup-win32-arm64-msvc": "4.53.2",
|
||||||
"@rollup/rollup-win32-ia32-msvc": "4.52.5",
|
"@rollup/rollup-win32-ia32-msvc": "4.53.2",
|
||||||
"@rollup/rollup-win32-x64-gnu": "4.52.5",
|
"@rollup/rollup-win32-x64-gnu": "4.53.2",
|
||||||
"@rollup/rollup-win32-x64-msvc": "4.52.5",
|
"@rollup/rollup-win32-x64-msvc": "4.53.2",
|
||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -10202,9 +10203,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/sass": {
|
"node_modules/sass": {
|
||||||
"version": "1.93.3",
|
"version": "1.94.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.93.3.tgz",
|
"resolved": "https://registry.npmjs.org/sass/-/sass-1.94.0.tgz",
|
||||||
"integrity": "sha512-elOcIZRTM76dvxNAjqYrucTSI0teAF/L2Lv0s6f6b7FOwcwIuA357bIE871580AjHJuSvLIRUosgV+lIWx6Rgg==",
|
"integrity": "sha512-Dqh7SiYcaFtdv5Wvku6QgS5IGPm281L+ZtVD1U2FJa7Q0EFRlq8Z3sjYtz6gYObsYThUOz9ArwFqPZx+1azILQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -11665,15 +11666,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite-plugin-vue-devtools": {
|
"node_modules/vite-plugin-vue-devtools": {
|
||||||
"version": "7.7.7",
|
"version": "7.7.8",
|
||||||
"resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.7.7.tgz",
|
"resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.7.8.tgz",
|
||||||
"integrity": "sha512-d0fIh3wRcgSlr4Vz7bAk4va1MkdqhQgj9ANE/rBhsAjOnRfTLs2ocjFMvSUOsv6SRRXU9G+VM7yMgqDb6yI4iQ==",
|
"integrity": "sha512-04jowFsal5f9Gbso0X5Ff/mtvik7VP/PBYcKDCQHnTLH0x+juWSj7v1QJfDtXnWrrxU7/yrljEP8KZTm4skvkg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/devtools-core": "^7.7.7",
|
"@vue/devtools-core": "^7.7.8",
|
||||||
"@vue/devtools-kit": "^7.7.7",
|
"@vue/devtools-kit": "^7.7.8",
|
||||||
"@vue/devtools-shared": "^7.7.7",
|
"@vue/devtools-shared": "^7.7.8",
|
||||||
"execa": "^9.5.2",
|
"execa": "^9.5.2",
|
||||||
"sirv": "^3.0.1",
|
"sirv": "^3.0.1",
|
||||||
"vite-plugin-inspect": "0.8.9",
|
"vite-plugin-inspect": "0.8.9",
|
||||||
@ -11802,16 +11803,16 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/vue": {
|
"node_modules/vue": {
|
||||||
"version": "3.5.23",
|
"version": "3.5.24",
|
||||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.23.tgz",
|
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.24.tgz",
|
||||||
"integrity": "sha512-CfvZv/vI52xUhumUvHtD6iFIS78nGWfX4IJnHfBGhpqMI0CwDq2YEngXOeaBFMRmiArcqczuVrLxurvesTYT9w==",
|
"integrity": "sha512-uTHDOpVQTMjcGgrqFPSb8iO2m1DUvo+WbGqoXQz8Y1CeBYQ0FXf2z1gLRaBtHjlRz7zZUBHxjVB5VTLzYkvftg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.5.23",
|
"@vue/compiler-dom": "3.5.24",
|
||||||
"@vue/compiler-sfc": "3.5.23",
|
"@vue/compiler-sfc": "3.5.24",
|
||||||
"@vue/runtime-dom": "3.5.23",
|
"@vue/runtime-dom": "3.5.24",
|
||||||
"@vue/server-renderer": "3.5.23",
|
"@vue/server-renderer": "3.5.24",
|
||||||
"@vue/shared": "3.5.23"
|
"@vue/shared": "3.5.24"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": "*"
|
"typescript": "*"
|
||||||
|
|||||||
13
package.json
13
package.json
@ -25,11 +25,10 @@
|
|||||||
"@neptune/wasm": "file:./packages/neptune-wasm",
|
"@neptune/wasm": "file:./packages/neptune-wasm",
|
||||||
"ant-design-vue": "^4.2.6",
|
"ant-design-vue": "^4.2.6",
|
||||||
"axios": "^1.6.8",
|
"axios": "^1.6.8",
|
||||||
"crypto": "^1.0.1",
|
|
||||||
"electron-log": "^5.4.3",
|
"electron-log": "^5.4.3",
|
||||||
"electron-squirrel-startup": "^1.0.1",
|
"electron-squirrel-startup": "^1.0.1",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"vue": "^3.4.21",
|
"vue": "^3.5.24",
|
||||||
"vue-router": "^4.3.0",
|
"vue-router": "^4.3.0",
|
||||||
"vue3-i18n": "^1.1.5"
|
"vue3-i18n": "^1.1.5"
|
||||||
},
|
},
|
||||||
@ -43,12 +42,12 @@
|
|||||||
"@electron-forge/plugin-fuses": "^7.10.2",
|
"@electron-forge/plugin-fuses": "^7.10.2",
|
||||||
"@electron-forge/plugin-vite": "^7.10.2",
|
"@electron-forge/plugin-vite": "^7.10.2",
|
||||||
"@electron/fuses": "^1.8.0",
|
"@electron/fuses": "^1.8.0",
|
||||||
"@rushstack/eslint-patch": "^1.8.0",
|
"@rushstack/eslint-patch": "^1.15.0",
|
||||||
"@tsconfig/node20": "^20.1.4",
|
"@tsconfig/node20": "^20.1.4",
|
||||||
"@types/electron-squirrel-startup": "^1.0.2",
|
"@types/electron-squirrel-startup": "^1.0.2",
|
||||||
"@types/node": "^20.12.5",
|
"@types/node": "^20.19.25",
|
||||||
"@vitejs/plugin-vue": "^5.0.4",
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
"@vitejs/plugin-vue-jsx": "^5.1.1",
|
||||||
"@vue/eslint-config-prettier": "^9.0.0",
|
"@vue/eslint-config-prettier": "^9.0.0",
|
||||||
"@vue/eslint-config-typescript": "^13.0.0",
|
"@vue/eslint-config-typescript": "^13.0.0",
|
||||||
"@vue/tsconfig": "^0.5.1",
|
"@vue/tsconfig": "^0.5.1",
|
||||||
@ -57,11 +56,11 @@
|
|||||||
"eslint-plugin-vue": "^9.23.0",
|
"eslint-plugin-vue": "^9.23.0",
|
||||||
"npm-run-all2": "^6.1.2",
|
"npm-run-all2": "^6.1.2",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"sass": "^1.75.0",
|
"sass": "^1.94.0",
|
||||||
"typescript": "~5.4.0",
|
"typescript": "~5.4.0",
|
||||||
"unplugin-auto-import": "^20.2.0",
|
"unplugin-auto-import": "^20.2.0",
|
||||||
"unplugin-vue-components": "^30.0.0",
|
"unplugin-vue-components": "^30.0.0",
|
||||||
"vite": "^5.2.8",
|
"vite": "^5.4.21",
|
||||||
"vite-plugin-vue-devtools": "^7.0.25",
|
"vite-plugin-vue-devtools": "^7.0.25",
|
||||||
"vue-tsc": "^2.0.11"
|
"vue-tsc": "^2.0.11"
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 975 KiB |
@ -11,15 +11,6 @@ const instance = axios.create({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
instance.interceptors.response.use(
|
|
||||||
(response) => {
|
|
||||||
return response
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
return Promise.reject(error)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
instance.interceptors.response.use(
|
instance.interceptors.response.use(
|
||||||
function (response) {
|
function (response) {
|
||||||
if (response?.status !== STATUS_CODE_SUCCESS) return Promise.reject(response?.data)
|
if (response?.status !== STATUS_CODE_SUCCESS) return Promise.reject(response?.data)
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import { callJsonRpc } from '@/api/request'
|
import { callJsonRpc } from '@/api/request'
|
||||||
|
import { DEFAULT_MIN_BLOCK_HEIGHT } from '@/utils/constants/constants'
|
||||||
|
|
||||||
export const getUtxosFromViewKey = async (
|
export const getUtxosFromViewKey = async (
|
||||||
viewKey: string,
|
viewKey: string,
|
||||||
startBlock: number | null = 0,
|
startBlock: number = DEFAULT_MIN_BLOCK_HEIGHT,
|
||||||
endBlock: number | null = null,
|
endBlock: number | null = null,
|
||||||
maxSearchDepth: number = 1000
|
maxSearchDepth: number = 1000
|
||||||
): Promise<any> => {
|
): Promise<any> => {
|
||||||
@ -17,7 +18,7 @@ export const getUtxosFromViewKey = async (
|
|||||||
|
|
||||||
export const getBalance = async (
|
export const getBalance = async (
|
||||||
viewKey: string,
|
viewKey: string,
|
||||||
startBlock: number | null = 0,
|
startBlock: number = DEFAULT_MIN_BLOCK_HEIGHT,
|
||||||
endBlock: number | null = null,
|
endBlock: number | null = null,
|
||||||
maxSearchDepth: number = 1000
|
maxSearchDepth: number = 1000
|
||||||
): Promise<any> => {
|
): Promise<any> => {
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 975 KiB |
@ -1,13 +1,14 @@
|
|||||||
import { useNeptuneStore } from '@/stores/neptuneStore'
|
import { useNeptuneStore } from '@/stores/neptuneStore'
|
||||||
import * as API from '@/api/neptuneApi'
|
import * as API from '@/api/neptuneApi'
|
||||||
import type {
|
import type {
|
||||||
|
BalanceResult,
|
||||||
GenerateSeedResult,
|
GenerateSeedResult,
|
||||||
PayloadBuildTransaction,
|
PayloadBuildTransaction,
|
||||||
ViewKeyResult,
|
ViewKeyResult,
|
||||||
WalletState,
|
WalletState,
|
||||||
} from '@/interface'
|
} from '@/interface'
|
||||||
import initWasm, { generate_seed, address_from_seed, validate_seed_phrase } from '@neptune/wasm'
|
import initWasm, { generate_seed, address_from_seed, validate_seed_phrase } from '@neptune/wasm'
|
||||||
import { toFiniteNumber } from '@/utils'
|
import { DEFAULT_MIN_BLOCK_HEIGHT, toFiniteNumber } from '@/utils'
|
||||||
|
|
||||||
let wasmInitialized = false
|
let wasmInitialized = false
|
||||||
let initPromise: Promise<void> | null = null
|
let initPromise: Promise<void> | null = null
|
||||||
@ -32,7 +33,7 @@ export function useNeptuneWallet() {
|
|||||||
wasmInitialized = true
|
wasmInitialized = true
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
wasmInitialized = false
|
wasmInitialized = false
|
||||||
await (window as any).logger.error('WASM init error:', err.message)
|
await (window as any).logger.error('WASM init error:')
|
||||||
throw new Error('Failed to initialize Neptune WASM')
|
throw new Error('Failed to initialize Neptune WASM')
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
@ -47,7 +48,6 @@ export function useNeptuneWallet() {
|
|||||||
const resultJson = generate_seed()
|
const resultJson = generate_seed()
|
||||||
const result: GenerateSeedResult = JSON.parse(resultJson)
|
const result: GenerateSeedResult = JSON.parse(resultJson)
|
||||||
|
|
||||||
store.setSeedPhrase(result.seed_phrase)
|
|
||||||
store.setReceiverId(result.receiver_identifier)
|
store.setReceiverId(result.receiver_identifier)
|
||||||
|
|
||||||
const viewKeyResult = await getViewKeyFromSeed(result.seed_phrase)
|
const viewKeyResult = await getViewKeyFromSeed(result.seed_phrase)
|
||||||
@ -59,24 +59,22 @@ export function useNeptuneWallet() {
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
await (window as any).logger.error('Error generating wallet:', err.message)
|
await (window as any).logger.error('Error generating wallet: ', err.message)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getViewKeyFromSeed = async (seedPhrase: string[]): Promise<ViewKeyResult> => {
|
const getViewKeyFromSeed = async (seedPhrase: string[]): Promise<ViewKeyResult> => {
|
||||||
const result = await (window as any).walletApi.generateKeysFromSeed([...seedPhrase])
|
return await (window as any).walletApi.generateKeysFromSeed([...seedPhrase])
|
||||||
return JSON.parse(result)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const recoverWalletFromSeed = async (seedPhrase: string[]): Promise<WalletState> => {
|
const recoverWalletFromSeed = async (seedPhrase: string[]): Promise<WalletState> => {
|
||||||
try {
|
try {
|
||||||
|
await ensureWasmInitialized()
|
||||||
const isValid = validate_seed_phrase(JSON.stringify(seedPhrase))
|
const isValid = validate_seed_phrase(JSON.stringify(seedPhrase))
|
||||||
if (!isValid) throw new Error('Invalid seed phrase')
|
if (!isValid) throw new Error('Invalid seed phrase')
|
||||||
|
|
||||||
const result = await getViewKeyFromSeed(seedPhrase)
|
const result = await getViewKeyFromSeed(seedPhrase)
|
||||||
|
|
||||||
store.setSeedPhrase(seedPhrase)
|
|
||||||
store.setReceiverId(result.receiver_identifier)
|
store.setReceiverId(result.receiver_identifier)
|
||||||
store.setViewKey(result.view_key_hex)
|
store.setViewKey(result.view_key_hex)
|
||||||
store.setSpendingKey(result.spending_key_hex)
|
store.setSpendingKey(result.spending_key_hex)
|
||||||
@ -85,7 +83,6 @@ export function useNeptuneWallet() {
|
|||||||
store.setAddress(addressResult)
|
store.setAddress(addressResult)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
seedPhrase: seedPhrase,
|
|
||||||
network: store.getNetwork,
|
network: store.getNetwork,
|
||||||
receiverId: result.receiver_identifier,
|
receiverId: result.receiver_identifier,
|
||||||
viewKey: result.view_key_hex,
|
viewKey: result.view_key_hex,
|
||||||
@ -93,7 +90,7 @@ export function useNeptuneWallet() {
|
|||||||
address: addressResult,
|
address: addressResult,
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
await (window as any).logger.error('Error recovering wallet from seed:', err.message)
|
await (window as any).logger.error('Error recovering wallet from seed: ', err.message)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,21 +101,19 @@ export function useNeptuneWallet() {
|
|||||||
return address_from_seed(seedPhraseJson, store.getNetwork)
|
return address_from_seed(seedPhraseJson, store.getNetwork)
|
||||||
}
|
}
|
||||||
|
|
||||||
const decryptKeystore = async (password: string): Promise<void> => {
|
const decryptKeystore = async (password: string): Promise<{ seedPhrase: string[] }> => {
|
||||||
try {
|
try {
|
||||||
const keystorePath = store.getKeystorePath
|
const keystoreFileName = store.getKeystoreFileName
|
||||||
if (!keystorePath) await checkKeystore()
|
if (!keystoreFileName) await checkKeystore()
|
||||||
|
|
||||||
const result = await (window as any).walletApi.decryptKeystore(
|
const result = await (window as any).walletApi.decryptKeystore(
|
||||||
store.getKeystorePath,
|
keystoreFileName,
|
||||||
password
|
password
|
||||||
)
|
)
|
||||||
|
|
||||||
const seedPhrase = result.phrase.trim().split(/\s+/)
|
const seedPhrase = result.phrase.trim().split(/\s+/)
|
||||||
const viewKeyResult = await getViewKeyFromSeed(seedPhrase)
|
const viewKeyResult = await getViewKeyFromSeed(seedPhrase)
|
||||||
|
|
||||||
store.setPassword(password)
|
|
||||||
store.setSeedPhrase(seedPhrase)
|
|
||||||
store.setViewKey(viewKeyResult.view_key_hex)
|
store.setViewKey(viewKeyResult.view_key_hex)
|
||||||
store.setReceiverId(viewKeyResult.receiver_identifier)
|
store.setReceiverId(viewKeyResult.receiver_identifier)
|
||||||
store.setSpendingKey(viewKeyResult.spending_key_hex)
|
store.setSpendingKey(viewKeyResult.spending_key_hex)
|
||||||
@ -127,6 +122,8 @@ export function useNeptuneWallet() {
|
|||||||
store.setAddress(addressResult)
|
store.setAddress(addressResult)
|
||||||
|
|
||||||
await loadMinBlockHeightFromKeystore()
|
await loadMinBlockHeightFromKeystore()
|
||||||
|
|
||||||
|
return { seedPhrase }
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
if (
|
if (
|
||||||
err instanceof Error &&
|
err instanceof Error &&
|
||||||
@ -134,55 +131,58 @@ export function useNeptuneWallet() {
|
|||||||
err.message.includes('unable to authenticate'))
|
err.message.includes('unable to authenticate'))
|
||||||
) {
|
) {
|
||||||
await (window as any).logger.error('Invalid password')
|
await (window as any).logger.error('Invalid password')
|
||||||
} else await (window as any).logger.error('Error decrypting keystore:', err.message)
|
} else await (window as any).logger.error('Error decrypting keystore: ', err.message)
|
||||||
|
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const createKeystore = async (seed: string, password: string): Promise<string> => {
|
const createKeystore = async (seed: string, password: string): Promise<string | null> => {
|
||||||
try {
|
try {
|
||||||
const result = await (window as any).walletApi.createKeystore(seed, password)
|
const result = await (window as any).walletApi.createKeystore(seed, password)
|
||||||
store.setKeystorePath(result.filePath)
|
if (!result.success) return null
|
||||||
store.setMinBlockHeight(null)
|
store.setKeystoreFileName(result.fileName)
|
||||||
return result.filePath
|
store.setMinBlockHeight(DEFAULT_MIN_BLOCK_HEIGHT)
|
||||||
|
return result.fileName
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
await (window as any).logger.error('Error creating keystore:', err.message)
|
await (window as any).logger.error('Error creating keystore: ', err.message)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveKeystoreAs = async (seed: string, password: string): Promise<string> => {
|
const saveKeystoreAs = async (): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
const result = await (window as any).walletApi.saveKeystoreAs(seed, password)
|
const keystoreFileName = store.getKeystoreFileName
|
||||||
|
if (!keystoreFileName) throw new Error('No file to save')
|
||||||
|
|
||||||
|
const result = await (window as any).walletApi.saveKeystoreAs(keystoreFileName)
|
||||||
if (!result.filePath) throw new Error('User canceled')
|
if (!result.filePath) throw new Error('User canceled')
|
||||||
return result.filePath
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
await (window as any).logger.error('Error saving keystore:', err.message)
|
await (window as any).logger.error('Error saving keystore: ', err.message)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkKeystore = async (): Promise<boolean> => {
|
const checkKeystore = async (): Promise<boolean> => {
|
||||||
try {
|
try {
|
||||||
const keystoreFile = await (window as any).walletApi.checkKeystore()
|
const keystoreFile = await (window as any).walletApi.checkKeystore(store.getKeystoreFileName)
|
||||||
if (!keystoreFile.exists) return false
|
if (!keystoreFile.exists) return false
|
||||||
|
|
||||||
store.setKeystorePath(keystoreFile.filePath)
|
store.setKeystoreFileName(keystoreFile.fileName)
|
||||||
if ('minBlockHeight' in keystoreFile) {
|
if ('minBlockHeight' in keystoreFile) {
|
||||||
const height = keystoreFile.minBlockHeight
|
const height = keystoreFile.minBlockHeight
|
||||||
store.setMinBlockHeight(toFiniteNumber(height))
|
store.setMinBlockHeight(toFiniteNumber(height))
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
await (window as any).logger.error('Error checking keystore:', err.message)
|
await (window as any).logger.error('Error checking keystore: ', err.message)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const persistMinBlockHeight = async (utxos: any[]) => {
|
const persistMinBlockHeight = async (utxos: any[]) => {
|
||||||
const keystorePath = store.getKeystorePath
|
const keystoreFileName = store.getKeystoreFileName
|
||||||
if (!keystorePath) return
|
if (!keystoreFileName) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const minBlockHeight = utxos.reduce((min, utxo) => {
|
const minBlockHeight = utxos.reduce((min, utxo) => {
|
||||||
@ -196,31 +196,31 @@ export function useNeptuneWallet() {
|
|||||||
}, null)
|
}, null)
|
||||||
|
|
||||||
const response = await (window as any).walletApi.updateMinBlockHeight(
|
const response = await (window as any).walletApi.updateMinBlockHeight(
|
||||||
keystorePath,
|
keystoreFileName,
|
||||||
minBlockHeight
|
minBlockHeight
|
||||||
)
|
)
|
||||||
if (!response.success) throw new Error('Failed to update min block height')
|
if (!response.success) throw new Error('Failed to update min block height')
|
||||||
store.setMinBlockHeight(minBlockHeight)
|
store.setMinBlockHeight(minBlockHeight)
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
await (window as any).logger.error('Error saving min block height:', err.message)
|
await (window as any).logger.error('Error saving min block height: ', err.message)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadMinBlockHeightFromKeystore = async (): Promise<number | null> => {
|
const loadMinBlockHeightFromKeystore = async (): Promise<number> => {
|
||||||
const keystorePath = store.getKeystorePath
|
const keystoreFileName = store.getKeystoreFileName
|
||||||
if (!keystorePath) return null
|
if (!keystoreFileName) return DEFAULT_MIN_BLOCK_HEIGHT
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await (window as any).walletApi.getMinBlockHeight(keystorePath)
|
const response = await (window as any).walletApi.getMinBlockHeight(keystoreFileName)
|
||||||
if (!response?.success) return null
|
if (!response?.success) throw new Error(String(response.error))
|
||||||
|
|
||||||
const minBlockHeight = toFiniteNumber(response.minBlockHeight)
|
const minBlockHeight = toFiniteNumber(response.minBlockHeight)
|
||||||
|
|
||||||
store.setMinBlockHeight(minBlockHeight)
|
store.setMinBlockHeight(minBlockHeight)
|
||||||
return minBlockHeight
|
return minBlockHeight
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
await (window as any).logger.error('Error loading min block height:', err.message)
|
await (window as any).logger.error('Error loading min block height: ', err.message)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,7 +237,7 @@ export function useNeptuneWallet() {
|
|||||||
|
|
||||||
const response = await API.getUtxosFromViewKey(
|
const response = await API.getUtxosFromViewKey(
|
||||||
store.getViewKey || '',
|
store.getViewKey || '',
|
||||||
toFiniteNumber(startBlock, 0)
|
toFiniteNumber(startBlock)
|
||||||
)
|
)
|
||||||
|
|
||||||
const result = response?.result || response
|
const result = response?.result || response
|
||||||
@ -249,22 +249,22 @@ export function useNeptuneWallet() {
|
|||||||
await persistMinBlockHeight(utxoList)
|
await persistMinBlockHeight(utxoList)
|
||||||
return result
|
return result
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
await (window as any).logger.error('Error getting UTXOs:', err.message)
|
await (window as any).logger.error('Error getting UTXOs: ', err.message)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getBalance = async (): Promise<any> => {
|
const getBalance = async (): Promise<BalanceResult> => {
|
||||||
try {
|
try {
|
||||||
let startBlock: number | null | undefined = store.getMinBlockHeight
|
let startBlock: number | null | undefined = store.getMinBlockHeight
|
||||||
|
|
||||||
if (startBlock === null || startBlock === undefined) {
|
if (startBlock == null) {
|
||||||
startBlock = await loadMinBlockHeightFromKeystore()
|
startBlock = await loadMinBlockHeightFromKeystore()
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await API.getBalance(
|
const response = await API.getBalance(
|
||||||
store.getViewKey || '',
|
store.getViewKey || '',
|
||||||
toFiniteNumber(startBlock, 0)
|
toFiniteNumber(startBlock)
|
||||||
)
|
)
|
||||||
const result = response?.result || response
|
const result = response?.result || response
|
||||||
|
|
||||||
@ -275,7 +275,7 @@ export function useNeptuneWallet() {
|
|||||||
pendingBalance: result?.pendingBalance || result,
|
pendingBalance: result?.pendingBalance || result,
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
await (window as any).logger.error('Error getting balance:', err.message)
|
await (window as any).logger.error('Error getting balance: ', err.message)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -286,7 +286,7 @@ export function useNeptuneWallet() {
|
|||||||
const result = response?.result || response
|
const result = response?.result || response
|
||||||
return result?.height || result
|
return result?.height || result
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
await (window as any).logger.error('Error getting block height:', err.message)
|
await (window as any).logger.error('Error getting block height: ', err.message)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -299,7 +299,7 @@ export function useNeptuneWallet() {
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
await (window as any).logger.error('Error getting network info:', err.message)
|
await (window as any).logger.error('Error getting network info: ', err.message)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -313,7 +313,7 @@ export function useNeptuneWallet() {
|
|||||||
const payload = {
|
const payload = {
|
||||||
spendingKeyHex: store.getSpendingKey,
|
spendingKeyHex: store.getSpendingKey,
|
||||||
inputAdditionRecords: args.inputAdditionRecords,
|
inputAdditionRecords: args.inputAdditionRecords,
|
||||||
minBlockHeight: toFiniteNumber(minBlockHeight, 0),
|
minBlockHeight: toFiniteNumber(minBlockHeight),
|
||||||
outputAddresses: args.outputAddresses,
|
outputAddresses: args.outputAddresses,
|
||||||
outputAmounts: args.outputAmounts,
|
outputAmounts: args.outputAmounts,
|
||||||
fee: args.fee,
|
fee: args.fee,
|
||||||
@ -327,25 +327,7 @@ export function useNeptuneWallet() {
|
|||||||
const result = response?.result || response
|
const result = response?.result || response
|
||||||
return result
|
return result
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
await (window as any).logger.error('Error sending transaction:', err.message)
|
await (window as any).logger.error('Error sending transaction: ', err.message)
|
||||||
throw err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const setNetwork = async (network: 'mainnet' | 'testnet') => {
|
|
||||||
try {
|
|
||||||
store.setNetwork(network)
|
|
||||||
|
|
||||||
if (store.getSeedPhrase) {
|
|
||||||
const viewKeyResult = await getViewKeyFromSeed(store.getSeedPhrase)
|
|
||||||
store.setViewKey(viewKeyResult.view_key_hex)
|
|
||||||
store.setSpendingKey(viewKeyResult.spending_key_hex)
|
|
||||||
|
|
||||||
const addressResult = await getAddressFromSeed(store.getSeedPhrase)
|
|
||||||
store.setAddress(addressResult)
|
|
||||||
}
|
|
||||||
} catch (err: any) {
|
|
||||||
await (window as any).logger.error('Error setting network:', err.message)
|
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -374,6 +356,5 @@ export function useNeptuneWallet() {
|
|||||||
checkKeystore,
|
checkKeystore,
|
||||||
|
|
||||||
clearWallet,
|
clearWallet,
|
||||||
setNetwork,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
export interface WalletState {
|
export interface WalletState {
|
||||||
seedPhrase: string[] | null
|
|
||||||
password?: string | null
|
|
||||||
receiverId: string | null
|
receiverId: string | null
|
||||||
viewKey: string | null
|
viewKey: string | null
|
||||||
spendingKey?: string | null
|
spendingKey?: string | null
|
||||||
@ -42,3 +40,8 @@ export interface Utxo {
|
|||||||
blockHeight: number
|
blockHeight: number
|
||||||
utxoHash: string
|
utxoHash: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface BalanceResult {
|
||||||
|
balance: string | null
|
||||||
|
pendingBalance: string | null
|
||||||
|
}
|
||||||
|
|||||||
@ -1,15 +1,13 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import type { WalletState } from '@/interface'
|
import type { WalletState } from '@/interface'
|
||||||
import { toFiniteNumber } from '@/utils'
|
import { DEFAULT_MIN_BLOCK_HEIGHT, toFiniteNumber } from '@/utils'
|
||||||
|
|
||||||
export const useNeptuneStore = defineStore('neptune', () => {
|
export const useNeptuneStore = defineStore('neptune', () => {
|
||||||
const defaultNetwork = (import.meta.env.VITE_NODE_NETWORK || 'mainnet') as 'mainnet' | 'testnet'
|
const defaultNetwork = (import.meta.env.VITE_NODE_NETWORK || 'mainnet') as 'mainnet' | 'testnet'
|
||||||
|
|
||||||
// ===== STATE =====
|
// ===== STATE =====
|
||||||
const wallet = ref<WalletState>({
|
const wallet = ref<WalletState>({
|
||||||
seedPhrase: null,
|
|
||||||
password: null,
|
|
||||||
receiverId: null,
|
receiverId: null,
|
||||||
viewKey: null,
|
viewKey: null,
|
||||||
spendingKey: null,
|
spendingKey: null,
|
||||||
@ -21,18 +19,10 @@ export const useNeptuneStore = defineStore('neptune', () => {
|
|||||||
minBlockHeight: null,
|
minBlockHeight: null,
|
||||||
})
|
})
|
||||||
|
|
||||||
const keystorePath = ref<null | string>(null)
|
const keystoreFileName = ref<string | null>(null)
|
||||||
|
|
||||||
// ===== SETTERS =====
|
// ===== SETTERS =====
|
||||||
|
|
||||||
const setSeedPhrase = (seedPhrase: string[] | null) => {
|
|
||||||
wallet.value.seedPhrase = seedPhrase
|
|
||||||
}
|
|
||||||
|
|
||||||
const setPassword = (password: string | null) => {
|
|
||||||
wallet.value.password = password
|
|
||||||
}
|
|
||||||
|
|
||||||
const setReceiverId = (receiverId: string | null) => {
|
const setReceiverId = (receiverId: string | null) => {
|
||||||
wallet.value.receiverId = receiverId
|
wallet.value.receiverId = receiverId
|
||||||
}
|
}
|
||||||
@ -65,7 +55,7 @@ export const useNeptuneStore = defineStore('neptune', () => {
|
|||||||
wallet.value.utxos = utxos
|
wallet.value.utxos = utxos
|
||||||
}
|
}
|
||||||
|
|
||||||
const setMinBlockHeight = (minBlockHeight: number | null) => {
|
const setMinBlockHeight = (minBlockHeight: number = DEFAULT_MIN_BLOCK_HEIGHT) => {
|
||||||
wallet.value.minBlockHeight = toFiniteNumber(minBlockHeight)
|
wallet.value.minBlockHeight = toFiniteNumber(minBlockHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,14 +63,12 @@ export const useNeptuneStore = defineStore('neptune', () => {
|
|||||||
wallet.value = { ...wallet.value, ...walletData }
|
wallet.value = { ...wallet.value, ...walletData }
|
||||||
}
|
}
|
||||||
|
|
||||||
const setKeystorePath = (path: string | null) => {
|
const setKeystoreFileName = (fileName: string | null) => {
|
||||||
keystorePath.value = path
|
keystoreFileName.value = fileName
|
||||||
}
|
}
|
||||||
|
|
||||||
const clearWallet = () => {
|
const clearWallet = () => {
|
||||||
wallet.value = {
|
wallet.value = {
|
||||||
seedPhrase: null,
|
|
||||||
password: null,
|
|
||||||
receiverId: null,
|
receiverId: null,
|
||||||
viewKey: null,
|
viewKey: null,
|
||||||
spendingKey: null,
|
spendingKey: null,
|
||||||
@ -95,9 +83,6 @@ export const useNeptuneStore = defineStore('neptune', () => {
|
|||||||
|
|
||||||
// ===== GETTERS =====
|
// ===== GETTERS =====
|
||||||
const getWallet = computed(() => wallet.value)
|
const getWallet = computed(() => wallet.value)
|
||||||
const getSeedPhrase = computed(() => wallet.value.seedPhrase)
|
|
||||||
const getSeedPhraseString = computed(() => wallet.value.seedPhrase?.join(' ') || '')
|
|
||||||
const getPassword = computed(() => wallet.value.password)
|
|
||||||
const getReceiverId = computed(() => wallet.value.receiverId)
|
const getReceiverId = computed(() => wallet.value.receiverId)
|
||||||
const getViewKey = computed(() => wallet.value.viewKey)
|
const getViewKey = computed(() => wallet.value.viewKey)
|
||||||
const getSpendingKey = computed(() => wallet.value.spendingKey)
|
const getSpendingKey = computed(() => wallet.value.spendingKey)
|
||||||
@ -108,12 +93,9 @@ export const useNeptuneStore = defineStore('neptune', () => {
|
|||||||
const getUtxos = computed(() => wallet.value.utxos)
|
const getUtxos = computed(() => wallet.value.utxos)
|
||||||
const getMinBlockHeight = computed(() => wallet.value.minBlockHeight ?? null)
|
const getMinBlockHeight = computed(() => wallet.value.minBlockHeight ?? null)
|
||||||
const hasWallet = computed(() => wallet.value.address !== null)
|
const hasWallet = computed(() => wallet.value.address !== null)
|
||||||
const getKeystorePath = computed(() => keystorePath.value)
|
const getKeystoreFileName = computed(() => keystoreFileName.value ?? null)
|
||||||
return {
|
return {
|
||||||
getWallet,
|
getWallet,
|
||||||
getSeedPhrase,
|
|
||||||
getSeedPhraseString,
|
|
||||||
getPassword,
|
|
||||||
getReceiverId,
|
getReceiverId,
|
||||||
getViewKey,
|
getViewKey,
|
||||||
getSpendingKey,
|
getSpendingKey,
|
||||||
@ -124,9 +106,7 @@ export const useNeptuneStore = defineStore('neptune', () => {
|
|||||||
getUtxos,
|
getUtxos,
|
||||||
getMinBlockHeight,
|
getMinBlockHeight,
|
||||||
hasWallet,
|
hasWallet,
|
||||||
getKeystorePath,
|
getKeystoreFileName,
|
||||||
setSeedPhrase,
|
|
||||||
setPassword,
|
|
||||||
setReceiverId,
|
setReceiverId,
|
||||||
setViewKey,
|
setViewKey,
|
||||||
setSpendingKey,
|
setSpendingKey,
|
||||||
@ -137,7 +117,7 @@ export const useNeptuneStore = defineStore('neptune', () => {
|
|||||||
setUtxos,
|
setUtxos,
|
||||||
setMinBlockHeight,
|
setMinBlockHeight,
|
||||||
setWallet,
|
setWallet,
|
||||||
setKeystorePath,
|
setKeystoreFileName,
|
||||||
clearWallet,
|
clearWallet,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
export const PAGE_FIRST = 1
|
export const PAGE_FIRST = 1
|
||||||
export const PER_PAGE = 20
|
export const PER_PAGE = 20
|
||||||
export const POLLING_INTERVAL = 1000 * 60 // 1 minute
|
export const POLLING_INTERVAL = 1000 * 60 // 1 minute
|
||||||
|
export const DEFAULT_MIN_BLOCK_HEIGHT = 0
|
||||||
|
|||||||
@ -1,3 +1,9 @@
|
|||||||
export function toFiniteNumber(value: number | null, defaultValue?: number): number | null {
|
import { DEFAULT_MIN_BLOCK_HEIGHT } from '@/utils/constants/constants'
|
||||||
return Number.isFinite(value) ? value : (defaultValue ?? null)
|
|
||||||
|
export function toFiniteNumber(
|
||||||
|
value: number,
|
||||||
|
defaultValue: number = DEFAULT_MIN_BLOCK_HEIGHT
|
||||||
|
): number {
|
||||||
|
return Number.isFinite(value) ? value : defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -33,6 +33,7 @@ const handleGoToRecover = () => {
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.auth-container {
|
.auth-container {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
|
background: var(--bg-white);
|
||||||
}
|
}
|
||||||
|
|
||||||
.complete-state {
|
.complete-state {
|
||||||
|
|||||||
@ -41,7 +41,6 @@ const handleRecover = () => {
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.welcome-page {
|
.welcome-page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background-color: var(--bg-light);
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.welcome-card {
|
.welcome-card {
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { useNeptuneStore } from '@/stores/neptuneStore'
|
|
||||||
import { message } from 'ant-design-vue'
|
import { message } from 'ant-design-vue'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
seedPhrase: string[]
|
||||||
backButton?: boolean
|
backButton?: boolean
|
||||||
nextButton?: boolean
|
nextButton?: boolean
|
||||||
backButtonText?: string
|
backButtonText?: string
|
||||||
@ -22,13 +22,11 @@ const emit = defineEmits<{
|
|||||||
back: []
|
back: []
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const neptuneStore = useNeptuneStore()
|
const seedWords = computed(() => props.seedPhrase || [])
|
||||||
|
|
||||||
const seedWords = computed(() => neptuneStore.getSeedPhrase || [])
|
|
||||||
|
|
||||||
const handleNext = () => {
|
const handleNext = () => {
|
||||||
if (!seedWords.value || seedWords.value.length === 0) {
|
if (!seedWords.value || seedWords.value.length === 0) {
|
||||||
message.error('❌ Cannot proceed without seed phrase')
|
message.error('Cannot proceed without seed phrase')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
emit('next')
|
emit('next')
|
||||||
@ -97,7 +95,7 @@ const handleCopySeed = async () => {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="no-seed-warning">
|
<div v-else class="no-seed-warning">
|
||||||
<p>⚠️ No seed phrase found. Please go back and generate a wallet first.</p>
|
<p>No seed phrase found. Please go back and generate a wallet first.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="recovery-actions">
|
<div class="recovery-actions">
|
||||||
|
|||||||
@ -1,16 +1,19 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, computed } from 'vue'
|
import { ref, onMounted, computed } from 'vue'
|
||||||
import { useNeptuneStore } from '@/stores/neptuneStore'
|
|
||||||
import { message } from 'ant-design-vue'
|
import { message } from 'ant-design-vue'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
seedPhrase: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<Props>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
next: []
|
next: []
|
||||||
back: []
|
back: []
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const neptuneStore = useNeptuneStore()
|
const seedWords = computed(() => props.seedPhrase || [])
|
||||||
|
|
||||||
const seedWords = computed(() => neptuneStore.getSeedPhrase || [])
|
|
||||||
const currentQuestionIndex = ref(0)
|
const currentQuestionIndex = ref(0)
|
||||||
const selectedAnswer = ref('')
|
const selectedAnswer = ref('')
|
||||||
const isCorrect = ref(false)
|
const isCorrect = ref(false)
|
||||||
@ -110,7 +113,7 @@ const handleBack = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const seeds = neptuneStore.getSeedPhrase
|
const seeds = props.seedPhrase
|
||||||
|
|
||||||
if (!seeds || seeds.length === 0) {
|
if (!seeds || seeds.length === 0) {
|
||||||
message.warning('No seed phrase found. Please go back and generate a wallet first.')
|
message.warning('No seed phrase found. Please go back and generate a wallet first.')
|
||||||
|
|||||||
@ -1,14 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import { useNeptuneStore } from '@/stores'
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
next: []
|
next: [password: string]
|
||||||
navigateToRecoverWallet: []
|
navigateToRecoverWallet: []
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const neptuneStore = useNeptuneStore()
|
|
||||||
|
|
||||||
const password = ref('')
|
const password = ref('')
|
||||||
const confirmPassword = ref('')
|
const confirmPassword = ref('')
|
||||||
const passwordError = ref('')
|
const passwordError = ref('')
|
||||||
@ -56,8 +53,7 @@ const handleNext = () => {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
neptuneStore.setPassword(password.value)
|
emit('next', password.value)
|
||||||
emit('next')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleIHaveWallet = () => {
|
const handleIHaveWallet = () => {
|
||||||
|
|||||||
@ -14,6 +14,8 @@ const { initWasm, generateWallet, clearWallet } = useNeptuneWallet()
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const step = ref(1)
|
const step = ref(1)
|
||||||
|
const seedPhrase = ref<string[]>([])
|
||||||
|
const password = ref('')
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
try {
|
try {
|
||||||
@ -35,9 +37,11 @@ const handleNextToWalletCreated = () => {
|
|||||||
step.value = 4
|
step.value = 4
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleNextFromPassword = async () => {
|
const handleNextFromPassword = async (pwd: string) => {
|
||||||
try {
|
try {
|
||||||
await generateWallet()
|
const result = await generateWallet()
|
||||||
|
seedPhrase.value = result.seed_phrase
|
||||||
|
password.value = pwd
|
||||||
step.value = 2
|
step.value = 2
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
message.error('Failed to generate wallet')
|
message.error('Failed to generate wallet')
|
||||||
@ -58,6 +62,8 @@ const handleAccessWallet = () => {
|
|||||||
|
|
||||||
function resetAll() {
|
function resetAll() {
|
||||||
step.value = 1
|
step.value = 1
|
||||||
|
seedPhrase.value = []
|
||||||
|
password.value = ''
|
||||||
clearWallet()
|
clearWallet()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -75,6 +81,7 @@ function resetAll() {
|
|||||||
<!-- Step 2: Recovery Seed -->
|
<!-- Step 2: Recovery Seed -->
|
||||||
<SeedPhraseDisplayComponent
|
<SeedPhraseDisplayComponent
|
||||||
v-else-if="step === 2"
|
v-else-if="step === 2"
|
||||||
|
:seed-phrase="seedPhrase"
|
||||||
@back="handleBackToCreatePassword"
|
@back="handleBackToCreatePassword"
|
||||||
@next="handleNextToConfirmSeed"
|
@next="handleNextToConfirmSeed"
|
||||||
/>
|
/>
|
||||||
@ -82,6 +89,7 @@ function resetAll() {
|
|||||||
<!-- Step 3: Confirm Seed -->
|
<!-- Step 3: Confirm Seed -->
|
||||||
<ConfirmSeedComponent
|
<ConfirmSeedComponent
|
||||||
v-else-if="step === 3"
|
v-else-if="step === 3"
|
||||||
|
:seed-phrase="seedPhrase"
|
||||||
@back="handleBackToSeedPhrase"
|
@back="handleBackToSeedPhrase"
|
||||||
@next="handleNextToWalletCreated"
|
@next="handleNextToWalletCreated"
|
||||||
/>
|
/>
|
||||||
@ -89,6 +97,8 @@ function resetAll() {
|
|||||||
<!-- Step 4: Success -->
|
<!-- Step 4: Success -->
|
||||||
<WalletCreatedStep
|
<WalletCreatedStep
|
||||||
v-else-if="step === 4"
|
v-else-if="step === 4"
|
||||||
|
:seed-phrase="seedPhrase"
|
||||||
|
:password="password"
|
||||||
@access-wallet="handleAccessWallet"
|
@access-wallet="handleAccessWallet"
|
||||||
@create-another="resetAll"
|
@create-another="resetAll"
|
||||||
/>
|
/>
|
||||||
@ -103,7 +113,6 @@ function resetAll() {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: var(--spacing-xl);
|
padding: var(--spacing-xl);
|
||||||
background: var(--bg-light);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.auth-card {
|
.auth-card {
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useNeptuneStore } from '@/stores/neptuneStore'
|
|
||||||
import { useNeptuneWallet } from '@/composables/useNeptuneWallet'
|
import { useNeptuneWallet } from '@/composables/useNeptuneWallet'
|
||||||
import { message } from 'ant-design-vue'
|
import { message } from 'ant-design-vue'
|
||||||
|
|
||||||
const neptuneStore = useNeptuneStore()
|
const props = defineProps<{
|
||||||
|
seedPhrase: string[]
|
||||||
|
password: string
|
||||||
|
}>()
|
||||||
|
|
||||||
const { createKeystore } = useNeptuneWallet()
|
const { createKeystore } = useNeptuneWallet()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@ -13,15 +16,14 @@ const emit = defineEmits<{
|
|||||||
|
|
||||||
const handleAccessWallet = async () => {
|
const handleAccessWallet = async () => {
|
||||||
try {
|
try {
|
||||||
const seedPhrase = neptuneStore.getSeedPhraseString
|
const seedPhraseString = props.seedPhrase.join(' ')
|
||||||
const password = neptuneStore.getPassword!
|
|
||||||
|
|
||||||
if (!seedPhrase || !password) {
|
if (!seedPhraseString || !props.password) {
|
||||||
message.error('Missing seed or password')
|
message.error('Missing seed or password')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await createKeystore(seedPhrase, password)
|
await createKeystore(seedPhraseString, props.password)
|
||||||
emit('accessWallet')
|
emit('accessWallet')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
message.error('Failed to create keystore')
|
message.error('Failed to create keystore')
|
||||||
|
|||||||
@ -132,7 +132,7 @@ const handleCancel = () => {
|
|||||||
}
|
}
|
||||||
@include screen(mobile) {
|
@include screen(mobile) {
|
||||||
.import-wallet {
|
.import-wallet {
|
||||||
padding: 16px 5px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
|
import type { BalanceResult } from '@/interface'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isLoading?: boolean
|
isLoading?: boolean
|
||||||
availableBalance?: string
|
availableBalance?: BalanceResult['balance']
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
@ -27,7 +28,7 @@ const isAmountValid = computed(() => {
|
|||||||
if (isNaN(num) || num <= 0) return false
|
if (isNaN(num) || num <= 0) return false
|
||||||
|
|
||||||
// Check if amount exceeds available balance
|
// Check if amount exceeds available balance
|
||||||
const balance = parseFloat(props.availableBalance)
|
const balance = parseFloat(props.availableBalance ?? '0.00000000')
|
||||||
if (!isNaN(balance) && num > balance) return false
|
if (!isNaN(balance) && num > balance) return false
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -43,7 +44,7 @@ const amountErrorMessage = computed(() => {
|
|||||||
const num = parseFloat(outputAmounts.value)
|
const num = parseFloat(outputAmounts.value)
|
||||||
if (isNaN(num) || num <= 0) return 'Invalid amount'
|
if (isNaN(num) || num <= 0) return 'Invalid amount'
|
||||||
|
|
||||||
const balance = parseFloat(props.availableBalance)
|
const balance = parseFloat(props.availableBalance ?? '0.00000000')
|
||||||
if (!isNaN(balance) && num > balance) {
|
if (!isNaN(balance) && num > balance) {
|
||||||
return `Insufficient balance. Available: ${props.availableBalance} NPT`
|
return `Insufficient balance. Available: ${props.availableBalance} NPT`
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { BalanceResult } from '@/interface'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isLoadingData: boolean
|
isLoadingData: boolean
|
||||||
availableBalance: string
|
availableBalance: BalanceResult['balance']
|
||||||
pendingBalance: string
|
pendingBalance: BalanceResult['pendingBalance']
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>()
|
const props = defineProps<Props>()
|
||||||
@ -36,8 +38,8 @@ const props = defineProps<Props>()
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
.balance-label {
|
.balance-label {
|
||||||
color: var(--text-muted);
|
|
||||||
font-size: var(--font-base);
|
font-size: var(--font-base);
|
||||||
|
font-weight: var(--font-medium);
|
||||||
margin-bottom: var(--spacing-sm);
|
margin-bottom: var(--spacing-sm);
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: var(--tracking-wider);
|
letter-spacing: var(--tracking-wider);
|
||||||
@ -45,8 +47,8 @@ const props = defineProps<Props>()
|
|||||||
|
|
||||||
.balance-amount {
|
.balance-amount {
|
||||||
font-size: var(--font-4xl);
|
font-size: var(--font-4xl);
|
||||||
font-weight: var(--font-bold);
|
font-weight: var(--font-semibold);
|
||||||
color: var(--text-primary);
|
color: var(--primary-color);
|
||||||
margin-bottom: var(--spacing-lg);
|
margin-bottom: var(--spacing-lg);
|
||||||
letter-spacing: var(--tracking-tight);
|
letter-spacing: var(--tracking-tight);
|
||||||
}
|
}
|
||||||
@ -56,7 +58,6 @@ const props = defineProps<Props>()
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--spacing-sm);
|
gap: var(--spacing-sm);
|
||||||
color: var(--text-secondary);
|
|
||||||
font-size: var(--font-md);
|
font-size: var(--font-md);
|
||||||
|
|
||||||
.pending-label {
|
.pending-label {
|
||||||
@ -65,6 +66,7 @@ const props = defineProps<Props>()
|
|||||||
|
|
||||||
.pending-amount {
|
.pending-amount {
|
||||||
font-weight: var(--font-semibold);
|
font-weight: var(--font-semibold);
|
||||||
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { message } from 'ant-design-vue'
|
|||||||
import SeedPhraseDisplayComponent from '@/views/Auth/components/SeedPhraseDisplayComponent.vue'
|
import SeedPhraseDisplayComponent from '@/views/Auth/components/SeedPhraseDisplayComponent.vue'
|
||||||
import SendTransactionComponent from './SendTransactionComponent.vue'
|
import SendTransactionComponent from './SendTransactionComponent.vue'
|
||||||
import { WalletAddress, WalletBalance } from '.'
|
import { WalletAddress, WalletBalance } from '.'
|
||||||
import type { Utxo } from '@/interface'
|
import type { BalanceResult, Utxo } from '@/interface'
|
||||||
|
|
||||||
const neptuneStore = useNeptuneStore()
|
const neptuneStore = useNeptuneStore()
|
||||||
const {
|
const {
|
||||||
@ -18,8 +18,8 @@ const {
|
|||||||
} = useNeptuneWallet()
|
} = useNeptuneWallet()
|
||||||
const activeTabKey = inject<ComputedRef<string>>('activeTabKey')
|
const activeTabKey = inject<ComputedRef<string>>('activeTabKey')
|
||||||
|
|
||||||
const availableBalance = ref<string>('0.00000000')
|
const availableBalance = ref<BalanceResult['balance']>('0.00000000')
|
||||||
const pendingBalance = ref<string>('0.00000000')
|
const pendingBalance = ref< BalanceResult['pendingBalance']>('0.00000000')
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const sendingLoading = ref(false)
|
const sendingLoading = ref(false)
|
||||||
const error = ref<string | null>(null)
|
const error = ref<string | null>(null)
|
||||||
@ -28,6 +28,7 @@ const isSendingMode = ref(false)
|
|||||||
const isVerifyingPassword = ref(false)
|
const isVerifyingPassword = ref(false)
|
||||||
const passwordError = ref(false)
|
const passwordError = ref(false)
|
||||||
const isVerifying = ref(false)
|
const isVerifying = ref(false)
|
||||||
|
const seedPhrase = ref<string[]>([])
|
||||||
|
|
||||||
const receiveAddress = computed(() => neptuneStore.getWallet?.address || '')
|
const receiveAddress = computed(() => neptuneStore.getWallet?.address || '')
|
||||||
|
|
||||||
@ -96,15 +97,7 @@ const handleSendTransaction = async (data: {
|
|||||||
|
|
||||||
const handleBackupFile = async () => {
|
const handleBackupFile = async () => {
|
||||||
try {
|
try {
|
||||||
const seed = neptuneStore.getSeedPhraseString
|
await saveKeystoreAs()
|
||||||
const password = neptuneStore.getPassword
|
|
||||||
|
|
||||||
if (!seed || !password) {
|
|
||||||
message.error('Missing seed or password')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
await saveKeystoreAs(seed, password)
|
|
||||||
message.success('Keystore saved successfully')
|
message.success('Keystore saved successfully')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof Error && err.message.includes('User canceled')) return
|
if (err instanceof Error && err.message.includes('User canceled')) return
|
||||||
@ -126,7 +119,8 @@ const handlePasswordVerify = async (password: string) => {
|
|||||||
isVerifying.value = true
|
isVerifying.value = true
|
||||||
passwordError.value = false
|
passwordError.value = false
|
||||||
|
|
||||||
await decryptKeystore(password)
|
const result = await decryptKeystore(password)
|
||||||
|
seedPhrase.value = result.seedPhrase
|
||||||
|
|
||||||
isVerifyingPassword.value = false
|
isVerifyingPassword.value = false
|
||||||
showSeedModal.value = true
|
showSeedModal.value = true
|
||||||
@ -150,8 +144,8 @@ const loadWalletData = async () => {
|
|||||||
try {
|
try {
|
||||||
const result = await getBalance()
|
const result = await getBalance()
|
||||||
|
|
||||||
availableBalance.value = result?.balance || result || '0.00000000'
|
availableBalance.value = result?.balance ?? '0.00000000'
|
||||||
pendingBalance.value = result?.pendingBalance || result || '0.00000000'
|
pendingBalance.value = result?.pendingBalance ?? '0.00000000'
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error('Failed to load wallet data')
|
message.error('Failed to load wallet data')
|
||||||
} finally {
|
} finally {
|
||||||
@ -267,7 +261,7 @@ watch(
|
|||||||
@cancel="handleCloseModal"
|
@cancel="handleCloseModal"
|
||||||
>
|
>
|
||||||
<div class="seed-modal-content">
|
<div class="seed-modal-content">
|
||||||
<SeedPhraseDisplayComponent :back-button="false" :next-button="false" />
|
<SeedPhraseDisplayComponent :seed-phrase="seedPhrase" :back-button="false" :next-button="false" />
|
||||||
</div>
|
</div>
|
||||||
</ModalCommon>
|
</ModalCommon>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,6 +1,12 @@
|
|||||||
{
|
{
|
||||||
"extends": "@tsconfig/node20/tsconfig.json",
|
"extends": "@tsconfig/node20/tsconfig.json",
|
||||||
"include": ["vite.config.*", "vitest.config.*", "vite.config.ts", "env.d.ts"],
|
"include": [
|
||||||
|
"vite.config.*",
|
||||||
|
"vitest.config.*",
|
||||||
|
"vite.config.ts",
|
||||||
|
"env.d.ts",
|
||||||
|
"vite-plugin-csp.ts"
|
||||||
|
],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"composite": true,
|
"composite": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
|
|||||||
34
vite-plugin-csp.ts
Normal file
34
vite-plugin-csp.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import type { Plugin } from 'vite'
|
||||||
|
|
||||||
|
export function cspPlugin(): Plugin {
|
||||||
|
return {
|
||||||
|
name: 'vite-plugin-csp',
|
||||||
|
transformIndexHtml(html) {
|
||||||
|
const isDev = process.env.NODE_ENV === 'development'
|
||||||
|
const apiUrl = process.env.VITE_APP_API || 'http://zsmartex.com:8080'
|
||||||
|
|
||||||
|
const devUrl = apiUrl
|
||||||
|
const prodUrl = apiUrl.replace(/^http:/, 'https:')
|
||||||
|
|
||||||
|
const cspContent = isDev
|
||||||
|
? `default-src 'self' blob: data:;
|
||||||
|
script-src 'self' 'wasm-unsafe-eval' blob:;
|
||||||
|
style-src 'self' 'unsafe-inline';
|
||||||
|
connect-src 'self' ${devUrl};
|
||||||
|
img-src 'self' data:;`
|
||||||
|
: `default-src 'self' blob: data:;
|
||||||
|
script-src 'self' 'wasm-unsafe-eval' blob:;
|
||||||
|
style-src 'self';
|
||||||
|
connect-src 'self' ${devUrl};
|
||||||
|
img-src 'self' data:;`
|
||||||
|
|
||||||
|
return html.replace(
|
||||||
|
/<meta\s+http-equiv="Content-Security-Policy"[\s\S]*?\/>/,
|
||||||
|
`<meta
|
||||||
|
http-equiv="Content-Security-Policy"
|
||||||
|
content="${cspContent}"
|
||||||
|
/>`
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,27 +5,34 @@ import vueJsx from '@vitejs/plugin-vue-jsx'
|
|||||||
import VueDevTools from 'vite-plugin-vue-devtools'
|
import VueDevTools from 'vite-plugin-vue-devtools'
|
||||||
import Components from 'unplugin-vue-components/vite'
|
import Components from 'unplugin-vue-components/vite'
|
||||||
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'
|
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'
|
||||||
|
import { cspPlugin } from './vite-plugin-csp'
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
server: {
|
server: {
|
||||||
port: 3008,
|
port: 3008,
|
||||||
},
|
},
|
||||||
base: './',
|
base: './',
|
||||||
plugins: [vue(), vueJsx(), VueDevTools(), Components({
|
plugins: [
|
||||||
resolvers: [AntDesignVueResolver({importStyle: false})],
|
cspPlugin(),
|
||||||
})],
|
vue(),
|
||||||
|
vueJsx(),
|
||||||
|
VueDevTools(),
|
||||||
|
Components({
|
||||||
|
resolvers: [AntDesignVueResolver({ importStyle: false })],
|
||||||
|
}),
|
||||||
|
],
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
exclude: ['@neptune/wasm', '@neptune/native'],
|
exclude: ['@neptune/wasm', '@neptune/native'],
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
external: ['@neptune/wasm', '@neptune/native'],
|
external: ['@neptune/wasm', '@neptune/native'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
css: {
|
css: {
|
||||||
preprocessorOptions: {
|
preprocessorOptions: {
|
||||||
scss: {
|
scss: {
|
||||||
silenceDeprecations: ['import'],
|
silenceDeprecations: ['import', 'legacy-js-api'],
|
||||||
additionalData: `
|
additionalData: `
|
||||||
@import "@/assets/scss/__variables.scss";
|
@import "@/assets/scss/__variables.scss";
|
||||||
@import "@/assets/scss/__mixin.scss";
|
@import "@/assets/scss/__mixin.scss";
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user