agentvault 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +9 -0
- package/README.md +1 -1
- package/dist/cli/commands/approve.js +5 -5
- package/dist/cli/commands/archive.js +5 -5
- package/dist/cli/commands/backup.js +5 -5
- package/dist/cli/commands/cloud-backup.js +12 -12
- package/dist/cli/commands/decrypt.js +2 -2
- package/dist/cli/commands/deploy.js +1 -1
- package/dist/cli/commands/exec.js +2 -2
- package/dist/cli/commands/fetch.js +4 -4
- package/dist/cli/commands/inference.js +5 -5
- package/dist/cli/commands/init.d.ts +1 -1
- package/dist/cli/commands/init.js +16 -16
- package/dist/cli/commands/list.js +4 -4
- package/dist/cli/commands/package.js +2 -2
- package/dist/cli/commands/profile.js +1 -1
- package/dist/cli/commands/rebuild.js +2 -2
- package/dist/cli/commands/show.js +1 -1
- package/dist/cli/commands/status.d.ts +1 -1
- package/dist/cli/commands/status.js +8 -8
- package/dist/cli/commands/trace.js +1 -1
- package/dist/cli/commands/wallet-export.js +1 -1
- package/dist/cli/commands/wallet-sign.js +1 -1
- package/dist/cli/commands/wallet.d.ts +1 -1
- package/dist/cli/commands/wallet.js +1 -1
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.js +3 -3
- package/dist/src/archival/archive-manager.d.ts +85 -0
- package/dist/src/archival/archive-manager.js +294 -0
- package/dist/src/archival/arweave-client.d.ts +88 -0
- package/dist/src/archival/arweave-client.js +223 -0
- package/dist/src/archival/index.d.ts +8 -0
- package/{src/archival/index.ts → dist/src/archival/index.js} +1 -1
- package/dist/src/backup/backup.d.ts +67 -0
- package/dist/src/backup/backup.js +231 -0
- package/dist/src/backup/index.d.ts +7 -0
- package/{src/backup/index.ts → dist/src/backup/index.js} +1 -1
- package/dist/src/cloud-storage/cloud-sync.d.ts +49 -0
- package/dist/src/cloud-storage/cloud-sync.js +372 -0
- package/dist/src/cloud-storage/index.d.ts +11 -0
- package/{src/cloud-storage/index.ts → dist/src/cloud-storage/index.js} +1 -1
- package/dist/src/cloud-storage/provider-detector.d.ts +34 -0
- package/dist/src/cloud-storage/provider-detector.js +158 -0
- package/{src/cloud-storage/types.ts → dist/src/cloud-storage/types.d.ts} +40 -53
- package/dist/src/cloud-storage/types.js +10 -0
- package/dist/src/debugging/index.d.ts +6 -0
- package/{src/debugging/index.ts → dist/src/debugging/index.js} +1 -1
- package/dist/src/debugging/logs.d.ts +32 -0
- package/dist/src/debugging/logs.js +158 -0
- package/dist/src/debugging/types.d.ts +91 -0
- package/dist/src/debugging/types.js +5 -0
- package/dist/src/deployment/deployer.d.ts +52 -0
- package/dist/src/deployment/deployer.js +211 -0
- package/dist/src/deployment/icpClient.d.ts +144 -0
- package/dist/src/deployment/icpClient.js +545 -0
- package/dist/src/deployment/index.d.ts +11 -0
- package/dist/src/deployment/index.js +14 -0
- package/dist/src/deployment/promotion.d.ts +32 -0
- package/dist/src/deployment/promotion.js +114 -0
- package/dist/src/deployment/types.d.ts +101 -0
- package/dist/src/deployment/types.js +5 -0
- package/dist/src/icp/batch.d.ts +112 -0
- package/dist/src/icp/batch.js +273 -0
- package/dist/src/icp/cycles.d.ts +29 -0
- package/{src/icp/cycles.ts → dist/src/icp/cycles.js} +8 -22
- package/dist/src/icp/environment.d.ts +60 -0
- package/dist/src/icp/environment.js +183 -0
- package/dist/src/icp/icpcli.d.ts +204 -0
- package/dist/src/icp/icpcli.js +374 -0
- package/dist/src/icp/icwasm.d.ts +94 -0
- package/dist/src/icp/icwasm.js +197 -0
- package/dist/src/icp/identity.d.ts +50 -0
- package/{src/icp/identity.ts → dist/src/icp/identity.js} +15 -28
- package/dist/src/icp/index.d.ts +16 -0
- package/dist/src/icp/index.js +20 -0
- package/dist/src/icp/optimization.d.ts +16 -0
- package/dist/src/icp/optimization.js +225 -0
- package/dist/src/icp/tokens.d.ts +24 -0
- package/{src/icp/tokens.ts → dist/src/icp/tokens.js} +5 -12
- package/dist/src/icp/tool-detector.d.ts +31 -0
- package/dist/src/icp/tool-detector.js +104 -0
- package/dist/src/icp/types.d.ts +493 -0
- package/dist/src/icp/types.js +7 -0
- package/dist/src/index.d.ts +12 -0
- package/dist/src/index.js +18 -0
- package/dist/src/inference/bittensor-client.d.ts +108 -0
- package/dist/src/inference/bittensor-client.js +224 -0
- package/dist/src/inference/index.d.ts +8 -0
- package/{src/inference/index.ts → dist/src/inference/index.js} +1 -1
- package/dist/src/inference/inference-manager.d.ts +76 -0
- package/dist/src/inference/inference-manager.js +228 -0
- package/dist/src/metrics/index.d.ts +7 -0
- package/{src/metrics/index.ts → dist/src/metrics/index.js} +1 -1
- package/dist/src/metrics/metrics.d.ts +39 -0
- package/dist/src/metrics/metrics.js +129 -0
- package/dist/src/monitoring/alerting.d.ts +51 -0
- package/dist/src/monitoring/alerting.js +169 -0
- package/dist/src/monitoring/health.d.ts +40 -0
- package/dist/src/monitoring/health.js +164 -0
- package/dist/src/monitoring/index.d.ts +10 -0
- package/dist/src/monitoring/index.js +12 -0
- package/dist/src/monitoring/info.d.ts +15 -0
- package/dist/src/monitoring/info.js +109 -0
- package/dist/src/monitoring/types.d.ts +93 -0
- package/dist/src/monitoring/types.js +7 -0
- package/dist/src/network/index.d.ts +5 -0
- package/{src/network/index.ts → dist/src/network/index.js} +1 -1
- package/dist/src/network/network-config.d.ts +31 -0
- package/dist/src/network/network-config.js +109 -0
- package/dist/src/packaging/compiler.d.ts +61 -0
- package/dist/src/packaging/compiler.js +562 -0
- package/dist/src/packaging/config-persistence.d.ts +46 -0
- package/dist/src/packaging/config-persistence.js +108 -0
- package/dist/src/packaging/config-schemas.d.ts +115 -0
- package/dist/src/packaging/config-schemas.js +43 -0
- package/dist/src/packaging/detector.d.ts +26 -0
- package/dist/src/packaging/detector.js +193 -0
- package/dist/src/packaging/index.d.ts +16 -0
- package/dist/src/packaging/index.js +22 -0
- package/dist/src/packaging/packager.d.ts +31 -0
- package/dist/src/packaging/packager.js +90 -0
- package/dist/src/packaging/parsers/clawdbot.d.ts +19 -0
- package/dist/src/packaging/parsers/clawdbot.js +231 -0
- package/dist/src/packaging/parsers/cline.d.ts +26 -0
- package/dist/src/packaging/parsers/cline.js +185 -0
- package/dist/src/packaging/parsers/generic.d.ts +27 -0
- package/dist/src/packaging/parsers/generic.js +228 -0
- package/dist/src/packaging/parsers/goose.d.ts +26 -0
- package/dist/src/packaging/parsers/goose.js +175 -0
- package/dist/src/packaging/parsers/index.d.ts +11 -0
- package/{src/packaging/parsers/index.ts → dist/src/packaging/parsers/index.js} +1 -1
- package/dist/src/packaging/serializer.d.ts +108 -0
- package/dist/src/packaging/serializer.js +153 -0
- package/dist/src/packaging/types.d.ts +131 -0
- package/dist/src/packaging/types.js +5 -0
- package/dist/src/packaging/wasmedge-compiler.d.ts +76 -0
- package/dist/src/packaging/wasmedge-compiler.js +349 -0
- package/dist/src/security/index.d.ts +11 -0
- package/{src/security/index.ts → dist/src/security/index.js} +1 -4
- package/dist/src/security/multisig.d.ts +102 -0
- package/dist/src/security/multisig.js +283 -0
- package/dist/src/security/types.d.ts +207 -0
- package/dist/src/security/types.js +217 -0
- package/dist/src/security/vetkeys.d.ts +179 -0
- package/dist/src/security/vetkeys.js +499 -0
- package/dist/src/testing/index.d.ts +6 -0
- package/{src/testing/index.ts → dist/src/testing/index.js} +1 -1
- package/dist/src/testing/local-runner.d.ts +23 -0
- package/dist/src/testing/local-runner.js +226 -0
- package/dist/src/testing/types.d.ts +98 -0
- package/dist/src/testing/types.js +5 -0
- package/dist/src/wallet/cbor-serializer.d.ts +82 -0
- package/dist/src/wallet/cbor-serializer.js +282 -0
- package/dist/src/wallet/chain-dispatcher.d.ts +112 -0
- package/dist/src/wallet/chain-dispatcher.js +241 -0
- package/dist/src/wallet/cross-chain-aggregator.d.ts +119 -0
- package/dist/src/wallet/cross-chain-aggregator.js +235 -0
- package/dist/src/wallet/index.d.ts +16 -0
- package/dist/src/wallet/index.js +22 -0
- package/dist/src/wallet/key-derivation.d.ts +117 -0
- package/dist/src/wallet/key-derivation.js +325 -0
- package/dist/src/wallet/providers/base-provider.d.ts +111 -0
- package/dist/src/wallet/providers/base-provider.js +58 -0
- package/dist/src/wallet/providers/cketh-provider.d.ts +104 -0
- package/dist/src/wallet/providers/cketh-provider.js +343 -0
- package/dist/src/wallet/providers/polkadot-provider.d.ts +115 -0
- package/dist/src/wallet/providers/polkadot-provider.js +407 -0
- package/dist/src/wallet/providers/solana-provider.d.ts +102 -0
- package/dist/src/wallet/providers/solana-provider.js +393 -0
- package/dist/src/wallet/transaction-queue.d.ts +133 -0
- package/dist/src/wallet/transaction-queue.js +195 -0
- package/dist/src/wallet/types.d.ts +167 -0
- package/dist/src/wallet/types.js +5 -0
- package/dist/src/wallet/vetkeys-adapter.d.ts +134 -0
- package/dist/src/wallet/vetkeys-adapter.js +313 -0
- package/dist/src/wallet/wallet-manager.d.ts +202 -0
- package/dist/src/wallet/wallet-manager.js +451 -0
- package/dist/src/wallet/wallet-storage.d.ts +131 -0
- package/dist/src/wallet/wallet-storage.js +274 -0
- package/macos-wallet-app/AgentVaultWallet/App/AgentVaultWalletApp.swift +54 -0
- package/macos-wallet-app/AgentVaultWallet/Models/AppState.swift +102 -0
- package/macos-wallet-app/AgentVaultWallet/Models/Chain.swift +121 -0
- package/macos-wallet-app/AgentVaultWallet/Models/Wallet.swift +98 -0
- package/macos-wallet-app/AgentVaultWallet/Resources/AgentVaultWallet.entitlements +27 -0
- package/macos-wallet-app/AgentVaultWallet/Resources/Info.plist +69 -0
- package/macos-wallet-app/AgentVaultWallet/Services/BackupService.swift +270 -0
- package/macos-wallet-app/AgentVaultWallet/Services/CLIBridge.swift +367 -0
- package/macos-wallet-app/AgentVaultWallet/Services/CryptoService.swift +157 -0
- package/macos-wallet-app/AgentVaultWallet/Services/FileService.swift +120 -0
- package/macos-wallet-app/AgentVaultWallet/Services/KeychainService.swift +219 -0
- package/macos-wallet-app/AgentVaultWallet/Utilities/Constants.swift +44 -0
- package/macos-wallet-app/AgentVaultWallet/Utilities/Extensions.swift +115 -0
- package/macos-wallet-app/AgentVaultWallet/ViewModels/BackupViewModel.swift +237 -0
- package/macos-wallet-app/AgentVaultWallet/ViewModels/CreateWalletViewModel.swift +137 -0
- package/macos-wallet-app/AgentVaultWallet/ViewModels/ImportWalletViewModel.swift +179 -0
- package/macos-wallet-app/AgentVaultWallet/ViewModels/WalletStore.swift +286 -0
- package/macos-wallet-app/AgentVaultWallet/Views/Backup/BackupView.swift +235 -0
- package/macos-wallet-app/AgentVaultWallet/Views/Backup/RestoreView.swift +316 -0
- package/macos-wallet-app/AgentVaultWallet/Views/Create/CreateWalletFlow.swift +438 -0
- package/macos-wallet-app/AgentVaultWallet/Views/Import/ImportWalletFlow.swift +399 -0
- package/macos-wallet-app/AgentVaultWallet/Views/MainView.swift +134 -0
- package/macos-wallet-app/AgentVaultWallet/Views/Settings/SettingsView.swift +276 -0
- package/macos-wallet-app/AgentVaultWallet/Views/Sidebar/SidebarView.swift +133 -0
- package/macos-wallet-app/AgentVaultWallet/Views/Wallet/DashboardView.swift +233 -0
- package/macos-wallet-app/AgentVaultWallet/Views/Wallet/WalletDetailView.swift +281 -0
- package/macos-wallet-app/AgentVaultWallet/Views/Wallet/WalletListView.swift +280 -0
- package/macos-wallet-app/AgentVaultWallet/Views/Welcome/WelcomeView.swift +176 -0
- package/macos-wallet-app/Makefile +47 -0
- package/macos-wallet-app/project.yml +40 -0
- package/macos-wallet-app/setup.sh +73 -0
- package/package.json +10 -2
- package/backups/agentvault-backup-test-agent-2026-02-12T17-54-28-967Z.json +0 -28
- package/backups/agentvault-backup-test-agent-2026-02-12T17-54-29-032Z.backup +0 -1
- package/backups/agentvault-backup-test-agent-2026-02-12T17-57-42-373Z.json +0 -28
- package/backups/agentvault-backup-test-agent-2026-02-12T17-57-42-428Z.backup +0 -1
- package/backups/agentvault-backup-test-agent-2026-02-12T18-52-25-132Z.json +0 -28
- package/backups/agentvault-backup-test-agent-2026-02-12T18-52-25-247Z.backup +0 -1
- package/backups/agentvault-backup-test-agent-2026-02-12T18-54-09-216Z.json +0 -28
- package/backups/agentvault-backup-test-agent-2026-02-12T18-54-09-283Z.backup +0 -1
- package/backups/agentvault-backup-test-agent-2026-02-12T22-18-22-772Z.backup +0 -1
- package/backups/agentvault-backup-test-agent-2026-02-12T22-18-22-793Z.json +0 -28
- package/backups/test-backup.json +0 -28
- package/scripts/dev-dashboard.mjs +0 -84
- package/site/README.md +0 -63
- package/site/docusaurus.config.ts +0 -148
- package/site/package-lock.json +0 -18383
- package/site/package.json +0 -47
- package/site/sidebars.ts +0 -86
- package/site/static/.gitkeep +0 -0
- package/site/static/img/logo.svg +0 -28
- package/site/static/img/og-image.svg +0 -35
- package/src/archival/archive-manager.ts +0 -372
- package/src/archival/arweave-client.ts +0 -289
- package/src/backup/backup.ts +0 -315
- package/src/cloud-storage/cloud-sync.ts +0 -461
- package/src/cloud-storage/provider-detector.ts +0 -198
- package/src/debugging/logs.ts +0 -193
- package/src/debugging/types.ts +0 -100
- package/src/deployment/deployer.ts +0 -274
- package/src/deployment/icpClient.ts +0 -620
- package/src/deployment/index.ts +0 -46
- package/src/deployment/promotion.ts +0 -161
- package/src/deployment/types.ts +0 -111
- package/src/icp/batch.ts +0 -374
- package/src/icp/environment.ts +0 -215
- package/src/icp/icpcli.ts +0 -438
- package/src/icp/icwasm.ts +0 -222
- package/src/icp/index.ts +0 -94
- package/src/icp/optimization.ts +0 -242
- package/src/icp/tool-detector.ts +0 -110
- package/src/icp/types.ts +0 -574
- package/src/index.ts +0 -25
- package/src/inference/bittensor-client.ts +0 -304
- package/src/inference/inference-manager.ts +0 -327
- package/src/metrics/metrics.ts +0 -186
- package/src/monitoring/alerting.ts +0 -190
- package/src/monitoring/health.ts +0 -197
- package/src/monitoring/index.ts +0 -38
- package/src/monitoring/info.ts +0 -114
- package/src/monitoring/types.ts +0 -99
- package/src/network/network-config.ts +0 -129
- package/src/packaging/compiler.ts +0 -647
- package/src/packaging/config-persistence.ts +0 -135
- package/src/packaging/config-schemas.ts +0 -156
- package/src/packaging/detector.ts +0 -220
- package/src/packaging/index.ts +0 -90
- package/src/packaging/packager.ts +0 -118
- package/src/packaging/parsers/clawdbot.ts +0 -278
- package/src/packaging/parsers/cline.ts +0 -223
- package/src/packaging/parsers/generic.ts +0 -266
- package/src/packaging/parsers/goose.ts +0 -214
- package/src/packaging/serializer.ts +0 -260
- package/src/packaging/types.ts +0 -144
- package/src/packaging/wasmedge-compiler.ts +0 -406
- package/src/security/multisig.ts +0 -415
- package/src/security/types.ts +0 -416
- package/src/security/vetkeys.ts +0 -655
- package/src/testing/local-runner.ts +0 -264
- package/src/testing/types.ts +0 -104
- package/src/wallet/cbor-serializer.ts +0 -323
- package/src/wallet/chain-dispatcher.ts +0 -313
- package/src/wallet/cross-chain-aggregator.ts +0 -346
- package/src/wallet/index.ts +0 -76
- package/src/wallet/key-derivation.ts +0 -425
- package/src/wallet/providers/base-provider.ts +0 -154
- package/src/wallet/providers/cketh-provider.ts +0 -434
- package/src/wallet/providers/polkadot-provider.ts +0 -503
- package/src/wallet/providers/solana-provider.ts +0 -490
- package/src/wallet/transaction-queue.ts +0 -284
- package/src/wallet/types.ts +0 -178
- package/src/wallet/vetkeys-adapter.ts +0 -431
- package/src/wallet/wallet-manager.ts +0 -597
- package/src/wallet/wallet-storage.ts +0 -380
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>CFBundleName</key>
|
|
6
|
+
<string>AgentVault Wallet</string>
|
|
7
|
+
<key>CFBundleDisplayName</key>
|
|
8
|
+
<string>AgentVault Wallet</string>
|
|
9
|
+
<key>CFBundleIdentifier</key>
|
|
10
|
+
<string>com.agentvault.wallet</string>
|
|
11
|
+
<key>CFBundleVersion</key>
|
|
12
|
+
<string>1</string>
|
|
13
|
+
<key>CFBundleShortVersionString</key>
|
|
14
|
+
<string>1.0.0</string>
|
|
15
|
+
<key>CFBundlePackageType</key>
|
|
16
|
+
<string>APPL</string>
|
|
17
|
+
<key>CFBundleExecutable</key>
|
|
18
|
+
<string>$(EXECUTABLE_NAME)</string>
|
|
19
|
+
<key>CFBundleInfoDictionaryVersion</key>
|
|
20
|
+
<string>6.0</string>
|
|
21
|
+
<key>LSMinimumSystemVersion</key>
|
|
22
|
+
<string>14.0</string>
|
|
23
|
+
<key>LSApplicationCategoryType</key>
|
|
24
|
+
<string>public.app-category.finance</string>
|
|
25
|
+
<key>NSMainNibFile</key>
|
|
26
|
+
<string></string>
|
|
27
|
+
<key>NSPrincipalClass</key>
|
|
28
|
+
<string>NSApplication</string>
|
|
29
|
+
<key>NSHumanReadableCopyright</key>
|
|
30
|
+
<string>Copyright 2024 AgentVault. All rights reserved.</string>
|
|
31
|
+
<key>CFBundleDocumentTypes</key>
|
|
32
|
+
<array>
|
|
33
|
+
<dict>
|
|
34
|
+
<key>CFBundleTypeName</key>
|
|
35
|
+
<string>AgentVault Backup</string>
|
|
36
|
+
<key>CFBundleTypeExtensions</key>
|
|
37
|
+
<array>
|
|
38
|
+
<string>avbackup</string>
|
|
39
|
+
</array>
|
|
40
|
+
<key>CFBundleTypeRole</key>
|
|
41
|
+
<string>Editor</string>
|
|
42
|
+
<key>LSHandlerRank</key>
|
|
43
|
+
<string>Owner</string>
|
|
44
|
+
<key>CFBundleTypeIconFiles</key>
|
|
45
|
+
<array/>
|
|
46
|
+
</dict>
|
|
47
|
+
</array>
|
|
48
|
+
<key>UTExportedTypeDeclarations</key>
|
|
49
|
+
<array>
|
|
50
|
+
<dict>
|
|
51
|
+
<key>UTTypeIdentifier</key>
|
|
52
|
+
<string>com.agentvault.backup</string>
|
|
53
|
+
<key>UTTypeDescription</key>
|
|
54
|
+
<string>AgentVault Wallet Backup</string>
|
|
55
|
+
<key>UTTypeConformsTo</key>
|
|
56
|
+
<array>
|
|
57
|
+
<string>public.data</string>
|
|
58
|
+
</array>
|
|
59
|
+
<key>UTTypeTagSpecification</key>
|
|
60
|
+
<dict>
|
|
61
|
+
<key>public.filename-extension</key>
|
|
62
|
+
<array>
|
|
63
|
+
<string>avbackup</string>
|
|
64
|
+
</array>
|
|
65
|
+
</dict>
|
|
66
|
+
</dict>
|
|
67
|
+
</array>
|
|
68
|
+
</dict>
|
|
69
|
+
</plist>
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
/// Handles wallet backup creation and restoration.
|
|
4
|
+
/// Backups are encrypted with AES-256-GCM using a user-provided password.
|
|
5
|
+
final class BackupService {
|
|
6
|
+
|
|
7
|
+
static let shared = BackupService()
|
|
8
|
+
|
|
9
|
+
private let crypto = CryptoService.shared
|
|
10
|
+
private let keychain = KeychainService.shared
|
|
11
|
+
private let fileManager = FileManager.default
|
|
12
|
+
|
|
13
|
+
enum BackupError: LocalizedError {
|
|
14
|
+
case noWalletsToBackup
|
|
15
|
+
case serializationFailed
|
|
16
|
+
case fileWriteFailed(String)
|
|
17
|
+
case fileReadFailed(String)
|
|
18
|
+
case invalidBackupFormat
|
|
19
|
+
case versionMismatch(Int)
|
|
20
|
+
case decryptionFailed
|
|
21
|
+
case corruptedBackup
|
|
22
|
+
|
|
23
|
+
var errorDescription: String? {
|
|
24
|
+
switch self {
|
|
25
|
+
case .noWalletsToBackup:
|
|
26
|
+
return "No wallets to back up"
|
|
27
|
+
case .serializationFailed:
|
|
28
|
+
return "Failed to serialize wallet data"
|
|
29
|
+
case .fileWriteFailed(let path):
|
|
30
|
+
return "Failed to write backup file to \(path)"
|
|
31
|
+
case .fileReadFailed(let path):
|
|
32
|
+
return "Failed to read backup file at \(path)"
|
|
33
|
+
case .invalidBackupFormat:
|
|
34
|
+
return "The selected file is not a valid AgentVault backup"
|
|
35
|
+
case .versionMismatch(let v):
|
|
36
|
+
return "Backup version \(v) is not supported by this app version"
|
|
37
|
+
case .decryptionFailed:
|
|
38
|
+
return "Failed to decrypt backup — incorrect password?"
|
|
39
|
+
case .corruptedBackup:
|
|
40
|
+
return "Backup file appears to be corrupted"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
private init() {}
|
|
46
|
+
|
|
47
|
+
// MARK: - Backup Creation
|
|
48
|
+
|
|
49
|
+
/// Create an encrypted backup of all provided wallets
|
|
50
|
+
func createBackup(wallets: [Wallet], password: String) throws -> Data {
|
|
51
|
+
guard !wallets.isEmpty else {
|
|
52
|
+
throw BackupError.noWalletsToBackup
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Collect secrets for each wallet
|
|
56
|
+
var secrets: [[String: String]] = []
|
|
57
|
+
for wallet in wallets {
|
|
58
|
+
var entry: [String: String] = [
|
|
59
|
+
"id": wallet.id.uuidString,
|
|
60
|
+
"chain": wallet.chain.rawValue,
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
if let mnemonic = try? keychain.getMnemonic(forWalletId: wallet.id) {
|
|
64
|
+
entry["mnemonic"] = mnemonic
|
|
65
|
+
}
|
|
66
|
+
if let privateKey = try? keychain.getPrivateKey(forWalletId: wallet.id) {
|
|
67
|
+
entry["privateKey"] = privateKey
|
|
68
|
+
}
|
|
69
|
+
if let jwkData = try? keychain.getJWK(forWalletId: wallet.id) {
|
|
70
|
+
entry["jwk"] = String(data: jwkData, encoding: .utf8)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
secrets.append(entry)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Serialize secrets to JSON
|
|
77
|
+
guard let secretsData = try? JSONSerialization.data(withJSONObject: secrets, options: []) else {
|
|
78
|
+
throw BackupError.serializationFailed
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Encrypt secrets
|
|
82
|
+
let encrypted = try crypto.encrypt(data: secretsData, password: password)
|
|
83
|
+
|
|
84
|
+
// Build backup entries
|
|
85
|
+
let entries = wallets.map { wallet in
|
|
86
|
+
WalletBackupEntry(
|
|
87
|
+
id: wallet.id,
|
|
88
|
+
name: wallet.name,
|
|
89
|
+
chain: wallet.chain,
|
|
90
|
+
address: wallet.address,
|
|
91
|
+
createdAt: wallet.createdAt,
|
|
92
|
+
derivationPath: wallet.derivationPath,
|
|
93
|
+
hasMnemonicBackup: wallet.hasMnemonicBackup
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Create backup structure
|
|
98
|
+
let backup = WalletBackup(
|
|
99
|
+
version: WalletBackup.currentVersion,
|
|
100
|
+
createdAt: Date(),
|
|
101
|
+
appVersion: Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0.0",
|
|
102
|
+
wallets: entries,
|
|
103
|
+
encryptedPayload: encrypted.ciphertext,
|
|
104
|
+
salt: encrypted.salt,
|
|
105
|
+
iv: encrypted.nonce
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
// Encode to JSON
|
|
109
|
+
let encoder = JSONEncoder()
|
|
110
|
+
encoder.dateEncodingStrategy = .iso8601
|
|
111
|
+
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
|
|
112
|
+
|
|
113
|
+
guard let backupData = try? encoder.encode(backup) else {
|
|
114
|
+
throw BackupError.serializationFailed
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return backupData
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/// Write backup data to a file
|
|
121
|
+
func writeBackup(_ data: Data, to url: URL) throws {
|
|
122
|
+
do {
|
|
123
|
+
try data.write(to: url, options: [.atomic, .completeFileProtection])
|
|
124
|
+
} catch {
|
|
125
|
+
throw BackupError.fileWriteFailed(url.path)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// MARK: - Backup Restoration
|
|
130
|
+
|
|
131
|
+
/// Read and validate a backup file, returning the metadata (before decryption)
|
|
132
|
+
func readBackupMetadata(from url: URL) throws -> WalletBackup {
|
|
133
|
+
guard let data = try? Data(contentsOf: url) else {
|
|
134
|
+
throw BackupError.fileReadFailed(url.path)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
let decoder = JSONDecoder()
|
|
138
|
+
decoder.dateDecodingStrategy = .iso8601
|
|
139
|
+
|
|
140
|
+
guard let backup = try? decoder.decode(WalletBackup.self, from: data) else {
|
|
141
|
+
throw BackupError.invalidBackupFormat
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
guard backup.version <= WalletBackup.currentVersion else {
|
|
145
|
+
throw BackupError.versionMismatch(backup.version)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return backup
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/// Decrypt and extract wallet secrets from a backup
|
|
152
|
+
func restoreSecrets(from backup: WalletBackup, password: String) throws -> [RestoredWalletSecret] {
|
|
153
|
+
let encrypted = CryptoService.EncryptedData(
|
|
154
|
+
ciphertext: backup.encryptedPayload,
|
|
155
|
+
nonce: backup.iv,
|
|
156
|
+
tag: Data(repeating: 0, count: 16), // Tag is embedded in ciphertext for our format
|
|
157
|
+
salt: backup.salt
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
let decryptedData: Data
|
|
161
|
+
do {
|
|
162
|
+
decryptedData = try crypto.decrypt(encrypted: encrypted, password: password)
|
|
163
|
+
} catch {
|
|
164
|
+
throw BackupError.decryptionFailed
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
guard let secrets = try? JSONSerialization.jsonObject(with: decryptedData) as? [[String: String]] else {
|
|
168
|
+
throw BackupError.corruptedBackup
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return secrets.compactMap { entry in
|
|
172
|
+
guard let idStr = entry["id"],
|
|
173
|
+
let id = UUID(uuidString: idStr),
|
|
174
|
+
let chainStr = entry["chain"],
|
|
175
|
+
let chain = Chain(rawValue: chainStr) else {
|
|
176
|
+
return nil
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return RestoredWalletSecret(
|
|
180
|
+
walletId: id,
|
|
181
|
+
chain: chain,
|
|
182
|
+
mnemonic: entry["mnemonic"],
|
|
183
|
+
privateKey: entry["privateKey"],
|
|
184
|
+
jwkJSON: entry["jwk"]
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/// Save restored secrets to Keychain
|
|
190
|
+
func saveRestoredSecrets(_ secrets: [RestoredWalletSecret]) throws {
|
|
191
|
+
for secret in secrets {
|
|
192
|
+
if let mnemonic = secret.mnemonic {
|
|
193
|
+
try keychain.saveMnemonic(mnemonic, forWalletId: secret.walletId)
|
|
194
|
+
}
|
|
195
|
+
if let privateKey = secret.privateKey {
|
|
196
|
+
try keychain.savePrivateKey(privateKey, forWalletId: secret.walletId)
|
|
197
|
+
}
|
|
198
|
+
if let jwkJSON = secret.jwkJSON, let jwkData = jwkJSON.data(using: .utf8) {
|
|
199
|
+
try keychain.saveJWK(jwkData, forWalletId: secret.walletId)
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// MARK: - Backup File Management
|
|
205
|
+
|
|
206
|
+
/// Default backup directory
|
|
207
|
+
var defaultBackupDirectory: URL {
|
|
208
|
+
let appSupport = fileManager.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
|
|
209
|
+
let backupDir = appSupport.appendingPathComponent("AgentVaultWallet/Backups", isDirectory: true)
|
|
210
|
+
try? fileManager.createDirectory(at: backupDir, withIntermediateDirectories: true)
|
|
211
|
+
return backupDir
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/// Generate a default backup filename
|
|
215
|
+
func defaultBackupFilename() -> String {
|
|
216
|
+
let formatter = DateFormatter()
|
|
217
|
+
formatter.dateFormat = "yyyy-MM-dd_HHmmss"
|
|
218
|
+
return "agentvault-backup-\(formatter.string(from: Date())).avbackup"
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/// List existing backup files in the default directory
|
|
222
|
+
func listBackups() -> [BackupFileInfo] {
|
|
223
|
+
guard let contents = try? fileManager.contentsOfDirectory(
|
|
224
|
+
at: defaultBackupDirectory,
|
|
225
|
+
includingPropertiesForKeys: [.creationDateKey, .fileSizeKey],
|
|
226
|
+
options: .skipsHiddenFiles
|
|
227
|
+
) else { return [] }
|
|
228
|
+
|
|
229
|
+
return contents
|
|
230
|
+
.filter { $0.pathExtension == "avbackup" }
|
|
231
|
+
.compactMap { url -> BackupFileInfo? in
|
|
232
|
+
let attrs = try? fileManager.attributesOfItem(atPath: url.path)
|
|
233
|
+
let size = attrs?[.size] as? Int ?? 0
|
|
234
|
+
let created = attrs?[.creationDate] as? Date ?? Date()
|
|
235
|
+
let walletCount = (try? readBackupMetadata(from: url))?.wallets.count
|
|
236
|
+
|
|
237
|
+
return BackupFileInfo(
|
|
238
|
+
url: url,
|
|
239
|
+
filename: url.lastPathComponent,
|
|
240
|
+
createdAt: created,
|
|
241
|
+
fileSize: size,
|
|
242
|
+
walletCount: walletCount
|
|
243
|
+
)
|
|
244
|
+
}
|
|
245
|
+
.sorted { $0.createdAt > $1.createdAt }
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/// Secrets extracted from a backup for a single wallet
|
|
250
|
+
struct RestoredWalletSecret {
|
|
251
|
+
let walletId: UUID
|
|
252
|
+
let chain: Chain
|
|
253
|
+
let mnemonic: String?
|
|
254
|
+
let privateKey: String?
|
|
255
|
+
let jwkJSON: String?
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/// Metadata about a backup file on disk
|
|
259
|
+
struct BackupFileInfo: Identifiable {
|
|
260
|
+
let id = UUID()
|
|
261
|
+
let url: URL
|
|
262
|
+
let filename: String
|
|
263
|
+
let createdAt: Date
|
|
264
|
+
let fileSize: Int
|
|
265
|
+
let walletCount: Int?
|
|
266
|
+
|
|
267
|
+
var formattedSize: String {
|
|
268
|
+
ByteCountFormatter.string(fromByteCount: Int64(fileSize), countStyle: .file)
|
|
269
|
+
}
|
|
270
|
+
}
|