/** * @file vault.ts * @description AgentVault — wallet-key encrypted credential storage. * * Lets an AI agent encrypt its own credentials (API keys, private keys, secrets) * using its EVM wallet private key. Encrypted blobs are stored on Arweave. * Only the wallet owner can decrypt. * * Multi-wallet access: use `grantAccess(granteePublicKey, blob)` to re-encrypt * a sealed blob for a second wallet. Store the re-encrypted blob on Arweave and * record the reference in an `AccessManifest` (uploaded via `projectAccessManifest` * on InkdRegistryV2). * * Encryption: ECIES (ECDH secp256k1 + HKDF-SHA256 + AES-256-GCM) * * Binary layout: * [33 bytes] ephemeral compressed public key * [12 bytes] AES-GCM IV (nonce) * [16 bytes] AES-GCM auth tag * [N bytes] ciphertext * * @example * ```ts * const vault = new AgentVault(process.env.PRIVATE_KEY as `0x${string}`) * * // Seal credentials * const encrypted = await vault.seal({ openaiKey: "sk-...", arweaveKey: { kty: "RSA", ... } }) * * // Unseal credentials * const creds = await vault.unseal(encrypted) * * // Grant access to another wallet * const granteePublicKey = AgentVault.getPublicKey('0x...') * const granteeBlob = await vault.grantAccess(granteePublicKey, encrypted) * * // Store on Arweave + retrieve * const hash = await vault.store(creds, arweaveClient) // → "ar://Qm..." * const loaded = await vault.load(hash, arweaveClient) * ``` */ export interface AccessManifestEntry { /** Wallet address of the grantee (checksummed or lowercase). */ walletAddress: string; /** Arweave URI (ar://...) of the re-encrypted blob for this grantee. */ encryptedBlobRef: string; /** ISO timestamp of when access was granted. */ grantedAt: string; /** Wallet address of the owner who granted access. */ grantedBy: string; } export interface AccessManifest { $schema: "https://inkdprotocol.com/schemas/access-manifest/v1.json"; projectId: number; entries: AccessManifestEntry[]; updatedAt: string; } import type { ArweaveClient } from "./arweave.js"; /** * Wallet-key encrypted credential vault for AI agents. * Uses ECIES so only the private key holder can decrypt. */ export declare class AgentVault { private privateKeyBytes; private publicKeyBytes; constructor(privateKey: `0x${string}`); /** * Encrypt credentials with this wallet's public key. * Returns a binary blob ready for Arweave upload. */ seal(credentials: Record): Promise; /** * Decrypt a sealed blob using this wallet's private key. */ unseal(encrypted: Uint8Array): Promise>; /** * Derive the compressed secp256k1 public key from a private key. * Returns a hex string (66 chars, no 0x prefix) suitable for `grantAccess`. */ static getPublicKey(privateKey: `0x${string}`): string; /** * Encrypt credentials for a specific public key (no private key needed). * The recipient can decrypt with their corresponding `AgentVault.unseal()`. * * @param credentials - The credentials to encrypt. * @param recipientPublicKeyHex - Compressed secp256k1 public key (33 bytes, 66 hex chars). */ static sealForPublicKey(credentials: Record, recipientPublicKeyHex: string): Promise; /** * Re-encrypt a sealed blob for a different wallet. * Decrypts with the caller's private key, then re-encrypts for the grantee. * * @param granteePublicKeyHex - Grantee's compressed public key (use `AgentVault.getPublicKey`). * @param blob - The sealed blob to re-encrypt. * @returns A new sealed blob that only the grantee can decrypt. * * @example * ```ts * const granteeKey = AgentVault.getPublicKey('0x...') * const granteeBlob = await ownerVault.grantAccess(granteeKey, ownerBlob) * const ref = await arweave.uploadFile(granteeBlob, ...) * ``` */ grantAccess(granteePublicKeyHex: string, blob: Uint8Array): Promise; /** * Build an AccessManifest object for upload to Arweave. * Upload this JSON to Arweave and store the txid in `InkdRegistryV2.setAccessManifest`. * * @param projectId - On-chain project ID. * @param entries - Array of grantee entries (wallet address + arweave ref). * @param ownerAddress - Wallet address of the owner (for `grantedBy` default). */ static buildAccessManifest(projectId: number, entries: Omit[], ownerAddress?: string): AccessManifest; /** * Seal credentials and upload to Arweave. * Returns the Arweave hash (ar://...). */ store(credentials: Record, arweave: ArweaveClient): Promise; /** * Fetch from Arweave and unseal. * Accepts an ar:// hash or raw Arweave transaction ID. */ load(arweaveHash: string, arweave: ArweaveClient): Promise>; } //# sourceMappingURL=vault.d.ts.map