Compare commits
No commits in common. "main" and "draply/mac-os-support" have entirely different histories.
main
...
draply/mac
109
README.md
109
README.md
@ -1,118 +1,31 @@
|
|||||||
# Neptune Web Wallet
|
# web-wallet
|
||||||
|
|
||||||
A secure Electron-based desktop wallet for the Neptune blockchain network.
|
## Project Setup
|
||||||
|
|
||||||
## 🚀 Features
|
|
||||||
|
|
||||||
- 🔐 Secure keystore encryption (AES-256-GCM)
|
|
||||||
- 💼 Create and recover wallets from seed phrases
|
|
||||||
- 💸 Send and receive Neptune tokens
|
|
||||||
- 📊 View transaction history and UTXOs
|
|
||||||
- 🛡️ Enhanced security with strict Content Security Policy
|
|
||||||
|
|
||||||
## 📋 Prerequisites
|
|
||||||
|
|
||||||
- Node.js >= 16
|
|
||||||
- npm or yarn
|
|
||||||
|
|
||||||
## 🔧 Installation
|
|
||||||
|
|
||||||
Install dependencies:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm install
|
yarn
|
||||||
```
|
```
|
||||||
|
|
||||||
## 💻 Development
|
### Compile and Hot-Reload for Development
|
||||||
|
|
||||||
### Start Electron app in development mode
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm run start:electron
|
yarn dev
|
||||||
```
|
```
|
||||||
|
|
||||||
### Start Vite dev server only
|
### Type-Check, Compile and Minify for Production
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm run dev
|
yarn build-only
|
||||||
```
|
```
|
||||||
|
|
||||||
### Type-check
|
### Lint with [ESLint](https://eslint.org/)
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm run type-check
|
yarn lint
|
||||||
```
|
```
|
||||||
|
|
||||||
### Lint with ESLint
|
### Format code
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm run lint
|
yarn format
|
||||||
```
|
```
|
||||||
|
|
||||||
### Format code with Prettier
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run format
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📦 Production Build
|
|
||||||
|
|
||||||
### Package the application
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run package:electron
|
|
||||||
```
|
|
||||||
|
|
||||||
### Create distributables (installers)
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run make:electron
|
|
||||||
```
|
|
||||||
|
|
||||||
The installers will be generated in `out/make/` directory:
|
|
||||||
- **Windows**: `.exe` installer in `out/make/squirrel.windows/x64/`
|
|
||||||
- **macOS**: `.zip` in `out/make/zip/darwin/`
|
|
||||||
- **Linux**: `.deb` and `.rpm` in respective directories
|
|
||||||
|
|
||||||
## 🔐 Security Features
|
|
||||||
|
|
||||||
- ✅ Context isolation enabled
|
|
||||||
- ✅ Node integration disabled
|
|
||||||
- ✅ Sandbox enabled
|
|
||||||
- ✅ Strict Content Security Policy in production
|
|
||||||
- ✅ Certificate validation
|
|
||||||
- ✅ Path traversal protection
|
|
||||||
- ✅ Input validation for all IPC handlers
|
|
||||||
- ✅ Secure keystore encryption with scrypt and AES-256-GCM
|
|
||||||
|
|
||||||
## 🌍 Environment Variables
|
|
||||||
|
|
||||||
Create a `.env` file in the root directory:
|
|
||||||
|
|
||||||
```env
|
|
||||||
# Neptune API URL
|
|
||||||
VITE_APP_API=
|
|
||||||
|
|
||||||
# Network (mainnet or testnet)
|
|
||||||
VITE_NODE_NETWORK=mainnet
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🛠️ Tech Stack
|
|
||||||
|
|
||||||
- **Framework**: Electron + Vue 3 + TypeScript
|
|
||||||
- **Build Tool**: Vite
|
|
||||||
- **State Management**: Pinia
|
|
||||||
|
|
||||||
## 📝 License
|
|
||||||
|
|
||||||
Apache-2.0
|
|
||||||
|
|
||||||
## 👥 Authors
|
|
||||||
|
|
||||||
Neptune Team
|
|
||||||
|
|
||||||
## 🔗 Links
|
|
||||||
|
|
||||||
- [Neptune Blockchain](https://neptune.cash)
|
|
||||||
- [Documentation](#)
|
|
||||||
- [Report Issues](#)
|
|
||||||
|
|||||||
@ -2,107 +2,36 @@ import { ipcMain, dialog, app } from 'electron'
|
|||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { encrypt, fromEncryptedJson } from './utils/keystore'
|
import { encrypt, fromEncryptedJson } from './utils/keystore'
|
||||||
import logger from './logger'
|
|
||||||
|
|
||||||
let neptuneNative: any = null
|
const neptuneNative = require('@neptune/native')
|
||||||
|
|
||||||
function loadNativeModule() {
|
|
||||||
try {
|
|
||||||
// Try normal require first (works in dev)
|
|
||||||
neptuneNative = require('@neptune/native')
|
|
||||||
logger.info('[Native] Loaded native module')
|
|
||||||
return
|
|
||||||
} catch (err) {
|
|
||||||
logger.error('[Native] Failed to load native module')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback: load from Resources in packaged app
|
|
||||||
try {
|
|
||||||
const platform = process.platform
|
|
||||||
const arch = process.arch
|
|
||||||
|
|
||||||
// Determine the correct .node file
|
|
||||||
let nodeFileName = ''
|
|
||||||
if (platform === 'win32' && arch === 'x64') {
|
|
||||||
nodeFileName = 'neptune-native.win32-x64-msvc.node'
|
|
||||||
} else if (platform === 'linux' && arch === 'x64') {
|
|
||||||
nodeFileName = 'neptune-native.linux-x64-gnu.node'
|
|
||||||
} else if (platform === 'darwin' && arch === 'arm64') {
|
|
||||||
nodeFileName = 'neptune-native.darwin-arm64.node'
|
|
||||||
} else {
|
|
||||||
throw new Error(`Unsupported platform: ${platform}-${arch}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try multiple possible locations
|
|
||||||
const possiblePaths = [
|
|
||||||
path.join(process.resourcesPath, 'packages', 'neptune-native', nodeFileName),
|
|
||||||
path.join(process.resourcesPath, 'neptune-native', nodeFileName),
|
|
||||||
path.join(process.resourcesPath, nodeFileName),
|
|
||||||
path.join(process.resourcesPath, 'app.asar.unpacked', 'packages', 'neptune-native', nodeFileName),
|
|
||||||
path.join(process.resourcesPath, 'app.asar.unpacked', 'node_modules', '@neptune', 'native', nodeFileName),
|
|
||||||
]
|
|
||||||
|
|
||||||
let nativeBinding: any = null
|
|
||||||
for (const nodePath of possiblePaths) {
|
|
||||||
if (fs.existsSync(nodePath)) {
|
|
||||||
nativeBinding = require(nodePath)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nativeBinding) {
|
|
||||||
throw new Error(`Native module not found`)
|
|
||||||
}
|
|
||||||
|
|
||||||
neptuneNative = nativeBinding
|
|
||||||
logger.info('[Native] Successfully loaded native module')
|
|
||||||
} catch (error) {
|
|
||||||
logger.error('[Native] Failed to load native module:')
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the native module
|
|
||||||
loadNativeModule()
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Create keystore into default wallets directory
|
||||||
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 })
|
||||||
|
|
||||||
|
// Use timestamp for filename
|
||||||
const timestamp = Date.now()
|
const timestamp = Date.now()
|
||||||
const fileName = `neptune-wallet-${timestamp}.json`
|
const fileName = `neptune-wallet-${timestamp}.json`
|
||||||
const filePath = path.join(WALLETS_DIR, fileName)
|
const filePath = path.join(savePath, fileName)
|
||||||
fs.writeFileSync(filePath, keystore, 'utf-8')
|
fs.writeFileSync(filePath, keystore)
|
||||||
return { success: true, fileName }
|
|
||||||
} catch (error: any) {
|
return { filePath }
|
||||||
logger.error('Error creating keystore:', error.message)
|
} catch (error) {
|
||||||
|
console.error('Error creating keystore:', error)
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.handle('wallet:saveKeystoreAs', async (_event, fileName: string) => {
|
// New handler: let user choose folder and filename to save keystore
|
||||||
|
ipcMain.handle('wallet:saveKeystoreAs', async (_event, seed: string, password: string) => {
|
||||||
try {
|
try {
|
||||||
const pathToFileName = safeResolvePath(fileName)
|
const keystore = await encrypt(seed, password)
|
||||||
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({
|
||||||
@ -111,154 +40,155 @@ ipcMain.handle('wallet:saveKeystoreAs', async (_event, fileName: string) => {
|
|||||||
filters: [{ name: 'JSON', extensions: ['json'] }],
|
filters: [{ name: 'JSON', extensions: ['json'] }],
|
||||||
})
|
})
|
||||||
|
|
||||||
if (canceled || !filePath) return { success: false, filePath: null }
|
if (canceled || !filePath) return { 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, 'utf-8')
|
fs.writeFileSync(filePath, keystore)
|
||||||
return { success: true, filePath }
|
|
||||||
} catch (error: any) {
|
return { filePath }
|
||||||
logger.error('Error saving keystore (Save As):', error.message)
|
} catch (error) {
|
||||||
|
console.error('Error saving keystore (Save As):', error)
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.handle('wallet:decryptKeystore', async (_event, fileName: string, password: string) => {
|
ipcMain.handle('wallet:decryptKeystore', async (_event, filePath, password) => {
|
||||||
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) {
|
||||||
logger.error('Error decrypting keystore ipc:', error.message)
|
console.error('Error decrypting keystore ipc:', error)
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.handle('wallet:checkKeystore', async () => {
|
ipcMain.handle('wallet:checkKeystore', async () => {
|
||||||
try {
|
try {
|
||||||
if (!fs.existsSync(WALLETS_DIR)) return { exists: false, fileName: null }
|
const walletDir = path.join(process.cwd(), 'wallets')
|
||||||
|
if (!fs.existsSync(walletDir)) return { exists: false, filePath: null }
|
||||||
|
|
||||||
const newestFile = fs
|
const newestFile = fs
|
||||||
.readdirSync(WALLETS_DIR)
|
.readdirSync(walletDir)
|
||||||
.filter((f) => f.endsWith('.json'))
|
.filter((f) => f.endsWith('.json'))
|
||||||
.sort(
|
.sort(
|
||||||
(a, b) =>
|
(a, b) =>
|
||||||
fs.statSync(path.join(WALLETS_DIR, b)).mtime.getTime() -
|
fs.statSync(path.join(walletDir, b)).mtime.getTime() -
|
||||||
fs.statSync(path.join(WALLETS_DIR, a)).mtime.getTime()
|
fs.statSync(path.join(walletDir, a)).mtime.getTime()
|
||||||
)[0]
|
)[0]
|
||||||
|
|
||||||
if (!newestFile) return { exists: false, fileName: null }
|
if (!newestFile) return { exists: false, filePath: 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
|
|
||||||
} catch (error: any) {
|
if (typeof height === 'number' && Number.isFinite(height)) {
|
||||||
logger.warn('Unable to read minBlockHeight from keystore:', error.message)
|
minBlockHeight = height
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Unable to read minBlockHeight from keystore:', error)
|
||||||
}
|
}
|
||||||
return { exists: true, fileName: newestFile, minBlockHeight }
|
|
||||||
} catch (error: any) {
|
return { exists: true, filePath: resolvedPath, minBlockHeight }
|
||||||
logger.error('Error checking keystore ipc:', error.message)
|
} catch (error) {
|
||||||
return { exists: false, fileName: null, minBlockHeight: null, error: error.message }
|
console.error('Error checking keystore ipc:', error)
|
||||||
|
return { exists: false, filePath: null, minBlockHeight: null, error: String(error) }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.handle(
|
ipcMain.handle(
|
||||||
'wallet:updateMinBlockHeight',
|
'wallet:updateMinBlockHeight',
|
||||||
async (_event, fileName: string | null, minBlockHeight: number | null) => {
|
async (_event, filePath: string | null, minBlockHeight: number | null) => {
|
||||||
if (!fileName) {
|
if (!filePath) {
|
||||||
return { success: false, error: 'No keystore file name provided.' }
|
return { success: false, error: 'No keystore file path provided.' }
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const filePath = safeResolvePath(fileName)
|
const normalizedPath = path.isAbsolute(filePath)
|
||||||
if (!fs.existsSync(filePath)) {
|
? 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
|
|
||||||
fs.writeFileSync(filePath, JSON.stringify(walletJson, null, 2), 'utf-8')
|
if (minBlockHeight === null || Number.isNaN(minBlockHeight)) {
|
||||||
|
walletJson.minBlockHeight = null
|
||||||
|
} else {
|
||||||
|
walletJson.minBlockHeight = minBlockHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(normalizedPath, JSON.stringify(walletJson, null, 2), 'utf-8')
|
||||||
|
|
||||||
return { success: true, minBlockHeight }
|
return { success: true, minBlockHeight }
|
||||||
} catch (error: any) {
|
} catch (error) {
|
||||||
logger.error('Error updating min block height:', error.message)
|
console.error('Error updating min block height:', error)
|
||||||
return { success: false, error: error.message }
|
return { success: false, error: String(error) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
ipcMain.handle('wallet:getMinBlockHeight', async (_event, fileName: string | null) => {
|
ipcMain.handle(
|
||||||
if (!fileName) {
|
'wallet:getMinBlockHeight',
|
||||||
return { success: false, error: 'No keystore file name provided.', minBlockHeight: null }
|
async (_event, filePath: string | null) => {
|
||||||
}
|
if (!filePath) {
|
||||||
try {
|
return { success: false, error: 'No keystore file path provided.', minBlockHeight: null }
|
||||||
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)
|
try {
|
||||||
const height = walletJson?.minBlockHeight
|
const normalizedPath = path.isAbsolute(filePath)
|
||||||
return {
|
? filePath
|
||||||
success: true,
|
: path.join(process.cwd(), filePath)
|
||||||
minBlockHeight: Number.isFinite(height) ? height : null,
|
|
||||||
|
if (!fs.existsSync(normalizedPath)) {
|
||||||
|
return { success: false, error: 'Keystore file not found.', minBlockHeight: null }
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileContents = fs.readFileSync(normalizedPath, 'utf-8')
|
||||||
|
const walletJson = JSON.parse(fileContents)
|
||||||
|
const height = walletJson?.minBlockHeight
|
||||||
|
|
||||||
|
if (typeof height === 'number' && Number.isFinite(height)) {
|
||||||
|
return { success: true, minBlockHeight: height }
|
||||||
|
}
|
||||||
|
|
||||||
|
return { success: true, minBlockHeight: null }
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error reading min block height:', error)
|
||||||
|
return { success: false, error: String(error), minBlockHeight: null }
|
||||||
}
|
}
|
||||||
} 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 JSON.parse(wallet.generateKeysFromSeed(seedPhrase))
|
return wallet.generateKeysFromSeed(seedPhrase)
|
||||||
} catch (error: any) {
|
} catch (error) {
|
||||||
logger.error('Error generating keys from seed ipc:', error.message)
|
console.error('Error generating keys from seed ipc:', error)
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
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,
|
||||||
spendingKeyHex,
|
spendingKeyHex,
|
||||||
inputAdditionRecords,
|
inputAdditionRecords,
|
||||||
|
// pass minBlockHeight from args if provided, default 0
|
||||||
typeof args?.minBlockHeight === 'number' && Number.isFinite(args.minBlockHeight)
|
typeof args?.minBlockHeight === 'number' && Number.isFinite(args.minBlockHeight)
|
||||||
? args.minBlockHeight
|
? args.minBlockHeight
|
||||||
: 0,
|
: 0,
|
||||||
@ -267,12 +197,8 @@ ipcMain.handle('wallet:buildTransaction', async (_event, args) => {
|
|||||||
fee
|
fee
|
||||||
)
|
)
|
||||||
return JSON.parse(result)
|
return JSON.parse(result)
|
||||||
} catch (error: any) {
|
} catch (error) {
|
||||||
logger.error('Error building transaction ipc:', error.message)
|
console.error('Error building transaction with primitive proof ipc:', error)
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.on('log:info', (_, ...msg: string[]) => logger.info(...msg))
|
|
||||||
ipcMain.on('log:warn', (_, ...msg: string[]) => logger.warn(...msg))
|
|
||||||
ipcMain.on('log:error', (_, ...msg: string[]) => logger.error(...msg))
|
|
||||||
|
|||||||
@ -1,27 +0,0 @@
|
|||||||
import { app } from 'electron'
|
|
||||||
import log from 'electron-log'
|
|
||||||
|
|
||||||
const isDev = app.isPackaged
|
|
||||||
|
|
||||||
if (!isDev) {
|
|
||||||
log.transports.file.level = 'info'
|
|
||||||
log.transports.console.level = false
|
|
||||||
log.transports.file.format = '{y}-{m}-{d} {h}:{i}:{s} [{level}] {text}'
|
|
||||||
}
|
|
||||||
|
|
||||||
export const logger = {
|
|
||||||
info: (...args: string[]) => {
|
|
||||||
if (!isDev) log.info(...args)
|
|
||||||
},
|
|
||||||
warn: (...args: string[]) => {
|
|
||||||
if (!isDev) log.warn(...args)
|
|
||||||
},
|
|
||||||
error: (...args: string[]) => {
|
|
||||||
if (!isDev) log.error(...args)
|
|
||||||
},
|
|
||||||
debug: (...args: string[]) => {
|
|
||||||
if (!isDev) log.debug(...args)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
export default logger
|
|
||||||
@ -2,29 +2,12 @@ import { app, BrowserWindow } from 'electron'
|
|||||||
import path from 'node:path'
|
import path from 'node:path'
|
||||||
import started from 'electron-squirrel-startup'
|
import started from 'electron-squirrel-startup'
|
||||||
import './ipcHandlers'
|
import './ipcHandlers'
|
||||||
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')
|
|
||||||
const mainWindow = new BrowserWindow({
|
const mainWindow = new BrowserWindow({
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 800,
|
height: 800,
|
||||||
@ -35,8 +18,6 @@ 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) {
|
||||||
@ -45,48 +26,7 @@ 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`))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Security: Prevent opening new windows - block all window.open() calls
|
mainWindow.webContents.openDevTools()
|
||||||
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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method will be called when Electron has finished
|
// This method will be called when Electron has finished
|
||||||
@ -98,7 +38,6 @@ app.on('ready', createWindow)
|
|||||||
// for applications and their menu bar to stay active until the user quits
|
// for applications and their menu bar to stay active until the user quits
|
||||||
// explicitly with Cmd + Q.
|
// explicitly with Cmd + Q.
|
||||||
app.on('window-all-closed', () => {
|
app.on('window-all-closed', () => {
|
||||||
logger.info('App closed')
|
|
||||||
if (process.platform !== 'darwin') {
|
if (process.platform !== 'darwin') {
|
||||||
app.quit()
|
app.quit()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,21 +5,16 @@ 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: (fileName: string) => ipcRenderer.invoke('wallet:saveKeystoreAs', fileName),
|
saveKeystoreAs: (seed: string, password: string) =>
|
||||||
decryptKeystore: (fileName: string, password: string) =>
|
ipcRenderer.invoke('wallet:saveKeystoreAs', seed, password),
|
||||||
ipcRenderer.invoke('wallet:decryptKeystore', fileName, password),
|
decryptKeystore: (filePath: string, password: string) =>
|
||||||
|
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: (fileName: string | null, minBlockHeight: number | null) =>
|
updateMinBlockHeight: (filePath: string | null, minBlockHeight: number | null) =>
|
||||||
ipcRenderer.invoke('wallet:updateMinBlockHeight', fileName, minBlockHeight),
|
ipcRenderer.invoke('wallet:updateMinBlockHeight', filePath, minBlockHeight),
|
||||||
getMinBlockHeight: (fileName: string | null) =>
|
getMinBlockHeight: (filePath: string | null) =>
|
||||||
ipcRenderer.invoke('wallet:getMinBlockHeight', fileName),
|
ipcRenderer.invoke('wallet:getMinBlockHeight', filePath),
|
||||||
})
|
|
||||||
|
|
||||||
contextBridge.exposeInMainWorld('logger', {
|
|
||||||
info: (...msg: any[]) => ipcRenderer.send('log:info', ...msg),
|
|
||||||
warn: (...msg: any[]) => ipcRenderer.send('log:warn', ...msg),
|
|
||||||
error: (...msg: any[]) => ipcRenderer.send('log:error', ...msg),
|
|
||||||
})
|
})
|
||||||
|
|||||||
@ -6,26 +6,14 @@ import { MakerRpm } from '@electron-forge/maker-rpm';
|
|||||||
import { VitePlugin } from '@electron-forge/plugin-vite';
|
import { VitePlugin } from '@electron-forge/plugin-vite';
|
||||||
import { FusesPlugin } from '@electron-forge/plugin-fuses';
|
import { FusesPlugin } from '@electron-forge/plugin-fuses';
|
||||||
import { FuseV1Options, FuseVersion } from '@electron/fuses';
|
import { FuseV1Options, FuseVersion } from '@electron/fuses';
|
||||||
import { AutoUnpackNativesPlugin } from '@electron-forge/plugin-auto-unpack-natives';
|
|
||||||
|
|
||||||
const config: ForgeConfig = {
|
const config: ForgeConfig = {
|
||||||
packagerConfig: {
|
packagerConfig: {
|
||||||
asar: true,
|
asar: true,
|
||||||
extraResource: [
|
|
||||||
'./packages/neptune-native',
|
|
||||||
'./packages/neptune-wasm',
|
|
||||||
]
|
|
||||||
},
|
|
||||||
rebuildConfig: {
|
|
||||||
onlyModules: ['@neptune/native'],
|
|
||||||
force: true,
|
|
||||||
},
|
},
|
||||||
|
rebuildConfig: {},
|
||||||
makers: [
|
makers: [
|
||||||
new MakerSquirrel({
|
new MakerSquirrel({}),
|
||||||
name: 'neptune-web-wallet',
|
|
||||||
authors: 'Neptune Team',
|
|
||||||
description: 'Neptune Blockchain Wallet - Secure cryptocurrency wallet for Neptune network',
|
|
||||||
}),
|
|
||||||
new MakerZIP({}, ['darwin']),
|
new MakerZIP({}, ['darwin']),
|
||||||
new MakerRpm({}),
|
new MakerRpm({}),
|
||||||
new MakerDeb({}),
|
new MakerDeb({}),
|
||||||
@ -65,9 +53,6 @@ const config: ForgeConfig = {
|
|||||||
[FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
|
[FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
|
||||||
[FuseV1Options.OnlyLoadAppFromAsar]: true,
|
[FuseV1Options.OnlyLoadAppFromAsar]: true,
|
||||||
}),
|
}),
|
||||||
new AutoUnpackNativesPlugin({
|
|
||||||
packageJsonPropNames: ['@neptune/native'],
|
|
||||||
}),
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
<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" />
|
||||||
|
|
||||||
<title>Neptune Web Wallet</title>
|
<title>Neptune Web Wallet</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
494
package-lock.json
generated
494
package-lock.json
generated
@ -15,10 +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",
|
||||||
"electron-log": "^5.4.3",
|
"crypto": "^1.0.1",
|
||||||
"electron-squirrel-startup": "^1.0.1",
|
"electron-squirrel-startup": "^1.0.1",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"vue": "^3.5.24",
|
"vue": "^3.4.21",
|
||||||
"vue-router": "^4.3.0",
|
"vue-router": "^4.3.0",
|
||||||
"vue3-i18n": "^1.1.5"
|
"vue3-i18n": "^1.1.5"
|
||||||
},
|
},
|
||||||
@ -32,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.15.0",
|
"@rushstack/eslint-patch": "^1.8.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.19.25",
|
"@types/node": "^20.12.5",
|
||||||
"@vitejs/plugin-vue": "^5.0.4",
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
"@vitejs/plugin-vue-jsx": "^5.1.1",
|
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||||
"@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",
|
||||||
@ -46,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.94.0",
|
"sass": "^1.75.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.4.21",
|
"vite": "^5.2.8",
|
||||||
"vite-plugin-vue-devtools": "^7.0.25",
|
"vite-plugin-vue-devtools": "^7.0.25",
|
||||||
"vue-tsc": "^2.0.11"
|
"vue-tsc": "^2.0.11"
|
||||||
}
|
}
|
||||||
@ -1976,9 +1976,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@inquirer/core/node_modules/@types/node": {
|
"node_modules/@inquirer/core/node_modules/@types/node": {
|
||||||
"version": "22.19.1",
|
"version": "22.19.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.0.tgz",
|
||||||
"integrity": "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==",
|
"integrity": "sha512-xpr/lmLPQEj+TUnHmR+Ab91/glhJvsqcjB+yY0Ix9GO70H6Lb4FHH5GeqdOE5btAx7eIMwuHkp4H2MSkLcqWbA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -2016,9 +2016,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@inquirer/figures": {
|
"node_modules/@inquirer/figures": {
|
||||||
"version": "1.0.15",
|
"version": "1.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz",
|
"resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.14.tgz",
|
||||||
"integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==",
|
"integrity": "sha512-DbFgdt+9/OZYFM+19dbpXOSeAstPy884FPy1KjDu4anWwymZeOYhMY1mdFri172htv6mvc/uvIAAi7b7tvjJBQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -2699,13 +2699,6 @@
|
|||||||
"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",
|
||||||
@ -2743,9 +2736,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz",
|
||||||
"integrity": "sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==",
|
"integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@ -2757,9 +2750,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm64": {
|
"node_modules/@rollup/rollup-android-arm64": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz",
|
||||||
"integrity": "sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==",
|
"integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -2771,9 +2764,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz",
|
||||||
"integrity": "sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==",
|
"integrity": "sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -2785,9 +2778,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-darwin-x64": {
|
"node_modules/@rollup/rollup-darwin-x64": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz",
|
||||||
"integrity": "sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==",
|
"integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -2799,9 +2792,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz",
|
||||||
"integrity": "sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==",
|
"integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -2813,9 +2806,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz",
|
||||||
"integrity": "sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==",
|
"integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -2827,9 +2820,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz",
|
||||||
"integrity": "sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==",
|
"integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@ -2841,9 +2834,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz",
|
||||||
"integrity": "sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==",
|
"integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@ -2855,9 +2848,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz",
|
||||||
"integrity": "sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==",
|
"integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -2869,9 +2862,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz",
|
||||||
"integrity": "sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==",
|
"integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -2883,9 +2876,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-loong64-gnu": {
|
"node_modules/@rollup/rollup-linux-loong64-gnu": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz",
|
||||||
"integrity": "sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==",
|
"integrity": "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"loong64"
|
"loong64"
|
||||||
],
|
],
|
||||||
@ -2897,9 +2890,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz",
|
||||||
"integrity": "sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==",
|
"integrity": "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
@ -2911,9 +2904,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz",
|
||||||
"integrity": "sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==",
|
"integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
@ -2925,9 +2918,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz",
|
||||||
"integrity": "sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==",
|
"integrity": "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
@ -2939,9 +2932,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz",
|
||||||
"integrity": "sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==",
|
"integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"s390x"
|
"s390x"
|
||||||
],
|
],
|
||||||
@ -2953,9 +2946,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz",
|
||||||
"integrity": "sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==",
|
"integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -2967,9 +2960,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz",
|
||||||
"integrity": "sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==",
|
"integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -2981,9 +2974,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-openharmony-arm64": {
|
"node_modules/@rollup/rollup-openharmony-arm64": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz",
|
||||||
"integrity": "sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==",
|
"integrity": "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -2995,9 +2988,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz",
|
||||||
"integrity": "sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==",
|
"integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -3009,9 +3002,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz",
|
||||||
"integrity": "sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==",
|
"integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
@ -3023,9 +3016,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-x64-gnu": {
|
"node_modules/@rollup/rollup-win32-x64-gnu": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz",
|
||||||
"integrity": "sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==",
|
"integrity": "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -3037,9 +3030,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz",
|
||||||
"integrity": "sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==",
|
"integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -3051,9 +3044,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rushstack/eslint-patch": {
|
"node_modules/@rushstack/eslint-patch": {
|
||||||
"version": "1.15.0",
|
"version": "1.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.14.1.tgz",
|
||||||
"integrity": "sha512-ojSshQPKwVvSMR8yT2L/QtUkV5SXi/IfDiJ4/8d6UbTPjiHVmxZzUAzGD8Tzks1b9+qQkZa0isUOvYObedITaw==",
|
"integrity": "sha512-jGTk8UD/RdjsNZW8qq10r0RBvxL8OWtoT+kImlzPDFilmozzM+9QmIJsmze9UiSBrFU45ZxhTYBypn9q9z/VfQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
@ -3124,9 +3117,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tsconfig/node20": {
|
"node_modules/@tsconfig/node20": {
|
||||||
"version": "20.1.7",
|
"version": "20.1.6",
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.6.tgz",
|
||||||
"integrity": "sha512-Lt137u6AoCCJNNklpNtfGIYFEywma7Hd3B083jqMga37opSEVw7beWsD4OTXyzKS0I3G2kbQJVoZpOxy9GnxBQ==",
|
"integrity": "sha512-sz+Hqx9zwZDpZIV871WSbUzSqNIsXzghZydypnfgzPKLltVJfkINfUeTct31n/tTSa9ZE1ZOfKdRre1uHHquYQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
@ -3225,9 +3218,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "20.19.25",
|
"version": "20.19.24",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.24.tgz",
|
||||||
"integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==",
|
"integrity": "sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -3503,23 +3496,21 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitejs/plugin-vue-jsx": {
|
"node_modules/@vitejs/plugin-vue-jsx": {
|
||||||
"version": "5.1.1",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-3.1.0.tgz",
|
||||||
"integrity": "sha512-uQkfxzlF8SGHJJVH966lFTdjM/lGcwJGzwAHpVqAPDD/QcsqoUGa+q31ox1BrUfi+FLP2ChVp7uLXE3DkHyDdQ==",
|
"integrity": "sha512-w9M6F3LSEU5kszVb9An2/MmXNxocAnUb3WhRr8bHlimhDrXNt6n6D2nJQR3UXpGlZHh/EsgouOHCsM8V3Ln+WA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.28.3",
|
"@babel/core": "^7.23.3",
|
||||||
"@babel/plugin-syntax-typescript": "^7.27.1",
|
"@babel/plugin-transform-typescript": "^7.23.3",
|
||||||
"@babel/plugin-transform-typescript": "^7.28.0",
|
"@vue/babel-plugin-jsx": "^1.1.5"
|
||||||
"@rolldown/pluginutils": "^1.0.0-beta.34",
|
|
||||||
"@vue/babel-plugin-jsx": "^1.5.0"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^14.18.0 || >=16.0.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
|
"vite": "^4.0.0 || ^5.0.0",
|
||||||
"vue": "^3.0.0"
|
"vue": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -3613,39 +3604,39 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-core": {
|
"node_modules/@vue/compiler-core": {
|
||||||
"version": "3.5.24",
|
"version": "3.5.23",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.24.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.23.tgz",
|
||||||
"integrity": "sha512-eDl5H57AOpNakGNAkFDH+y7kTqrQpJkZFXhWZQGyx/5Wh7B1uQYvcWkvZi11BDhscPgj8N7XV3oRwiPnx1Vrig==",
|
"integrity": "sha512-nW7THWj5HOp085ROk65LwaoxuzDsjIxr485F4iu63BoxsXoSqKqmsUUoP4A7Gl67DgIgi0zJ8JFgHfvny/74MA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.28.5",
|
"@babel/parser": "^7.28.5",
|
||||||
"@vue/shared": "3.5.24",
|
"@vue/shared": "3.5.23",
|
||||||
"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.24",
|
"version": "3.5.23",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.24.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.23.tgz",
|
||||||
"integrity": "sha512-1QHGAvs53gXkWdd3ZMGYuvQFXHW4ksKWPG8HP8/2BscrbZ0brw183q2oNWjMrSWImYLHxHrx1ItBQr50I/q2zw==",
|
"integrity": "sha512-AT8RMw0vEzzzO0JU5gY0F6iCzaWUIh/aaRVordzMBKXRpoTllTT4kocHDssByPsvodNCfump/Lkdow2mT/O5KQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-core": "3.5.24",
|
"@vue/compiler-core": "3.5.23",
|
||||||
"@vue/shared": "3.5.24"
|
"@vue/shared": "3.5.23"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-sfc": {
|
"node_modules/@vue/compiler-sfc": {
|
||||||
"version": "3.5.24",
|
"version": "3.5.23",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.24.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.23.tgz",
|
||||||
"integrity": "sha512-8EG5YPRgmTB+YxYBM3VXy8zHD9SWHUJLIGPhDovo3Z8VOgvP+O7UP5vl0J4BBPWYD9vxtBabzW1EuEZ+Cqs14g==",
|
"integrity": "sha512-3QTEUo4qg7FtQwaDJa8ou1CUikx5WTtZlY61rRRDu3lK2ZKrGoAGG8mvDgOpDsQ4A1bez9s+WtBB6DS2KuFCPw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.28.5",
|
"@babel/parser": "^7.28.5",
|
||||||
"@vue/compiler-core": "3.5.24",
|
"@vue/compiler-core": "3.5.23",
|
||||||
"@vue/compiler-dom": "3.5.24",
|
"@vue/compiler-dom": "3.5.23",
|
||||||
"@vue/compiler-ssr": "3.5.24",
|
"@vue/compiler-ssr": "3.5.23",
|
||||||
"@vue/shared": "3.5.24",
|
"@vue/shared": "3.5.23",
|
||||||
"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",
|
||||||
@ -3653,13 +3644,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-ssr": {
|
"node_modules/@vue/compiler-ssr": {
|
||||||
"version": "3.5.24",
|
"version": "3.5.23",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.24.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.23.tgz",
|
||||||
"integrity": "sha512-trOvMWNBMQ/odMRHW7Ae1CdfYx+7MuiQu62Jtu36gMLXcaoqKvAyh+P73sYG9ll+6jLB6QPovqoKGGZROzkFFg==",
|
"integrity": "sha512-Hld2xphbMjXs9Q9WKxPf2EqmE+Rq/FEDnK/wUBtmYq74HCV4XDdSCheAaB823OQXIIFGq9ig/RbAZkF9s4U0Ow==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.5.24",
|
"@vue/compiler-dom": "3.5.23",
|
||||||
"@vue/shared": "3.5.24"
|
"@vue/shared": "3.5.23"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-vue2": {
|
"node_modules/@vue/compiler-vue2": {
|
||||||
@ -3680,14 +3671,14 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@vue/devtools-core": {
|
"node_modules/@vue/devtools-core": {
|
||||||
"version": "7.7.8",
|
"version": "7.7.7",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-7.7.8.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-7.7.7.tgz",
|
||||||
"integrity": "sha512-EVLQTYML/v77JFA3Q8zvVANCvEv1WtG0TMo+HQR5eZ7PpEzSmVbEcBp2C1/OXyn8EJO4mHEeParMLpp43prUOw==",
|
"integrity": "sha512-9z9TLbfC+AjAi1PQyWX+OErjIaJmdFlbDHcD+cAMYKY6Bh5VlsAtCeGyRMrXwIlMEQPukvnWt3gZBLwTAIMKzQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/devtools-kit": "^7.7.8",
|
"@vue/devtools-kit": "^7.7.7",
|
||||||
"@vue/devtools-shared": "^7.7.8",
|
"@vue/devtools-shared": "^7.7.7",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
"nanoid": "^5.1.0",
|
"nanoid": "^5.1.0",
|
||||||
"pathe": "^2.0.3",
|
"pathe": "^2.0.3",
|
||||||
@ -3717,13 +3708,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/devtools-kit": {
|
"node_modules/@vue/devtools-kit": {
|
||||||
"version": "7.7.8",
|
"version": "7.7.7",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.8.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.7.tgz",
|
||||||
"integrity": "sha512-4Y8op+AoxOJhB9fpcEF6d5vcJXWKgHxC3B0ytUB8zz15KbP9g9WgVzral05xluxi2fOeAy6t140rdQ943GcLRQ==",
|
"integrity": "sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/devtools-shared": "^7.7.8",
|
"@vue/devtools-shared": "^7.7.7",
|
||||||
"birpc": "^2.3.0",
|
"birpc": "^2.3.0",
|
||||||
"hookable": "^5.5.3",
|
"hookable": "^5.5.3",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
@ -3733,9 +3724,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/devtools-shared": {
|
"node_modules/@vue/devtools-shared": {
|
||||||
"version": "7.7.8",
|
"version": "7.7.7",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.8.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.7.tgz",
|
||||||
"integrity": "sha512-XHpO3jC5nOgYr40M9p8Z4mmKfTvUxKyRcUnpBAYg11pE78eaRFBKb0kG5yKLroMuJeeNH9LWmKp2zMU5LUc7CA==",
|
"integrity": "sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -3834,53 +3825,53 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/reactivity": {
|
"node_modules/@vue/reactivity": {
|
||||||
"version": "3.5.24",
|
"version": "3.5.23",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.24.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.23.tgz",
|
||||||
"integrity": "sha512-BM8kBhtlkkbnyl4q+HiF5R5BL0ycDPfihowulm02q3WYp2vxgPcJuZO866qa/0u3idbMntKEtVNuAUp5bw4teg==",
|
"integrity": "sha512-ji5w0qvrPyBmBx5Ldv4QGNsw0phgRreEvjt0iUf1lei2Sm8//9ZAi78uM2ZjsT5gk0YZilLuoRCIMvtuZlHMJw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/shared": "3.5.24"
|
"@vue/shared": "3.5.23"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-core": {
|
"node_modules/@vue/runtime-core": {
|
||||||
"version": "3.5.24",
|
"version": "3.5.23",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.24.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.23.tgz",
|
||||||
"integrity": "sha512-RYP/byyKDgNIqfX/gNb2PB55dJmM97jc9wyF3jK7QUInYKypK2exmZMNwnjueWwGceEkP6NChd3D2ZVEp9undQ==",
|
"integrity": "sha512-LMB0S6/G7mFJcpQeQaZrbsthFbWrIX8FVTzu5x9U3Ec8YW5MY1CGAnBBHNj+TPOBu3pIbtPpjrXtcaN04X+aBw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "3.5.24",
|
"@vue/reactivity": "3.5.23",
|
||||||
"@vue/shared": "3.5.24"
|
"@vue/shared": "3.5.23"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-dom": {
|
"node_modules/@vue/runtime-dom": {
|
||||||
"version": "3.5.24",
|
"version": "3.5.23",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.24.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.23.tgz",
|
||||||
"integrity": "sha512-Z8ANhr/i0XIluonHVjbUkjvn+CyrxbXRIxR7wn7+X7xlcb7dJsfITZbkVOeJZdP8VZwfrWRsWdShH6pngMxRjw==",
|
"integrity": "sha512-r/PYc8W9THzEL0UExpTkV+d31zO+Jid/RMZIDG6aS/NekOEUHuCJkJgftySWZw7JTJO/+q9Kxkg8p+i7Q7Q+ew==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "3.5.24",
|
"@vue/reactivity": "3.5.23",
|
||||||
"@vue/runtime-core": "3.5.24",
|
"@vue/runtime-core": "3.5.23",
|
||||||
"@vue/shared": "3.5.24",
|
"@vue/shared": "3.5.23",
|
||||||
"csstype": "^3.1.3"
|
"csstype": "^3.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/server-renderer": {
|
"node_modules/@vue/server-renderer": {
|
||||||
"version": "3.5.24",
|
"version": "3.5.23",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.24.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.23.tgz",
|
||||||
"integrity": "sha512-Yh2j2Y4G/0/4z/xJ1Bad4mxaAk++C2v4kaa8oSYTMJBJ00/ndPuxCnWeot0/7/qafQFLh5pr6xeV6SdMcE/G1w==",
|
"integrity": "sha512-NiWZsNCsXA20/VufcrW5u+Trt/PyFlpMmxaB2KERYM8eZgUoKUjXxJQb9ypq+LZ0Sp3XHJGNBR8DkhRnkKAMUw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-ssr": "3.5.24",
|
"@vue/compiler-ssr": "3.5.23",
|
||||||
"@vue/shared": "3.5.24"
|
"@vue/shared": "3.5.23"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vue": "3.5.24"
|
"vue": "3.5.23"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/shared": {
|
"node_modules/@vue/shared": {
|
||||||
"version": "3.5.24",
|
"version": "3.5.23",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.24.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.23.tgz",
|
||||||
"integrity": "sha512-9cwHL2EsJBdi8NY22pngYYWzkTDhld6fAD6jlaeloNGciNSJL6bLpbxVgXl96X00Jtc6YWQv96YA/0sxex/k1A==",
|
"integrity": "sha512-0YZ1DYuC5o/YJPf6pFdt2KYxVGDxkDbH/1NYJnVJWUkzr8ituBEmFVQRNX2gCaAsFEjEDnLkWpgqlZA7htgS/g==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@vue/tsconfig": {
|
"node_modules/@vue/tsconfig": {
|
||||||
@ -4401,9 +4392,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/baseline-browser-mapping": {
|
"node_modules/baseline-browser-mapping": {
|
||||||
"version": "2.8.28",
|
"version": "2.8.25",
|
||||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.28.tgz",
|
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.25.tgz",
|
||||||
"integrity": "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ==",
|
"integrity": "sha512-2NovHVesVF5TXefsGX1yzx1xgr7+m9JQenvz6FQY3qd+YXkKkYiv+vTCc7OriP9mcDZpTC5mAOYN4ocd29+erA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
@ -4411,9 +4402,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/birpc": {
|
"node_modules/birpc": {
|
||||||
"version": "2.8.0",
|
"version": "2.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/birpc/-/birpc-2.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/birpc/-/birpc-2.7.0.tgz",
|
||||||
"integrity": "sha512-Bz2a4qD/5GRhiHSwj30c/8kC8QGj12nNDwz3D4ErQ4Xhy35dsSDvF+RA/tWpjyU0pdGtSDiEk6B5fBGE1qNVhw==",
|
"integrity": "sha512-tub/wFGH49vNCm0xraykcY3TcRgX/3JsALYq/Lwrtti+bTyFHkCUAWF5wgYoie8P41wYwig2mIKiqoocr1EkEQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
@ -4480,9 +4471,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/browserslist": {
|
"node_modules/browserslist": {
|
||||||
"version": "4.28.0",
|
"version": "4.27.0",
|
||||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz",
|
||||||
"integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==",
|
"integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -4500,10 +4491,10 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"baseline-browser-mapping": "^2.8.25",
|
"baseline-browser-mapping": "^2.8.19",
|
||||||
"caniuse-lite": "^1.0.30001754",
|
"caniuse-lite": "^1.0.30001751",
|
||||||
"electron-to-chromium": "^1.5.249",
|
"electron-to-chromium": "^1.5.238",
|
||||||
"node-releases": "^2.0.27",
|
"node-releases": "^2.0.26",
|
||||||
"update-browserslist-db": "^1.1.4"
|
"update-browserslist-db": "^1.1.4"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@ -5101,6 +5092,13 @@
|
|||||||
"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",
|
||||||
@ -5188,9 +5186,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/default-browser": {
|
"node_modules/default-browser": {
|
||||||
"version": "5.3.0",
|
"version": "5.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
|
||||||
"integrity": "sha512-Qq68+VkJlc8tjnPV1i7HtbIn7ohmjZa88qUvHMIK0ZKUXMCuV45cT7cEXALPUmeXCe0q1DWQkQTemHVaLIFSrg==",
|
"integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -5389,9 +5387,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/electron": {
|
"node_modules/electron": {
|
||||||
"version": "39.1.2",
|
"version": "39.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/electron/-/electron-39.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/electron/-/electron-39.1.0.tgz",
|
||||||
"integrity": "sha512-+/TwT9NWxyQGTm5WemJEJy+bWCpnKJ4PLPswI1yn1P63bzM0/8yAeG05yS+NfFaWH4yNQtGXZmAv87Bxa5RlLg==",
|
"integrity": "sha512-vPRbKKQUzKWZZX68fuYdz4iS/eavGcQkHOGK4ylv0YJLbBRxxUlflPRdqRGflFjwid+sja7gbNul2lArevYwrw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -5809,15 +5807,6 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/electron-log": {
|
|
||||||
"version": "5.4.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/electron-log/-/electron-log-5.4.3.tgz",
|
|
||||||
"integrity": "sha512-sOUsM3LjZdugatazSQ/XTyNcw8dfvH1SYhXWiJyfYodAAKOZdHs0txPiLDXFzOZbhXgAgshQkshH2ccq0feyLQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/electron-squirrel-startup": {
|
"node_modules/electron-squirrel-startup": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/electron-squirrel-startup/-/electron-squirrel-startup-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/electron-squirrel-startup/-/electron-squirrel-startup-1.0.1.tgz",
|
||||||
@ -5843,9 +5832,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.5.250",
|
"version": "1.5.245",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.250.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.245.tgz",
|
||||||
"integrity": "sha512-/5UMj9IiGDMOFBnN4i7/Ry5onJrAGSbOGo3s9FEKmwobGq6xw832ccET0CE3CkkMBZ8GJSlUIesZofpyurqDXw==",
|
"integrity": "sha512-rdmGfW47ZhL/oWEJAY4qxRtdly2B98ooTJ0pdEI4jhVLZ6tNf8fPtov2wS1IRKwFJT92le3x4Knxiwzl7cPPpQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
@ -5932,9 +5921,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/electron/node_modules/@types/node": {
|
"node_modules/electron/node_modules/@types/node": {
|
||||||
"version": "22.19.1",
|
"version": "22.19.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.0.tgz",
|
||||||
"integrity": "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==",
|
"integrity": "sha512-xpr/lmLPQEj+TUnHmR+Ab91/glhJvsqcjB+yY0Ix9GO70H6Lb4FHH5GeqdOE5btAx7eIMwuHkp4H2MSkLcqWbA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -6574,9 +6563,9 @@
|
|||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0"
|
||||||
},
|
},
|
||||||
"node_modules/exsolve": {
|
"node_modules/exsolve": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz",
|
||||||
"integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==",
|
"integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
@ -7576,9 +7565,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ip-address": {
|
"node_modules/ip-address": {
|
||||||
"version": "10.1.0",
|
"version": "10.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz",
|
||||||
"integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==",
|
"integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -7858,9 +7847,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/js-yaml": {
|
"node_modules/js-yaml": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||||
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
|
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -8763,6 +8752,10 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/neptune-native": {
|
||||||
|
"resolved": "packages/neptune-native",
|
||||||
|
"link": true
|
||||||
|
},
|
||||||
"node_modules/nice-try": {
|
"node_modules/nice-try": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
|
||||||
@ -8771,9 +8764,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/node-abi": {
|
"node_modules/node-abi": {
|
||||||
"version": "3.82.0",
|
"version": "3.80.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.82.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.80.0.tgz",
|
||||||
"integrity": "sha512-aQuSU0xnqUUNU7rVmEB8M8pAJ/1SA/DL0tdAtr+X63+x61UJMo1Ulsp/3liX33EuA4kM8GG762/pyHtgag5PmQ==",
|
"integrity": "sha512-LyPuZJcI9HVwzXK1GPxWNzrr+vr8Hp/3UqlmWxxh8p54U1ZbclOqbSog9lWHaCX+dBaiGi6n/hIX+mKu74GmPA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -10092,9 +10085,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "4.53.2",
|
"version": "4.52.5",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz",
|
||||||
"integrity": "sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==",
|
"integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -10108,28 +10101,28 @@
|
|||||||
"npm": ">=8.0.0"
|
"npm": ">=8.0.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@rollup/rollup-android-arm-eabi": "4.53.2",
|
"@rollup/rollup-android-arm-eabi": "4.52.5",
|
||||||
"@rollup/rollup-android-arm64": "4.53.2",
|
"@rollup/rollup-android-arm64": "4.52.5",
|
||||||
"@rollup/rollup-darwin-arm64": "4.53.2",
|
"@rollup/rollup-darwin-arm64": "4.52.5",
|
||||||
"@rollup/rollup-darwin-x64": "4.53.2",
|
"@rollup/rollup-darwin-x64": "4.52.5",
|
||||||
"@rollup/rollup-freebsd-arm64": "4.53.2",
|
"@rollup/rollup-freebsd-arm64": "4.52.5",
|
||||||
"@rollup/rollup-freebsd-x64": "4.53.2",
|
"@rollup/rollup-freebsd-x64": "4.52.5",
|
||||||
"@rollup/rollup-linux-arm-gnueabihf": "4.53.2",
|
"@rollup/rollup-linux-arm-gnueabihf": "4.52.5",
|
||||||
"@rollup/rollup-linux-arm-musleabihf": "4.53.2",
|
"@rollup/rollup-linux-arm-musleabihf": "4.52.5",
|
||||||
"@rollup/rollup-linux-arm64-gnu": "4.53.2",
|
"@rollup/rollup-linux-arm64-gnu": "4.52.5",
|
||||||
"@rollup/rollup-linux-arm64-musl": "4.53.2",
|
"@rollup/rollup-linux-arm64-musl": "4.52.5",
|
||||||
"@rollup/rollup-linux-loong64-gnu": "4.53.2",
|
"@rollup/rollup-linux-loong64-gnu": "4.52.5",
|
||||||
"@rollup/rollup-linux-ppc64-gnu": "4.53.2",
|
"@rollup/rollup-linux-ppc64-gnu": "4.52.5",
|
||||||
"@rollup/rollup-linux-riscv64-gnu": "4.53.2",
|
"@rollup/rollup-linux-riscv64-gnu": "4.52.5",
|
||||||
"@rollup/rollup-linux-riscv64-musl": "4.53.2",
|
"@rollup/rollup-linux-riscv64-musl": "4.52.5",
|
||||||
"@rollup/rollup-linux-s390x-gnu": "4.53.2",
|
"@rollup/rollup-linux-s390x-gnu": "4.52.5",
|
||||||
"@rollup/rollup-linux-x64-gnu": "4.53.2",
|
"@rollup/rollup-linux-x64-gnu": "4.52.5",
|
||||||
"@rollup/rollup-linux-x64-musl": "4.53.2",
|
"@rollup/rollup-linux-x64-musl": "4.52.5",
|
||||||
"@rollup/rollup-openharmony-arm64": "4.53.2",
|
"@rollup/rollup-openharmony-arm64": "4.52.5",
|
||||||
"@rollup/rollup-win32-arm64-msvc": "4.53.2",
|
"@rollup/rollup-win32-arm64-msvc": "4.52.5",
|
||||||
"@rollup/rollup-win32-ia32-msvc": "4.53.2",
|
"@rollup/rollup-win32-ia32-msvc": "4.52.5",
|
||||||
"@rollup/rollup-win32-x64-gnu": "4.53.2",
|
"@rollup/rollup-win32-x64-gnu": "4.52.5",
|
||||||
"@rollup/rollup-win32-x64-msvc": "4.53.2",
|
"@rollup/rollup-win32-x64-msvc": "4.52.5",
|
||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -10199,9 +10192,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/sass": {
|
"node_modules/sass": {
|
||||||
"version": "1.94.0",
|
"version": "1.93.3",
|
||||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.94.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass/-/sass-1.93.3.tgz",
|
||||||
"integrity": "sha512-Dqh7SiYcaFtdv5Wvku6QgS5IGPm281L+ZtVD1U2FJa7Q0EFRlq8Z3sjYtz6gYObsYThUOz9ArwFqPZx+1azILQ==",
|
"integrity": "sha512-elOcIZRTM76dvxNAjqYrucTSI0teAF/L2Lv0s6f6b7FOwcwIuA357bIE871580AjHJuSvLIRUosgV+lIWx6Rgg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -11662,15 +11655,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite-plugin-vue-devtools": {
|
"node_modules/vite-plugin-vue-devtools": {
|
||||||
"version": "7.7.8",
|
"version": "7.7.7",
|
||||||
"resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.7.8.tgz",
|
"resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.7.7.tgz",
|
||||||
"integrity": "sha512-04jowFsal5f9Gbso0X5Ff/mtvik7VP/PBYcKDCQHnTLH0x+juWSj7v1QJfDtXnWrrxU7/yrljEP8KZTm4skvkg==",
|
"integrity": "sha512-d0fIh3wRcgSlr4Vz7bAk4va1MkdqhQgj9ANE/rBhsAjOnRfTLs2ocjFMvSUOsv6SRRXU9G+VM7yMgqDb6yI4iQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/devtools-core": "^7.7.8",
|
"@vue/devtools-core": "^7.7.7",
|
||||||
"@vue/devtools-kit": "^7.7.8",
|
"@vue/devtools-kit": "^7.7.7",
|
||||||
"@vue/devtools-shared": "^7.7.8",
|
"@vue/devtools-shared": "^7.7.7",
|
||||||
"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",
|
||||||
@ -11799,16 +11792,16 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/vue": {
|
"node_modules/vue": {
|
||||||
"version": "3.5.24",
|
"version": "3.5.23",
|
||||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.24.tgz",
|
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.23.tgz",
|
||||||
"integrity": "sha512-uTHDOpVQTMjcGgrqFPSb8iO2m1DUvo+WbGqoXQz8Y1CeBYQ0FXf2z1gLRaBtHjlRz7zZUBHxjVB5VTLzYkvftg==",
|
"integrity": "sha512-CfvZv/vI52xUhumUvHtD6iFIS78nGWfX4IJnHfBGhpqMI0CwDq2YEngXOeaBFMRmiArcqczuVrLxurvesTYT9w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.5.24",
|
"@vue/compiler-dom": "3.5.23",
|
||||||
"@vue/compiler-sfc": "3.5.24",
|
"@vue/compiler-sfc": "3.5.23",
|
||||||
"@vue/runtime-dom": "3.5.24",
|
"@vue/runtime-dom": "3.5.23",
|
||||||
"@vue/server-renderer": "3.5.24",
|
"@vue/server-renderer": "3.5.23",
|
||||||
"@vue/shared": "3.5.24"
|
"@vue/shared": "3.5.23"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": "*"
|
"typescript": "*"
|
||||||
@ -12322,7 +12315,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/neptune-native": {
|
"packages/neptune-native": {
|
||||||
"name": "@neptune/native",
|
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
16
package.json
16
package.json
@ -1,8 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "neptune-web-wallet",
|
"name": "neptune-web-wallet",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"description": "Neptune Blockchain Wallet - Secure cryptocurrency wallet for Neptune network",
|
|
||||||
"author": "Neptune Team",
|
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
@ -27,10 +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",
|
||||||
"electron-log": "^5.4.3",
|
"crypto": "^1.0.1",
|
||||||
"electron-squirrel-startup": "^1.0.1",
|
"electron-squirrel-startup": "^1.0.1",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"vue": "^3.5.24",
|
"vue": "^3.4.21",
|
||||||
"vue-router": "^4.3.0",
|
"vue-router": "^4.3.0",
|
||||||
"vue3-i18n": "^1.1.5"
|
"vue3-i18n": "^1.1.5"
|
||||||
},
|
},
|
||||||
@ -44,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.15.0",
|
"@rushstack/eslint-patch": "^1.8.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.19.25",
|
"@types/node": "^20.12.5",
|
||||||
"@vitejs/plugin-vue": "^5.0.4",
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
"@vitejs/plugin-vue-jsx": "^5.1.1",
|
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||||
"@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",
|
||||||
@ -58,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.94.0",
|
"sass": "^1.75.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.4.21",
|
"vite": "^5.2.8",
|
||||||
"vite-plugin-vue-devtools": "^7.0.25",
|
"vite-plugin-vue-devtools": "^7.0.25",
|
||||||
"vue-tsc": "^2.0.11"
|
"vue-tsc": "^2.0.11"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "@neptune/native",
|
"name": "neptune-native",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"description": "Native Node.js addon for Neptune transaction building",
|
"description": "Native Node.js addon for Neptune transaction building",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 975 KiB After Width: | Height: | Size: 1.2 MiB |
@ -11,6 +11,15 @@ 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,9 +1,8 @@
|
|||||||
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 = DEFAULT_MIN_BLOCK_HEIGHT,
|
startBlock: number | null = 0,
|
||||||
endBlock: number | null = null,
|
endBlock: number | null = null,
|
||||||
maxSearchDepth: number = 1000
|
maxSearchDepth: number = 1000
|
||||||
): Promise<any> => {
|
): Promise<any> => {
|
||||||
@ -18,7 +17,7 @@ export const getUtxosFromViewKey = async (
|
|||||||
|
|
||||||
export const getBalance = async (
|
export const getBalance = async (
|
||||||
viewKey: string,
|
viewKey: string,
|
||||||
startBlock: number = DEFAULT_MIN_BLOCK_HEIGHT,
|
startBlock: number | null = 0,
|
||||||
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: 975 KiB After Width: | Height: | Size: 1.2 MiB |
@ -1,14 +1,13 @@
|
|||||||
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 { DEFAULT_MIN_BLOCK_HEIGHT, toFiniteNumber } from '@/utils'
|
import { toFiniteNumber } from '@/utils'
|
||||||
|
|
||||||
let wasmInitialized = false
|
let wasmInitialized = false
|
||||||
let initPromise: Promise<void> | null = null
|
let initPromise: Promise<void> | null = null
|
||||||
@ -31,10 +30,11 @@ export function useNeptuneWallet() {
|
|||||||
await initWasm()
|
await initWasm()
|
||||||
|
|
||||||
wasmInitialized = true
|
wasmInitialized = true
|
||||||
} catch (err: any) {
|
} catch (err) {
|
||||||
wasmInitialized = false
|
wasmInitialized = false
|
||||||
await (window as any).logger.error('WASM init error:')
|
const errorMsg = 'Failed to initialize Neptune WASM'
|
||||||
throw new Error('Failed to initialize Neptune WASM')
|
console.error('WASM init error:', err)
|
||||||
|
throw new Error(errorMsg)
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
|
||||||
@ -48,6 +48,7 @@ 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)
|
||||||
@ -58,23 +59,25 @@ export function useNeptuneWallet() {
|
|||||||
store.setAddress(addressResult)
|
store.setAddress(addressResult)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
} catch (err: any) {
|
} catch (err) {
|
||||||
await (window as any).logger.error('Error generating wallet: ', err.message)
|
console.error('Error generating wallet:', err)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getViewKeyFromSeed = async (seedPhrase: string[]): Promise<ViewKeyResult> => {
|
const getViewKeyFromSeed = async (seedPhrase: string[]): Promise<ViewKeyResult> => {
|
||||||
return await (window as any).walletApi.generateKeysFromSeed([...seedPhrase])
|
const result = 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)
|
||||||
@ -83,14 +86,15 @@ 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,
|
||||||
spendingKey: result.spending_key_hex,
|
spendingKey: result.spending_key_hex,
|
||||||
address: addressResult,
|
address: addressResult,
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err) {
|
||||||
await (window as any).logger.error('Error recovering wallet from seed: ', err.message)
|
console.error('Error recovering wallet from seed:', err)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,19 +105,21 @@ export function useNeptuneWallet() {
|
|||||||
return address_from_seed(seedPhraseJson, store.getNetwork)
|
return address_from_seed(seedPhraseJson, store.getNetwork)
|
||||||
}
|
}
|
||||||
|
|
||||||
const decryptKeystore = async (password: string): Promise<{ seedPhrase: string[] }> => {
|
const decryptKeystore = async (password: string): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
const keystoreFileName = store.getKeystoreFileName
|
const keystorePath = store.getKeystorePath
|
||||||
if (!keystoreFileName) await checkKeystore()
|
if (!keystorePath) await checkKeystore()
|
||||||
|
|
||||||
const result = await (window as any).walletApi.decryptKeystore(
|
const result = await (window as any).walletApi.decryptKeystore(
|
||||||
keystoreFileName,
|
store.getKeystorePath,
|
||||||
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)
|
||||||
@ -122,67 +128,62 @@ export function useNeptuneWallet() {
|
|||||||
store.setAddress(addressResult)
|
store.setAddress(addressResult)
|
||||||
|
|
||||||
await loadMinBlockHeightFromKeystore()
|
await loadMinBlockHeightFromKeystore()
|
||||||
|
} catch (err) {
|
||||||
return { seedPhrase }
|
|
||||||
} catch (err: any) {
|
|
||||||
if (
|
if (
|
||||||
err instanceof Error &&
|
err instanceof Error &&
|
||||||
(err.message.includes('Unsupported state') ||
|
(err.message.includes('Unsupported state') ||
|
||||||
err.message.includes('unable to authenticate'))
|
err.message.includes('unable to authenticate'))
|
||||||
) {
|
) {
|
||||||
await (window as any).logger.error('Invalid password')
|
console.error('Invalid password')
|
||||||
} else await (window as any).logger.error('Error decrypting keystore: ', err.message)
|
} else console.error('Error decrypting keystore:', err)
|
||||||
|
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const createKeystore = async (seed: string, password: string): Promise<string | null> => {
|
const createKeystore = async (seed: string, password: string): Promise<string> => {
|
||||||
try {
|
try {
|
||||||
const result = await (window as any).walletApi.createKeystore(seed, password)
|
const result = await (window as any).walletApi.createKeystore(seed, password)
|
||||||
if (!result.success) return null
|
store.setKeystorePath(result.filePath)
|
||||||
store.setKeystoreFileName(result.fileName)
|
store.setMinBlockHeight(null)
|
||||||
store.setMinBlockHeight(DEFAULT_MIN_BLOCK_HEIGHT)
|
return result.filePath
|
||||||
return result.fileName
|
} catch (err) {
|
||||||
} catch (err: any) {
|
console.error('Error creating keystore:', err)
|
||||||
await (window as any).logger.error('Error creating keystore: ', err.message)
|
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveKeystoreAs = async (): Promise<void> => {
|
const saveKeystoreAs = async (seed: string, password: string): Promise<string> => {
|
||||||
try {
|
try {
|
||||||
const keystoreFileName = store.getKeystoreFileName
|
const result = await (window as any).walletApi.saveKeystoreAs(seed, password)
|
||||||
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')
|
||||||
} catch (err: any) {
|
return result.filePath
|
||||||
await (window as any).logger.error('Error saving keystore: ', err.message)
|
} catch (err) {
|
||||||
|
console.error('Error saving keystore:', err)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkKeystore = async (): Promise<boolean> => {
|
const checkKeystore = async (): Promise<boolean> => {
|
||||||
try {
|
try {
|
||||||
const keystoreFile = await (window as any).walletApi.checkKeystore(store.getKeystoreFileName)
|
const keystoreFile = await (window as any).walletApi.checkKeystore()
|
||||||
if (!keystoreFile.exists) return false
|
if (!keystoreFile.exists) return false
|
||||||
|
|
||||||
store.setKeystoreFileName(keystoreFile.fileName)
|
store.setKeystorePath(keystoreFile.filePath)
|
||||||
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) {
|
||||||
await (window as any).logger.error('Error checking keystore: ', err.message)
|
console.error('Error checking keystore:', err)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const persistMinBlockHeight = async (utxos: any[]) => {
|
const persistMinBlockHeight = async (utxos: any[]) => {
|
||||||
const keystoreFileName = store.getKeystoreFileName
|
const keystorePath = store.getKeystorePath
|
||||||
if (!keystoreFileName) return
|
if (!keystorePath) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const minBlockHeight = utxos.reduce((min, utxo) => {
|
const minBlockHeight = utxos.reduce((min, utxo) => {
|
||||||
@ -196,31 +197,31 @@ export function useNeptuneWallet() {
|
|||||||
}, null)
|
}, null)
|
||||||
|
|
||||||
const response = await (window as any).walletApi.updateMinBlockHeight(
|
const response = await (window as any).walletApi.updateMinBlockHeight(
|
||||||
keystoreFileName,
|
keystorePath,
|
||||||
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) {
|
||||||
await (window as any).logger.error('Error saving min block height: ', err.message)
|
console.error('Error saving min block height:', err)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadMinBlockHeightFromKeystore = async (): Promise<number> => {
|
const loadMinBlockHeightFromKeystore = async (): Promise<number | null> => {
|
||||||
const keystoreFileName = store.getKeystoreFileName
|
const keystorePath = store.getKeystorePath
|
||||||
if (!keystoreFileName) return DEFAULT_MIN_BLOCK_HEIGHT
|
if (!keystorePath) return null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await (window as any).walletApi.getMinBlockHeight(keystoreFileName)
|
const response = await (window as any).walletApi.getMinBlockHeight(keystorePath)
|
||||||
if (!response?.success) throw new Error(String(response.error))
|
if (!response?.success) return null
|
||||||
|
|
||||||
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) {
|
||||||
await (window as any).logger.error('Error loading min block height: ', err.message)
|
console.error('Error loading min block height:', err)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,7 +238,7 @@ export function useNeptuneWallet() {
|
|||||||
|
|
||||||
const response = await API.getUtxosFromViewKey(
|
const response = await API.getUtxosFromViewKey(
|
||||||
store.getViewKey || '',
|
store.getViewKey || '',
|
||||||
toFiniteNumber(startBlock)
|
toFiniteNumber(startBlock, 0)
|
||||||
)
|
)
|
||||||
|
|
||||||
const result = response?.result || response
|
const result = response?.result || response
|
||||||
@ -248,23 +249,23 @@ export function useNeptuneWallet() {
|
|||||||
|
|
||||||
await persistMinBlockHeight(utxoList)
|
await persistMinBlockHeight(utxoList)
|
||||||
return result
|
return result
|
||||||
} catch (err: any) {
|
} catch (err) {
|
||||||
await (window as any).logger.error('Error getting UTXOs: ', err.message)
|
console.error('Error getting UTXOs:', err)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getBalance = async (): Promise<BalanceResult> => {
|
const getBalance = async (): Promise<any> => {
|
||||||
try {
|
try {
|
||||||
let startBlock: number | null | undefined = store.getMinBlockHeight
|
let startBlock: number | null | undefined = store.getMinBlockHeight
|
||||||
|
|
||||||
if (startBlock == null) {
|
if (startBlock === null || startBlock === undefined) {
|
||||||
startBlock = await loadMinBlockHeightFromKeystore()
|
startBlock = await loadMinBlockHeightFromKeystore()
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await API.getBalance(
|
const response = await API.getBalance(
|
||||||
store.getViewKey || '',
|
store.getViewKey || '',
|
||||||
toFiniteNumber(startBlock)
|
toFiniteNumber(startBlock, 0)
|
||||||
)
|
)
|
||||||
const result = response?.result || response
|
const result = response?.result || response
|
||||||
|
|
||||||
@ -274,8 +275,8 @@ export function useNeptuneWallet() {
|
|||||||
balance: result?.balance || result,
|
balance: result?.balance || result,
|
||||||
pendingBalance: result?.pendingBalance || result,
|
pendingBalance: result?.pendingBalance || result,
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err) {
|
||||||
await (window as any).logger.error('Error getting balance: ', err.message)
|
console.error('Error getting balance:', err)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -285,8 +286,8 @@ export function useNeptuneWallet() {
|
|||||||
const response = await API.getBlockHeight()
|
const response = await API.getBlockHeight()
|
||||||
const result = response?.result || response
|
const result = response?.result || response
|
||||||
return result?.height || result
|
return result?.height || result
|
||||||
} catch (err: any) {
|
} catch (err) {
|
||||||
await (window as any).logger.error('Error getting block height: ', err.message)
|
console.error('Error getting block height:', err)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -298,8 +299,8 @@ export function useNeptuneWallet() {
|
|||||||
store.setNetwork((result.network + 'net') as 'mainnet' | 'testnet')
|
store.setNetwork((result.network + 'net') as 'mainnet' | 'testnet')
|
||||||
|
|
||||||
return result
|
return result
|
||||||
} catch (err: any) {
|
} catch (err) {
|
||||||
await (window as any).logger.error('Error getting network info: ', err.message)
|
console.error('Error getting network info:', err)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -313,7 +314,7 @@ export function useNeptuneWallet() {
|
|||||||
const payload = {
|
const payload = {
|
||||||
spendingKeyHex: store.getSpendingKey,
|
spendingKeyHex: store.getSpendingKey,
|
||||||
inputAdditionRecords: args.inputAdditionRecords,
|
inputAdditionRecords: args.inputAdditionRecords,
|
||||||
minBlockHeight: toFiniteNumber(minBlockHeight),
|
minBlockHeight: toFiniteNumber(minBlockHeight, 0),
|
||||||
outputAddresses: args.outputAddresses,
|
outputAddresses: args.outputAddresses,
|
||||||
outputAmounts: args.outputAmounts,
|
outputAmounts: args.outputAmounts,
|
||||||
fee: args.fee,
|
fee: args.fee,
|
||||||
@ -326,8 +327,26 @@ export function useNeptuneWallet() {
|
|||||||
const response = await API.broadcastSignedTransaction(transactionHex)
|
const response = await API.broadcastSignedTransaction(transactionHex)
|
||||||
const result = response?.result || response
|
const result = response?.result || response
|
||||||
return result
|
return result
|
||||||
} catch (err: any) {
|
} catch (err) {
|
||||||
await (window as any).logger.error('Error sending transaction: ', err.message)
|
console.error('Error sending transaction:', err)
|
||||||
|
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) {
|
||||||
|
console.error('Error setting network:', err)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -356,5 +375,6 @@ export function useNeptuneWallet() {
|
|||||||
checkKeystore,
|
checkKeystore,
|
||||||
|
|
||||||
clearWallet,
|
clearWallet,
|
||||||
|
setNetwork,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
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
|
||||||
@ -40,8 +42,3 @@ export interface Utxo {
|
|||||||
blockHeight: number
|
blockHeight: number
|
||||||
utxoHash: string
|
utxoHash: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BalanceResult {
|
|
||||||
balance: string | null
|
|
||||||
pendingBalance: string | null
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,4 +0,0 @@
|
|||||||
export default {
|
|
||||||
title: 'The page you requested was not found.',
|
|
||||||
back: 'Back to Home',
|
|
||||||
}
|
|
||||||
@ -1,13 +1,15 @@
|
|||||||
import { createI18n } from 'vue3-i18n'
|
import { createI18n } from 'vue3-i18n'
|
||||||
import { en } from './en'
|
import { en } from './en'
|
||||||
|
import { jp } from './jp'
|
||||||
|
|
||||||
const messages = {
|
const messages = {
|
||||||
en: en,
|
en: en,
|
||||||
|
jp: jp,
|
||||||
}
|
}
|
||||||
|
|
||||||
const i18n = createI18n({
|
const i18n = createI18n({
|
||||||
locale: 'en',
|
locale: 'jp',
|
||||||
fallbackLocale: 'en',
|
fallbackLocale: 'jp',
|
||||||
messages,
|
messages,
|
||||||
} as any)
|
} as any)
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
import { routes } from './route'
|
import { routes } from './route'
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: import.meta.env.DEV ? createWebHistory() : createWebHashHistory(),
|
history: createWebHistory(),
|
||||||
routes,
|
routes,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,15 @@
|
|||||||
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 { DEFAULT_MIN_BLOCK_HEIGHT, toFiniteNumber } from '@/utils'
|
import { 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,
|
||||||
@ -19,10 +21,18 @@ export const useNeptuneStore = defineStore('neptune', () => {
|
|||||||
minBlockHeight: null,
|
minBlockHeight: null,
|
||||||
})
|
})
|
||||||
|
|
||||||
const keystoreFileName = ref<string | null>(null)
|
const keystorePath = ref<null | string>(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
|
||||||
}
|
}
|
||||||
@ -55,7 +65,7 @@ export const useNeptuneStore = defineStore('neptune', () => {
|
|||||||
wallet.value.utxos = utxos
|
wallet.value.utxos = utxos
|
||||||
}
|
}
|
||||||
|
|
||||||
const setMinBlockHeight = (minBlockHeight: number = DEFAULT_MIN_BLOCK_HEIGHT) => {
|
const setMinBlockHeight = (minBlockHeight: number | null) => {
|
||||||
wallet.value.minBlockHeight = toFiniteNumber(minBlockHeight)
|
wallet.value.minBlockHeight = toFiniteNumber(minBlockHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,12 +73,14 @@ export const useNeptuneStore = defineStore('neptune', () => {
|
|||||||
wallet.value = { ...wallet.value, ...walletData }
|
wallet.value = { ...wallet.value, ...walletData }
|
||||||
}
|
}
|
||||||
|
|
||||||
const setKeystoreFileName = (fileName: string | null) => {
|
const setKeystorePath = (path: string | null) => {
|
||||||
keystoreFileName.value = fileName
|
keystorePath.value = path
|
||||||
}
|
}
|
||||||
|
|
||||||
const clearWallet = () => {
|
const clearWallet = () => {
|
||||||
wallet.value = {
|
wallet.value = {
|
||||||
|
seedPhrase: null,
|
||||||
|
password: null,
|
||||||
receiverId: null,
|
receiverId: null,
|
||||||
viewKey: null,
|
viewKey: null,
|
||||||
spendingKey: null,
|
spendingKey: null,
|
||||||
@ -83,6 +95,9 @@ 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)
|
||||||
@ -93,9 +108,12 @@ 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 getKeystoreFileName = computed(() => keystoreFileName.value ?? null)
|
const getKeystorePath = computed(() => keystorePath.value)
|
||||||
return {
|
return {
|
||||||
getWallet,
|
getWallet,
|
||||||
|
getSeedPhrase,
|
||||||
|
getSeedPhraseString,
|
||||||
|
getPassword,
|
||||||
getReceiverId,
|
getReceiverId,
|
||||||
getViewKey,
|
getViewKey,
|
||||||
getSpendingKey,
|
getSpendingKey,
|
||||||
@ -106,7 +124,9 @@ export const useNeptuneStore = defineStore('neptune', () => {
|
|||||||
getUtxos,
|
getUtxos,
|
||||||
getMinBlockHeight,
|
getMinBlockHeight,
|
||||||
hasWallet,
|
hasWallet,
|
||||||
getKeystoreFileName,
|
getKeystorePath,
|
||||||
|
setSeedPhrase,
|
||||||
|
setPassword,
|
||||||
setReceiverId,
|
setReceiverId,
|
||||||
setViewKey,
|
setViewKey,
|
||||||
setSpendingKey,
|
setSpendingKey,
|
||||||
@ -117,7 +137,7 @@ export const useNeptuneStore = defineStore('neptune', () => {
|
|||||||
setUtxos,
|
setUtxos,
|
||||||
setMinBlockHeight,
|
setMinBlockHeight,
|
||||||
setWallet,
|
setWallet,
|
||||||
setKeystoreFileName,
|
setKeystorePath,
|
||||||
clearWallet,
|
clearWallet,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
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,9 +1,3 @@
|
|||||||
import { DEFAULT_MIN_BLOCK_HEIGHT } from '@/utils/constants/constants'
|
export function toFiniteNumber(value: number | null, defaultValue?: number): number | null {
|
||||||
|
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,7 +33,6 @@ 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,6 +41,7 @@ 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,11 +22,13 @@ const emit = defineEmits<{
|
|||||||
back: []
|
back: []
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const seedWords = computed(() => props.seedPhrase || [])
|
const neptuneStore = useNeptuneStore()
|
||||||
|
|
||||||
|
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')
|
||||||
@ -95,7 +97,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,19 +1,16 @@
|
|||||||
<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 seedWords = computed(() => props.seedPhrase || [])
|
const neptuneStore = useNeptuneStore()
|
||||||
|
|
||||||
|
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)
|
||||||
@ -113,7 +110,7 @@ const handleBack = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const seeds = props.seedPhrase
|
const seeds = neptuneStore.getSeedPhrase
|
||||||
|
|
||||||
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,11 +1,14 @@
|
|||||||
<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: [password: string]
|
next: []
|
||||||
navigateToRecoverWallet: []
|
navigateToRecoverWallet: []
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const neptuneStore = useNeptuneStore()
|
||||||
|
|
||||||
const password = ref('')
|
const password = ref('')
|
||||||
const confirmPassword = ref('')
|
const confirmPassword = ref('')
|
||||||
const passwordError = ref('')
|
const passwordError = ref('')
|
||||||
@ -53,7 +56,8 @@ const handleNext = () => {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
emit('next', password.value)
|
neptuneStore.setPassword(password.value)
|
||||||
|
emit('next')
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleIHaveWallet = () => {
|
const handleIHaveWallet = () => {
|
||||||
|
|||||||
@ -14,8 +14,6 @@ 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 {
|
||||||
@ -37,11 +35,9 @@ const handleNextToWalletCreated = () => {
|
|||||||
step.value = 4
|
step.value = 4
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleNextFromPassword = async (pwd: string) => {
|
const handleNextFromPassword = async () => {
|
||||||
try {
|
try {
|
||||||
const result = await generateWallet()
|
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')
|
||||||
@ -62,8 +58,6 @@ const handleAccessWallet = () => {
|
|||||||
|
|
||||||
function resetAll() {
|
function resetAll() {
|
||||||
step.value = 1
|
step.value = 1
|
||||||
seedPhrase.value = []
|
|
||||||
password.value = ''
|
|
||||||
clearWallet()
|
clearWallet()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -81,7 +75,6 @@ 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"
|
||||||
/>
|
/>
|
||||||
@ -89,7 +82,6 @@ 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"
|
||||||
/>
|
/>
|
||||||
@ -97,8 +89,6 @@ 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"
|
||||||
/>
|
/>
|
||||||
@ -113,6 +103,7 @@ 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,12 +1,9 @@
|
|||||||
<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 props = defineProps<{
|
const neptuneStore = useNeptuneStore()
|
||||||
seedPhrase: string[]
|
|
||||||
password: string
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const { createKeystore } = useNeptuneWallet()
|
const { createKeystore } = useNeptuneWallet()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@ -16,14 +13,15 @@ const emit = defineEmits<{
|
|||||||
|
|
||||||
const handleAccessWallet = async () => {
|
const handleAccessWallet = async () => {
|
||||||
try {
|
try {
|
||||||
const seedPhraseString = props.seedPhrase.join(' ')
|
const seedPhrase = neptuneStore.getSeedPhraseString
|
||||||
|
const password = neptuneStore.getPassword!
|
||||||
|
|
||||||
if (!seedPhraseString || !props.password) {
|
if (!seedPhrase || !password) {
|
||||||
message.error('Missing seed or password')
|
message.error('Missing seed or password')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await createKeystore(seedPhraseString, props.password)
|
await createKeystore(seedPhrase, 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: 20px;
|
padding: 16px 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -32,6 +32,7 @@ const loadUtxos = async () => {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
const result = await getUtxos()
|
const result = await getUtxos()
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
|
console.error(result.error.message)
|
||||||
message.error('Failed to load UTXOs')
|
message.error('Failed to load UTXOs')
|
||||||
loading.value = false
|
loading.value = false
|
||||||
return
|
return
|
||||||
@ -39,6 +40,7 @@ const loadUtxos = async () => {
|
|||||||
loading.value = false
|
loading.value = false
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
message.error('Failed to load UTXOs')
|
message.error('Failed to load UTXOs')
|
||||||
|
console.error('Error loading UTXOs:', err)
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@ -61,8 +63,8 @@ watch(
|
|||||||
<div class="debug-header">
|
<div class="debug-header">
|
||||||
<h3 class="debug-title">IN USE UTXOS</h3>
|
<h3 class="debug-title">IN USE UTXOS</h3>
|
||||||
<div class="debug-info">
|
<div class="debug-info">
|
||||||
<p><span>COUNT</span> <strong>{{ inUseUtxosCount }}</strong></p>
|
<p><span>COUNT</span> {{ inUseUtxosCount }}</p>
|
||||||
<p><span>AMOUNT</span> <strong>{{ inUseUtxosAmount }}</strong> <strong>NPT</strong></p>
|
<p><span>AMOUNT</span> {{ inUseUtxosAmount }} <strong>NPT</strong></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -114,10 +116,6 @@ watch(
|
|||||||
font-weight: var(--font-bold);
|
font-weight: var(--font-bold);
|
||||||
margin-right: var(--spacing-sm);
|
margin-right: var(--spacing-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
strong {
|
|
||||||
color: var(--primary-color);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
<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?: BalanceResult['balance']
|
availableBalance?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
@ -28,7 +27,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 ?? '0.00000000')
|
const balance = parseFloat(props.availableBalance)
|
||||||
if (!isNaN(balance) && num > balance) return false
|
if (!isNaN(balance) && num > balance) return false
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -44,7 +43,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 ?? '0.00000000')
|
const balance = parseFloat(props.availableBalance)
|
||||||
if (!isNaN(balance) && num > balance) {
|
if (!isNaN(balance) && num > balance) {
|
||||||
return `Insufficient balance. Available: ${props.availableBalance} NPT`
|
return `Insufficient balance. Available: ${props.availableBalance} NPT`
|
||||||
}
|
}
|
||||||
@ -159,11 +158,9 @@ const displayAddress = computed(() => {
|
|||||||
<div class="amount-row">
|
<div class="amount-row">
|
||||||
<div class="amount-field">
|
<div class="amount-field">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label-extra">
|
<label class="form-label">
|
||||||
<span class="form-label"> Amount <span class="required">*</span> </span>
|
Amount <span class="required">*</span>
|
||||||
<span class="balance-info"
|
<span class="balance-info">Available: {{ availableBalance }} NPT</span>
|
||||||
>Available: <strong>{{ availableBalance }}</strong> NPT</span
|
|
||||||
>
|
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
v-model="outputAmounts"
|
v-model="outputAmounts"
|
||||||
@ -288,17 +285,12 @@ const displayAddress = computed(() => {
|
|||||||
gap: var(--spacing-xs);
|
gap: var(--spacing-xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-label-extra {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-label {
|
.form-label {
|
||||||
font-size: var(--font-sm);
|
font-size: var(--font-sm);
|
||||||
font-weight: var(--font-medium);
|
font-weight: var(--font-medium);
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
display: flex;
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
.required {
|
.required {
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { BalanceResult } from '@/interface'
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isLoadingData: boolean
|
isLoadingData: boolean
|
||||||
availableBalance: BalanceResult['balance']
|
availableBalance: string
|
||||||
pendingBalance: BalanceResult['pendingBalance']
|
pendingBalance: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>()
|
const props = defineProps<Props>()
|
||||||
@ -38,8 +36,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);
|
||||||
@ -47,8 +45,8 @@ const props = defineProps<Props>()
|
|||||||
|
|
||||||
.balance-amount {
|
.balance-amount {
|
||||||
font-size: var(--font-4xl);
|
font-size: var(--font-4xl);
|
||||||
font-weight: var(--font-semibold);
|
font-weight: var(--font-bold);
|
||||||
color: var(--primary-color);
|
color: var(--text-primary);
|
||||||
margin-bottom: var(--spacing-lg);
|
margin-bottom: var(--spacing-lg);
|
||||||
letter-spacing: var(--tracking-tight);
|
letter-spacing: var(--tracking-tight);
|
||||||
}
|
}
|
||||||
@ -58,6 +56,7 @@ 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 {
|
||||||
@ -66,7 +65,6 @@ 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 { BalanceResult, Utxo } from '@/interface'
|
import type { Utxo } from '@/interface'
|
||||||
|
|
||||||
const neptuneStore = useNeptuneStore()
|
const neptuneStore = useNeptuneStore()
|
||||||
const {
|
const {
|
||||||
@ -18,17 +18,15 @@ const {
|
|||||||
} = useNeptuneWallet()
|
} = useNeptuneWallet()
|
||||||
const activeTabKey = inject<ComputedRef<string>>('activeTabKey')
|
const activeTabKey = inject<ComputedRef<string>>('activeTabKey')
|
||||||
|
|
||||||
const availableBalance = ref<BalanceResult['balance']>('0.00000000')
|
const availableBalance = ref<string>('0.00000000')
|
||||||
const pendingBalance = ref< BalanceResult['pendingBalance']>('0.00000000')
|
const pendingBalance = ref<string>('0.00000000')
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const sendingLoading = ref(false)
|
|
||||||
const error = ref<string | null>(null)
|
const error = ref<string | null>(null)
|
||||||
const showSeedModal = ref(false)
|
const showSeedModal = ref(false)
|
||||||
const isSendingMode = ref(false)
|
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 || '')
|
||||||
|
|
||||||
@ -65,7 +63,7 @@ const handleSendTransaction = async (data: {
|
|||||||
fee: string
|
fee: string
|
||||||
}) => {
|
}) => {
|
||||||
try {
|
try {
|
||||||
sendingLoading.value = true
|
loading.value = true
|
||||||
const payload = {
|
const payload = {
|
||||||
spendingKeyHex: neptuneStore.getSpendingKey || '',
|
spendingKeyHex: neptuneStore.getSpendingKey || '',
|
||||||
inputAdditionRecords: neptuneStore.getUtxos?.map((utxo: Utxo) => utxo.additionRecord),
|
inputAdditionRecords: neptuneStore.getUtxos?.map((utxo: Utxo) => utxo.additionRecord),
|
||||||
@ -91,13 +89,21 @@ const handleSendTransaction = async (data: {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error('Failed to send transaction')
|
message.error('Failed to send transaction')
|
||||||
} finally {
|
} finally {
|
||||||
sendingLoading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBackupFile = async () => {
|
const handleBackupFile = async () => {
|
||||||
try {
|
try {
|
||||||
await saveKeystoreAs()
|
const seed = neptuneStore.getSeedPhraseString
|
||||||
|
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
|
||||||
@ -119,8 +125,7 @@ const handlePasswordVerify = async (password: string) => {
|
|||||||
isVerifying.value = true
|
isVerifying.value = true
|
||||||
passwordError.value = false
|
passwordError.value = false
|
||||||
|
|
||||||
const result = await decryptKeystore(password)
|
await decryptKeystore(password)
|
||||||
seedPhrase.value = result.seedPhrase
|
|
||||||
|
|
||||||
isVerifyingPassword.value = false
|
isVerifyingPassword.value = false
|
||||||
showSeedModal.value = true
|
showSeedModal.value = true
|
||||||
@ -144,8 +149,8 @@ const loadWalletData = async () => {
|
|||||||
try {
|
try {
|
||||||
const result = await getBalance()
|
const result = await getBalance()
|
||||||
|
|
||||||
availableBalance.value = result?.balance ?? '0.00000000'
|
availableBalance.value = result?.balance || result || '0.00000000'
|
||||||
pendingBalance.value = result?.pendingBalance ?? '0.00000000'
|
pendingBalance.value = result?.pendingBalance || result || '0.00000000'
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error('Failed to load wallet data')
|
message.error('Failed to load wallet data')
|
||||||
} finally {
|
} finally {
|
||||||
@ -230,14 +235,14 @@ watch(
|
|||||||
<!-- Send Transaction View -->
|
<!-- Send Transaction View -->
|
||||||
<div v-else-if="isSendingMode" class="send-transaction-wrapper">
|
<div v-else-if="isSendingMode" class="send-transaction-wrapper">
|
||||||
<SendTransactionComponent
|
<SendTransactionComponent
|
||||||
:is-loading="sendingLoading"
|
:is-loading="loading"
|
||||||
:available-balance="availableBalance"
|
:available-balance="availableBalance"
|
||||||
@cancel="handleCancelSend"
|
@cancel="handleCancelSend"
|
||||||
@send="handleSendTransaction"
|
@send="handleSendTransaction"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Loading Overlay -->
|
<!-- Loading Overlay -->
|
||||||
<div v-if="sendingLoading" class="sending-overlay">
|
<div v-if="loading" class="sending-overlay">
|
||||||
<div class="sending-content">
|
<div class="sending-content">
|
||||||
<SpinnerCommon size="large" />
|
<SpinnerCommon size="large" />
|
||||||
<p class="sending-text">Sending...</p>
|
<p class="sending-text">Sending...</p>
|
||||||
@ -261,7 +266,7 @@ watch(
|
|||||||
@cancel="handleCloseModal"
|
@cancel="handleCloseModal"
|
||||||
>
|
>
|
||||||
<div class="seed-modal-content">
|
<div class="seed-modal-content">
|
||||||
<SeedPhraseDisplayComponent :seed-phrase="seedPhrase" :back-button="false" :next-button="false" />
|
<SeedPhraseDisplayComponent :back-button="false" :next-button="false" />
|
||||||
</div>
|
</div>
|
||||||
</ModalCommon>
|
</ModalCommon>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -17,9 +17,9 @@ const { t } = useI18n()
|
|||||||
<h3 class="h2">
|
<h3 class="h2">
|
||||||
{{ t('notFound.title') }}
|
{{ t('notFound.title') }}
|
||||||
</h3>
|
</h3>
|
||||||
<router-link to="/auth" class="link_404">
|
<a href="/reservations" class="link_404">
|
||||||
{{ t('notFound.back') }}
|
{{ t('notFound.back') }}
|
||||||
</router-link>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,12 +1,6 @@
|
|||||||
{
|
{
|
||||||
"extends": "@tsconfig/node20/tsconfig.json",
|
"extends": "@tsconfig/node20/tsconfig.json",
|
||||||
"include": [
|
"include": ["vite.config.*", "vitest.config.*", "vite.config.ts", "env.d.ts"],
|
||||||
"vite.config.*",
|
|
||||||
"vitest.config.*",
|
|
||||||
"vite.config.ts",
|
|
||||||
"env.d.ts",
|
|
||||||
"vite-plugin-csp.ts"
|
|
||||||
],
|
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"composite": true,
|
"composite": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
|
|||||||
@ -1,34 +0,0 @@
|
|||||||
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,37 +5,27 @@ 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: [
|
plugins: [vue(), vueJsx(), VueDevTools(), Components({
|
||||||
cspPlugin(),
|
resolvers: [AntDesignVueResolver({importStyle: false})],
|
||||||
vue(),
|
})],
|
||||||
vueJsx(),
|
|
||||||
VueDevTools(),
|
|
||||||
Components({
|
|
||||||
resolvers: [AntDesignVueResolver({ importStyle: false })],
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
exclude: ['@neptune/native'],
|
exclude: ['@neptune/wasm', '@neptune/native'],
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
external: ['@neptune/native'],
|
external: ['@neptune/wasm', '@neptune/native'],
|
||||||
output: {
|
|
||||||
format: 'es',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
css: {
|
css: {
|
||||||
preprocessorOptions: {
|
preprocessorOptions: {
|
||||||
scss: {
|
scss: {
|
||||||
silenceDeprecations: ['import', 'legacy-js-api'],
|
silenceDeprecations: ['import'],
|
||||||
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