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,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Signature Approval Workflows
|
|
3
|
+
*
|
|
4
|
+
* Manages local approval workflows requiring multiple signatures.
|
|
5
|
+
* This is a LOCAL approval tracking system, not cryptographic multisig.
|
|
6
|
+
*
|
|
7
|
+
* IMPORTANT: For production blockchain multisig, use:
|
|
8
|
+
* - ICP canister-based threshold signatures (VetKeys)
|
|
9
|
+
* - The canister multisig module for on-chain verification
|
|
10
|
+
*
|
|
11
|
+
* This module provides:
|
|
12
|
+
* - Approval request tracking
|
|
13
|
+
* - Signature collection and counting
|
|
14
|
+
* - Policy-based approval thresholds
|
|
15
|
+
* - Audit trail for approvals
|
|
16
|
+
*/
|
|
17
|
+
import fs from 'node:fs';
|
|
18
|
+
import path from 'node:path';
|
|
19
|
+
import os from 'node:os';
|
|
20
|
+
import crypto from 'node:crypto';
|
|
21
|
+
import { parse, stringify } from 'yaml';
|
|
22
|
+
const AGENTVAULT_DIR = path.join(os.homedir(), '.agentvault');
|
|
23
|
+
const APPROVALS_DIR = path.join(AGENTVAULT_DIR, 'approvals');
|
|
24
|
+
function ensureApprovalsDir() {
|
|
25
|
+
if (!fs.existsSync(AGENTVAULT_DIR)) {
|
|
26
|
+
fs.mkdirSync(AGENTVAULT_DIR, { recursive: true });
|
|
27
|
+
}
|
|
28
|
+
if (!fs.existsSync(APPROVALS_DIR)) {
|
|
29
|
+
fs.mkdirSync(APPROVALS_DIR, { recursive: true });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function getApprovalFilePath(id) {
|
|
33
|
+
ensureApprovalsDir();
|
|
34
|
+
return path.join(APPROVALS_DIR, `${id}.yaml`);
|
|
35
|
+
}
|
|
36
|
+
function generateRequestId() {
|
|
37
|
+
return `req-${Date.now()}-${crypto.randomBytes(4).toString('hex')}`;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Create a new approval request
|
|
41
|
+
*/
|
|
42
|
+
export function createApprovalRequest(type, agentName, description, proposedBy, config, data) {
|
|
43
|
+
const id = generateRequestId();
|
|
44
|
+
const timestamp = new Date();
|
|
45
|
+
const requiredApprovals = config.requiredApprovals || calculateRequiredApprovals(config.policy, config.allowedSigners?.length || 1);
|
|
46
|
+
const request = {
|
|
47
|
+
id,
|
|
48
|
+
type,
|
|
49
|
+
agentName,
|
|
50
|
+
description,
|
|
51
|
+
proposedBy,
|
|
52
|
+
timestamp,
|
|
53
|
+
policy: config.policy,
|
|
54
|
+
requiredApprovals,
|
|
55
|
+
approvals: [],
|
|
56
|
+
status: 'pending',
|
|
57
|
+
data,
|
|
58
|
+
};
|
|
59
|
+
if (config.approvalTimeoutMs) {
|
|
60
|
+
request.expiresAt = new Date(timestamp.getTime() + config.approvalTimeoutMs);
|
|
61
|
+
}
|
|
62
|
+
const filePath = getApprovalFilePath(id);
|
|
63
|
+
fs.writeFileSync(filePath, stringify(request), 'utf8');
|
|
64
|
+
return request;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Calculate required approvals based on policy
|
|
68
|
+
*/
|
|
69
|
+
export function calculateRequiredApprovals(policy, totalSigners) {
|
|
70
|
+
switch (policy) {
|
|
71
|
+
case 'all':
|
|
72
|
+
return totalSigners;
|
|
73
|
+
case 'majority':
|
|
74
|
+
return Math.floor(totalSigners / 2) + 1;
|
|
75
|
+
case 'quorum':
|
|
76
|
+
default:
|
|
77
|
+
return Math.max(1, Math.ceil(totalSigners * 0.6));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Sign an approval request
|
|
82
|
+
*/
|
|
83
|
+
export function signApprovalRequest(id, signer, comment) {
|
|
84
|
+
const request = getApprovalRequest(id);
|
|
85
|
+
if (!request) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
if (request.status !== 'pending') {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
const existingSignature = request.approvals.find((s) => s.signer === signer);
|
|
92
|
+
if (existingSignature) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
const approvalSignature = {
|
|
96
|
+
signer,
|
|
97
|
+
auditToken: crypto.createHash('sha256')
|
|
98
|
+
.update(`${id}:${signer}:${Date.now()}:${request.description}`)
|
|
99
|
+
.digest('hex'),
|
|
100
|
+
timestamp: new Date(),
|
|
101
|
+
comment,
|
|
102
|
+
};
|
|
103
|
+
request.approvals.push(approvalSignature);
|
|
104
|
+
if (request.approvals.length >= request.requiredApprovals) {
|
|
105
|
+
request.status = 'approved';
|
|
106
|
+
}
|
|
107
|
+
const filePath = getApprovalFilePath(id);
|
|
108
|
+
fs.writeFileSync(filePath, stringify(request), 'utf8');
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Reject an approval request
|
|
113
|
+
*/
|
|
114
|
+
export function rejectApprovalRequest(id, rejectedBy, reason) {
|
|
115
|
+
const request = getApprovalRequest(id);
|
|
116
|
+
if (!request) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
if (request.status !== 'pending') {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
request.status = 'rejected';
|
|
123
|
+
request.approvals.push({
|
|
124
|
+
signer: rejectedBy,
|
|
125
|
+
auditToken: crypto.createHash('sha256')
|
|
126
|
+
.update(`${id}:rejected:${Date.now()}:${reason || 'no-reason'}`)
|
|
127
|
+
.digest('hex'),
|
|
128
|
+
timestamp: new Date(),
|
|
129
|
+
comment: `Rejected: ${reason || 'No reason provided'}`,
|
|
130
|
+
});
|
|
131
|
+
const filePath = getApprovalFilePath(id);
|
|
132
|
+
fs.writeFileSync(filePath, stringify(request), 'utf8');
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Get approval request by ID
|
|
137
|
+
*/
|
|
138
|
+
export function getApprovalRequest(id) {
|
|
139
|
+
try {
|
|
140
|
+
const filePath = getApprovalFilePath(id);
|
|
141
|
+
if (!fs.existsSync(filePath)) {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
145
|
+
const parsed = parse(content);
|
|
146
|
+
parsed.timestamp = new Date(parsed.timestamp);
|
|
147
|
+
parsed.expiresAt = parsed.expiresAt ? new Date(parsed.expiresAt) : undefined;
|
|
148
|
+
// Migrate old 'signature' field to 'auditToken' for backward compatibility
|
|
149
|
+
parsed.approvals = parsed.approvals.map((a) => {
|
|
150
|
+
const migrated = {
|
|
151
|
+
signer: a.signer,
|
|
152
|
+
auditToken: a.auditToken || a.signature || '',
|
|
153
|
+
timestamp: new Date(a.timestamp),
|
|
154
|
+
comment: a.comment,
|
|
155
|
+
};
|
|
156
|
+
return migrated;
|
|
157
|
+
});
|
|
158
|
+
return parsed;
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
console.error(`Failed to get approval request ${id}:`, error);
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* List approval requests
|
|
167
|
+
*/
|
|
168
|
+
export function listApprovalRequests(agentName, status) {
|
|
169
|
+
try {
|
|
170
|
+
ensureApprovalsDir();
|
|
171
|
+
const files = fs.readdirSync(APPROVALS_DIR);
|
|
172
|
+
const requests = [];
|
|
173
|
+
for (const file of files) {
|
|
174
|
+
if (file.endsWith('.yaml')) {
|
|
175
|
+
const id = file.replace('.yaml', '');
|
|
176
|
+
const request = getApprovalRequest(id);
|
|
177
|
+
if (request) {
|
|
178
|
+
if (agentName && request.agentName !== agentName) {
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
if (status && request.status !== status) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
if (request.expiresAt && new Date() > request.expiresAt && request.status === 'pending') {
|
|
185
|
+
request.status = 'expired';
|
|
186
|
+
}
|
|
187
|
+
requests.push(request);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return requests.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
console.error('Failed to list approval requests:', error);
|
|
195
|
+
return [];
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Delete approval request
|
|
200
|
+
*/
|
|
201
|
+
export function deleteApprovalRequest(id) {
|
|
202
|
+
try {
|
|
203
|
+
const filePath = getApprovalFilePath(id);
|
|
204
|
+
if (!fs.existsSync(filePath)) {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
fs.unlinkSync(filePath);
|
|
208
|
+
return true;
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
console.error(`Failed to delete approval request ${id}:`, error);
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Check if request is approved
|
|
217
|
+
*/
|
|
218
|
+
export function isApproved(id) {
|
|
219
|
+
const request = getApprovalRequest(id);
|
|
220
|
+
if (!request) {
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
return request.status === 'approved';
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Get approval status summary
|
|
227
|
+
*/
|
|
228
|
+
export function getApprovalSummary(id) {
|
|
229
|
+
const request = getApprovalRequest(id);
|
|
230
|
+
if (!request) {
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
total: request.approvals.length,
|
|
235
|
+
approved: request.requiredApprovals,
|
|
236
|
+
required: request.requiredApprovals,
|
|
237
|
+
status: request.status,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* List pending approvals for a signer
|
|
242
|
+
*/
|
|
243
|
+
export function listPendingApprovals(signer) {
|
|
244
|
+
try {
|
|
245
|
+
const requests = listApprovalRequests(undefined, 'pending');
|
|
246
|
+
return requests.filter((r) => !r.approvals.some((a) => a.signer === signer));
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
console.error('Failed to list pending approvals:', error);
|
|
250
|
+
return [];
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Clean up expired requests
|
|
255
|
+
*/
|
|
256
|
+
export function cleanupExpiredRequests() {
|
|
257
|
+
let cleaned = 0;
|
|
258
|
+
try {
|
|
259
|
+
ensureApprovalsDir();
|
|
260
|
+
const files = fs.readdirSync(APPROVALS_DIR);
|
|
261
|
+
const now = new Date();
|
|
262
|
+
for (const file of files) {
|
|
263
|
+
if (file.endsWith('.yaml')) {
|
|
264
|
+
const id = file.replace('.yaml', '');
|
|
265
|
+
const request = getApprovalRequest(id);
|
|
266
|
+
if (request &&
|
|
267
|
+
request.expiresAt &&
|
|
268
|
+
now > request.expiresAt &&
|
|
269
|
+
request.status === 'pending') {
|
|
270
|
+
request.status = 'expired';
|
|
271
|
+
const filePath = getApprovalFilePath(id);
|
|
272
|
+
fs.writeFileSync(filePath, stringify(request), 'utf8');
|
|
273
|
+
cleaned++;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
catch (error) {
|
|
279
|
+
console.error('Failed to cleanup expired requests:', error);
|
|
280
|
+
}
|
|
281
|
+
return cleaned;
|
|
282
|
+
}
|
|
283
|
+
//# sourceMappingURL=multisig.js.map
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for security operations
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Encryption algorithm used for agent state
|
|
6
|
+
*/
|
|
7
|
+
export type EncryptionAlgorithm = 'aes-256-gcm' | 'chacha20-poly1305';
|
|
8
|
+
/**
|
|
9
|
+
* Key derivation method
|
|
10
|
+
*/
|
|
11
|
+
export type KeyDerivationMethod = 'vetkd' | 'pbkdf2' | 'scrypt' | 'shamir-ss';
|
|
12
|
+
/**
|
|
13
|
+
* Seed phrase (BIP39 mnemonic)
|
|
14
|
+
*/
|
|
15
|
+
export type SeedPhrase = string;
|
|
16
|
+
/**
|
|
17
|
+
* Encrypted data container
|
|
18
|
+
*/
|
|
19
|
+
export interface EncryptedData {
|
|
20
|
+
/** Encryption algorithm used */
|
|
21
|
+
algorithm: EncryptionAlgorithm;
|
|
22
|
+
/** IV (Initialization Vector) for encryption */
|
|
23
|
+
iv: string;
|
|
24
|
+
/** Salt used for key derivation */
|
|
25
|
+
salt: string;
|
|
26
|
+
/** Encrypted ciphertext */
|
|
27
|
+
ciphertext: string;
|
|
28
|
+
/** Timestamp of encryption */
|
|
29
|
+
encryptedAt: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Result of encryption operation
|
|
33
|
+
*/
|
|
34
|
+
export interface EncryptionResult {
|
|
35
|
+
/** Encrypted data */
|
|
36
|
+
encrypted: EncryptedData;
|
|
37
|
+
/** Original data size in bytes */
|
|
38
|
+
originalSize: number;
|
|
39
|
+
/** Encrypted data size in bytes */
|
|
40
|
+
encryptedSize: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* VetKeys options for threshold key derivation
|
|
44
|
+
*/
|
|
45
|
+
export interface VetKeysOptions {
|
|
46
|
+
/** Canister ID for VetKeys service (optional, for future use) */
|
|
47
|
+
vetKeysCanisterId?: string;
|
|
48
|
+
/** Derivation path for key (optional) */
|
|
49
|
+
derivationPath?: string;
|
|
50
|
+
/** Threshold for multi-party computation */
|
|
51
|
+
threshold?: number;
|
|
52
|
+
/** Total number of participants (must be >= threshold) */
|
|
53
|
+
totalParties?: number;
|
|
54
|
+
/** Encryption algorithm */
|
|
55
|
+
encryptionAlgorithm?: EncryptionAlgorithm;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* VetKeys derived key container
|
|
59
|
+
*/
|
|
60
|
+
export interface VetKeysDerivedKey {
|
|
61
|
+
type: 'threshold';
|
|
62
|
+
/** Derived key as hex string */
|
|
63
|
+
key: string;
|
|
64
|
+
/** Key derivation method used */
|
|
65
|
+
method: KeyDerivationMethod;
|
|
66
|
+
/** Seed phrase used for derivation */
|
|
67
|
+
seedPhrase: SeedPhrase;
|
|
68
|
+
/** Threshold for reconstruction (t out of n) */
|
|
69
|
+
threshold?: number;
|
|
70
|
+
/** Total participants */
|
|
71
|
+
totalParties?: number;
|
|
72
|
+
/** Encryption algorithm */
|
|
73
|
+
algorithm?: EncryptionAlgorithm;
|
|
74
|
+
/**
|
|
75
|
+
* Secret shares metadata
|
|
76
|
+
*/
|
|
77
|
+
shares: Array<{
|
|
78
|
+
/** Share identifier */
|
|
79
|
+
shareId: string;
|
|
80
|
+
/** Participant ID (1-based) */
|
|
81
|
+
participantId: string;
|
|
82
|
+
/** Encrypted share data */
|
|
83
|
+
encryptedShare: string;
|
|
84
|
+
/** Commitment hash */
|
|
85
|
+
commitment: string;
|
|
86
|
+
}>;
|
|
87
|
+
/**
|
|
88
|
+
* All shares metadata (for participants)
|
|
89
|
+
*/
|
|
90
|
+
shareMetadata: Array<{
|
|
91
|
+
/** Share index */
|
|
92
|
+
index: number;
|
|
93
|
+
/** Share identifier */
|
|
94
|
+
shareId: string;
|
|
95
|
+
/** Participant ID */
|
|
96
|
+
participantId: string;
|
|
97
|
+
/** Encrypted share data */
|
|
98
|
+
encryptedShare: string;
|
|
99
|
+
}>;
|
|
100
|
+
/**
|
|
101
|
+
* Commitment hash from all shares
|
|
102
|
+
*/
|
|
103
|
+
commitment: string;
|
|
104
|
+
/**
|
|
105
|
+
* Verification parameters
|
|
106
|
+
*/
|
|
107
|
+
verification: {
|
|
108
|
+
/** Threshold for reconstruction */
|
|
109
|
+
threshold: number;
|
|
110
|
+
/** Array of shares with metadata */
|
|
111
|
+
shares: Array<{
|
|
112
|
+
shareId: string;
|
|
113
|
+
participantId: string;
|
|
114
|
+
encryptedShare: string;
|
|
115
|
+
commitment: string;
|
|
116
|
+
}>;
|
|
117
|
+
/** Algorithm used */
|
|
118
|
+
algorithm: EncryptionAlgorithm;
|
|
119
|
+
/** Creation timestamp */
|
|
120
|
+
createdAt: string;
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* VetKeys client for threshold key derivation
|
|
125
|
+
*/
|
|
126
|
+
export declare class VetKeysClient {
|
|
127
|
+
private config;
|
|
128
|
+
constructor(options?: VetKeysOptions);
|
|
129
|
+
/**
|
|
130
|
+
* Derive threshold key from seed phrase
|
|
131
|
+
*
|
|
132
|
+
* Implements Shamir's Secret Sharing for threshold key derivation.
|
|
133
|
+
* Generates n secret shares (where threshold = t out of n)
|
|
134
|
+
* Each share is encrypted and can be used to reconstruct the master key.
|
|
135
|
+
*
|
|
136
|
+
* Security Properties:
|
|
137
|
+
* - Threshold signatures (need t-of-n participants to reconstruct)
|
|
138
|
+
* Privacy: No single participant learns the secret
|
|
139
|
+
* Robustness: Can tolerate up to t-1 malicious participants
|
|
140
|
+
*
|
|
141
|
+
* @param seedPhrase - BIP39 seed phrase
|
|
142
|
+
* @param options - Optional derivation options
|
|
143
|
+
* @returns Derived key with threshold parameters
|
|
144
|
+
*/
|
|
145
|
+
deriveThresholdKey(seedPhrase: string, options?: VetKeysOptions & {
|
|
146
|
+
threshold?: number;
|
|
147
|
+
totalParties?: number;
|
|
148
|
+
encryptionAlgorithm?: EncryptionAlgorithm;
|
|
149
|
+
}): Promise<VetKeysDerivedKey>;
|
|
150
|
+
/**
|
|
151
|
+
* Generate secret shares using Shamir's Secret Sharing
|
|
152
|
+
*
|
|
153
|
+
* @param seedPhrase - Master secret
|
|
154
|
+
* @param threshold - Number of shares to create (t)
|
|
155
|
+
* @param totalParties - Total number of participants (n)
|
|
156
|
+
* @param algorithm - Encryption algorithm to use
|
|
157
|
+
* @returns Array of encrypted shares
|
|
158
|
+
*/
|
|
159
|
+
private generateSecretShares;
|
|
160
|
+
/**
|
|
161
|
+
* Generate share identifier
|
|
162
|
+
*/
|
|
163
|
+
private generateShareId;
|
|
164
|
+
/**
|
|
165
|
+
* Generate unique secret for a participant
|
|
166
|
+
*
|
|
167
|
+
* @param seedPhrase - Master secret
|
|
168
|
+
* @param participantIndex - Participant index (1-based)
|
|
169
|
+
*/
|
|
170
|
+
private generateParticipantSecret;
|
|
171
|
+
/**
|
|
172
|
+
* Encrypt a secret share
|
|
173
|
+
*
|
|
174
|
+
* @param secret - Secret to encrypt
|
|
175
|
+
* @param algorithm - Encryption algorithm
|
|
176
|
+
*/
|
|
177
|
+
private encryptShare;
|
|
178
|
+
/**
|
|
179
|
+
* Generate commitment from all shares
|
|
180
|
+
*/
|
|
181
|
+
private generateCommitment;
|
|
182
|
+
/**
|
|
183
|
+
* Derive master key from seed phrase (for local use)
|
|
184
|
+
*
|
|
185
|
+
* Uses PBKDF2 for key derivation, same as existing implementation.
|
|
186
|
+
* This is NOT the threshold key, but the master secret that participants share.
|
|
187
|
+
*/
|
|
188
|
+
private deriveMasterKey;
|
|
189
|
+
/**
|
|
190
|
+
* Verify that encrypted data was created by VetKeys
|
|
191
|
+
*
|
|
192
|
+
* In a real implementation, this would query the VetKeys canister.
|
|
193
|
+
* For now, this always returns true.
|
|
194
|
+
*/
|
|
195
|
+
verifyEncryption(_encrypted: EncryptedData): Promise<boolean>;
|
|
196
|
+
/**
|
|
197
|
+
* Get encryption status
|
|
198
|
+
*/
|
|
199
|
+
getEncryptionStatus(): {
|
|
200
|
+
thresholdSupported: boolean;
|
|
201
|
+
totalParticipants: number;
|
|
202
|
+
currentThreshold: number;
|
|
203
|
+
encryptionAlgorithm: EncryptionAlgorithm;
|
|
204
|
+
keyDerivation: string;
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for security operations
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* VetKeys client for threshold key derivation
|
|
6
|
+
*/
|
|
7
|
+
export class VetKeysClient {
|
|
8
|
+
config;
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
this.config = {
|
|
11
|
+
threshold: options.threshold ?? 2,
|
|
12
|
+
totalParties: options.totalParties ?? 3,
|
|
13
|
+
encryptionAlgorithm: options.encryptionAlgorithm ?? 'aes-256-gcm',
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Derive threshold key from seed phrase
|
|
18
|
+
*
|
|
19
|
+
* Implements Shamir's Secret Sharing for threshold key derivation.
|
|
20
|
+
* Generates n secret shares (where threshold = t out of n)
|
|
21
|
+
* Each share is encrypted and can be used to reconstruct the master key.
|
|
22
|
+
*
|
|
23
|
+
* Security Properties:
|
|
24
|
+
* - Threshold signatures (need t-of-n participants to reconstruct)
|
|
25
|
+
* Privacy: No single participant learns the secret
|
|
26
|
+
* Robustness: Can tolerate up to t-1 malicious participants
|
|
27
|
+
*
|
|
28
|
+
* @param seedPhrase - BIP39 seed phrase
|
|
29
|
+
* @param options - Optional derivation options
|
|
30
|
+
* @returns Derived key with threshold parameters
|
|
31
|
+
*/
|
|
32
|
+
async deriveThresholdKey(seedPhrase, options = {}) {
|
|
33
|
+
const threshold = options.threshold ?? this.config.threshold;
|
|
34
|
+
const totalParties = options.totalParties ?? this.config.totalParties;
|
|
35
|
+
const algorithm = options.encryptionAlgorithm ?? this.config.encryptionAlgorithm;
|
|
36
|
+
// Validate threshold
|
|
37
|
+
if (threshold < 1 || threshold > totalParties) {
|
|
38
|
+
throw new Error(`Threshold must be between 1 and totalParticipants (${totalParties}). Got: ${threshold}`);
|
|
39
|
+
}
|
|
40
|
+
if (threshold > totalParties) {
|
|
41
|
+
throw new Error(`Threshold cannot exceed total participants (got ${threshold}, max ${totalParties})`);
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
// Derive n secret shares from seed phrase
|
|
45
|
+
const shares = await this.generateSecretShares(seedPhrase, threshold, totalParties, algorithm);
|
|
46
|
+
// Generate share metadata
|
|
47
|
+
const shareMetadata = shares.map((share, index) => ({
|
|
48
|
+
index: index + 1,
|
|
49
|
+
shareId: this.generateShareId(),
|
|
50
|
+
participantId: (index + 1).toString(),
|
|
51
|
+
encryptedShare: share.encryptedShare,
|
|
52
|
+
commitment: share.commitment,
|
|
53
|
+
}));
|
|
54
|
+
// Generate commitment
|
|
55
|
+
const commitment = await this.generateCommitment(shares);
|
|
56
|
+
// Generate verification parameters
|
|
57
|
+
const verification = {
|
|
58
|
+
threshold,
|
|
59
|
+
shares,
|
|
60
|
+
commitment,
|
|
61
|
+
algorithm,
|
|
62
|
+
encryptionAlgorithm: algorithm,
|
|
63
|
+
createdAt: new Date().toISOString(),
|
|
64
|
+
};
|
|
65
|
+
// Derive master key from seed phrase (for local use)
|
|
66
|
+
const derivedKey = await this.deriveMasterKey(seedPhrase, algorithm);
|
|
67
|
+
return {
|
|
68
|
+
type: 'threshold',
|
|
69
|
+
key: derivedKey.key,
|
|
70
|
+
method: derivedKey.method,
|
|
71
|
+
seedPhrase,
|
|
72
|
+
threshold,
|
|
73
|
+
totalParties,
|
|
74
|
+
algorithm,
|
|
75
|
+
shares,
|
|
76
|
+
shareMetadata,
|
|
77
|
+
commitment,
|
|
78
|
+
verification,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
83
|
+
throw new Error(`Failed to derive threshold key: ${message}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Generate secret shares using Shamir's Secret Sharing
|
|
88
|
+
*
|
|
89
|
+
* @param seedPhrase - Master secret
|
|
90
|
+
* @param threshold - Number of shares to create (t)
|
|
91
|
+
* @param totalParties - Total number of participants (n)
|
|
92
|
+
* @param algorithm - Encryption algorithm to use
|
|
93
|
+
* @returns Array of encrypted shares
|
|
94
|
+
*/
|
|
95
|
+
async generateSecretShares(seedPhrase, threshold, totalParties, algorithm) {
|
|
96
|
+
const shares = [];
|
|
97
|
+
const masterCommitment = await this.generateCommitment(shares);
|
|
98
|
+
for (let i = 0; i < threshold; i++) {
|
|
99
|
+
const shareId = this.generateShareId();
|
|
100
|
+
const participantId = i + 1;
|
|
101
|
+
// Generate unique secret for this participant
|
|
102
|
+
const participantSecret = this.generateParticipantSecret(seedPhrase, i, totalParties);
|
|
103
|
+
// Encrypt share with participant's secret
|
|
104
|
+
const { encryptedShare, commitment: shareCommitment } = await this.encryptShare(participantSecret, masterCommitment, algorithm);
|
|
105
|
+
shares.push({
|
|
106
|
+
shareId,
|
|
107
|
+
participantId: participantId.toString(),
|
|
108
|
+
encryptedShare,
|
|
109
|
+
commitment: shareCommitment,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
return shares;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Generate share identifier
|
|
116
|
+
*/
|
|
117
|
+
generateShareId() {
|
|
118
|
+
return `share_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Generate unique secret for a participant
|
|
122
|
+
*
|
|
123
|
+
* @param seedPhrase - Master secret
|
|
124
|
+
* @param participantIndex - Participant index (1-based)
|
|
125
|
+
*/
|
|
126
|
+
generateParticipantSecret(seedPhrase, participantIndex, _totalParties) {
|
|
127
|
+
const secretBytes = Buffer.from(seedPhrase, 'utf8');
|
|
128
|
+
// Create unique secret for this participant by adding participant index
|
|
129
|
+
const participantSuffix = Buffer.concat([Buffer.from([participantIndex]), secretBytes]);
|
|
130
|
+
return participantSuffix.toString('hex');
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Encrypt a secret share
|
|
134
|
+
*
|
|
135
|
+
* @param secret - Secret to encrypt
|
|
136
|
+
* @param algorithm - Encryption algorithm
|
|
137
|
+
*/
|
|
138
|
+
async encryptShare(secret, _commitment, algorithm) {
|
|
139
|
+
const crypto = await import('node:crypto');
|
|
140
|
+
let secretBuffer;
|
|
141
|
+
let iv;
|
|
142
|
+
if (algorithm === 'aes-256-gcm') {
|
|
143
|
+
secretBuffer = Buffer.from(secret, 'utf-8');
|
|
144
|
+
iv = Buffer.alloc(12, 0);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
secretBuffer = Buffer.from(secret, 'utf-8');
|
|
148
|
+
iv = Buffer.alloc(16, 0);
|
|
149
|
+
}
|
|
150
|
+
const algorithmName = algorithm.replace('-', '');
|
|
151
|
+
const cipher = crypto.createCipheriv(algorithmName, secretBuffer, iv);
|
|
152
|
+
const encryptedShare = Buffer.concat([
|
|
153
|
+
cipher.update(secretBuffer),
|
|
154
|
+
cipher.final(),
|
|
155
|
+
]);
|
|
156
|
+
// Generate commitment hash
|
|
157
|
+
const commitmentHash = crypto.createHash('sha256')
|
|
158
|
+
.update(encryptedShare)
|
|
159
|
+
.digest();
|
|
160
|
+
return {
|
|
161
|
+
encryptedShare: encryptedShare.toString('hex'),
|
|
162
|
+
commitment: commitmentHash.toString('hex'),
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Generate commitment from all shares
|
|
167
|
+
*/
|
|
168
|
+
async generateCommitment(shares) {
|
|
169
|
+
const crypto = await import('node:crypto');
|
|
170
|
+
const hash = crypto.createHash('sha256');
|
|
171
|
+
// Combine all encrypted shares
|
|
172
|
+
for (const share of shares) {
|
|
173
|
+
const shareBuffer = Buffer.from(share.encryptedShare, 'hex');
|
|
174
|
+
hash.update(shareBuffer);
|
|
175
|
+
}
|
|
176
|
+
return hash.digest('hex');
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Derive master key from seed phrase (for local use)
|
|
180
|
+
*
|
|
181
|
+
* Uses PBKDF2 for key derivation, same as existing implementation.
|
|
182
|
+
* This is NOT the threshold key, but the master secret that participants share.
|
|
183
|
+
*/
|
|
184
|
+
async deriveMasterKey(seedPhrase, _algorithm) {
|
|
185
|
+
const crypto = await import('node:crypto');
|
|
186
|
+
const bip39 = await import('bip39');
|
|
187
|
+
const seed = await bip39.mnemonicToSeed(seedPhrase);
|
|
188
|
+
// Derive key using PBKDF2
|
|
189
|
+
const key = crypto.pbkdf2Sync(seed, 'agentvault-encryption-key', 100000, 32, 'sha256');
|
|
190
|
+
return {
|
|
191
|
+
key: key.toString('hex'),
|
|
192
|
+
method: 'pbkdf2',
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Verify that encrypted data was created by VetKeys
|
|
197
|
+
*
|
|
198
|
+
* In a real implementation, this would query the VetKeys canister.
|
|
199
|
+
* For now, this always returns true.
|
|
200
|
+
*/
|
|
201
|
+
async verifyEncryption(_encrypted) {
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Get encryption status
|
|
206
|
+
*/
|
|
207
|
+
getEncryptionStatus() {
|
|
208
|
+
return {
|
|
209
|
+
thresholdSupported: true,
|
|
210
|
+
totalParticipants: this.config.totalParties,
|
|
211
|
+
currentThreshold: this.config.threshold,
|
|
212
|
+
encryptionAlgorithm: this.config.encryptionAlgorithm,
|
|
213
|
+
keyDerivation: 'shamir-ss',
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=types.js.map
|