bedrock-ts-sdk 0.0.5 → 0.0.6

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client/bedrock-core.ts","../src/types/errors.ts","../src/types/schemas.ts","../src/client/aleph-service.ts","../src/services/file-service.ts","../src/crypto/encryption.ts","../src/services/contact-service.ts","../src/services/knowledge-base-service.ts","../src/services/credit-service.ts","../src/bedrock-client.ts","../src/index.ts"],"sourcesContent":["import { AuthenticatedAlephHttpClient } from '@aleph-sdk/client';\nimport { ETHAccount, getAccountFromProvider, importAccountFromPrivateKey } from '@aleph-sdk/ethereum';\nimport { PrivateKey } from 'eciesjs';\nimport web3 from 'web3';\nimport { AuthenticationError } from '../types/errors';\nimport { ALEPH_GENERAL_CHANNEL, BEDROCK_MESSAGE, SECURITY_AGGREGATE_KEY } from '../types/schemas';\nimport { AlephService } from './aleph-service';\n\n/**\n * Configuration for BedrockCore\n */\nexport interface BedrockCoreConfig {\n channel?: string;\n apiServer?: string;\n}\n\n/**\n * Core Bedrock functionality: authentication, sub-accounts, encryption key derivation\n */\nexport class BedrockCore {\n private readonly mainAccount: ETHAccount;\n private readonly subAccount: ETHAccount;\n private readonly alephService: AlephService;\n private readonly encryptionPrivateKey: PrivateKey;\n\n private constructor(\n mainAccount: ETHAccount,\n subAccount: ETHAccount,\n alephService: AlephService,\n encryptionPrivateKey: PrivateKey,\n _config: Required<BedrockCoreConfig>\n ) {\n this.mainAccount = mainAccount;\n this.subAccount = subAccount;\n this.alephService = alephService;\n this.encryptionPrivateKey = encryptionPrivateKey;\n }\n\n /**\n * Initialize from signature hash (matches Bedrock app pattern)\n * @param signatureHash - Signature hash from wallet\n * @param provider - EIP-1193 provider (for MetaMask/Rabby)\n * @param config - Optional configuration\n */\n static async fromSignature(signatureHash: string, provider: any, config?: BedrockCoreConfig): Promise<BedrockCore> {\n try {\n const cfg = {\n channel: config?.channel || ALEPH_GENERAL_CHANNEL,\n apiServer: config?.apiServer || 'https://api2.aleph.im',\n };\n\n // Derive private key from signature\n const privateKey = web3.utils.sha3(signatureHash);\n if (!privateKey) {\n throw new AuthenticationError('Failed to derive private key from signature');\n }\n\n // Create encryption private key\n const encryptionPrivateKey = PrivateKey.fromHex(privateKey);\n\n // Get main account from provider\n // Handle different wallet types like the old service did\n let mainAccount: ETHAccount;\n\n if (provider?.id && ['io.rabby', 'io.metamask'].includes(provider.id)) {\n // For Rabby and MetaMask, use window.ethereum directly\n if (typeof window !== 'undefined' && (window as any).ethereum) {\n mainAccount = await getAccountFromProvider((window as any).ethereum);\n } else {\n throw new AuthenticationError('window.ethereum not available');\n }\n } else {\n // For other wallets or standard EIP-1193 providers\n mainAccount = await getAccountFromProvider(provider);\n }\n\n // Create sub-account\n const subAccount = importAccountFromPrivateKey(privateKey);\n\n // Setup security permissions\n await BedrockCore.setupSecurityPermissions(mainAccount, subAccount, cfg);\n\n // Create AlephService\n const alephService = new AlephService(subAccount, cfg.channel, cfg.apiServer);\n\n return new BedrockCore(mainAccount, subAccount, alephService, encryptionPrivateKey, cfg);\n } catch (error) {\n throw new AuthenticationError(`Failed to initialize from signature: ${(error as Error).message}`);\n }\n }\n\n /**\n * Create BedrockCore from a private key (for testing/CLI)\n * @param privateKey - Ethereum private key (hex string with or without 0x prefix)\n * @param config - Optional configuration\n */\n static async fromPrivateKey(privateKey: string, config?: BedrockCoreConfig): Promise<BedrockCore> {\n try {\n const cfg = {\n channel: config?.channel || ALEPH_GENERAL_CHANNEL,\n apiServer: config?.apiServer || 'https://api2.aleph.im',\n };\n\n // Ensure 0x prefix\n const key = privateKey.startsWith('0x') ? privateKey : `0x${privateKey}`;\n\n // Create main account\n const mainAccount = importAccountFromPrivateKey(key);\n\n // For private key, we simulate signing by hashing the key + message\n const signatureHash = web3.utils.sha3(key + BEDROCK_MESSAGE);\n if (!signatureHash) {\n throw new AuthenticationError('Failed to derive signature');\n }\n\n const subPrivateKey = web3.utils.sha3(signatureHash);\n if (!subPrivateKey) {\n throw new AuthenticationError('Failed to derive sub-account key');\n }\n\n // Create encryption private key\n const encryptionPrivateKey = PrivateKey.fromHex(subPrivateKey);\n\n // Create sub-account\n const subAccount = importAccountFromPrivateKey(subPrivateKey);\n\n // Setup security permissions\n await BedrockCore.setupSecurityPermissions(mainAccount, subAccount, cfg);\n\n // Create AlephService\n const alephService = new AlephService(subAccount, cfg.channel, cfg.apiServer);\n\n return new BedrockCore(mainAccount, subAccount, alephService, encryptionPrivateKey, cfg);\n } catch (error) {\n throw new AuthenticationError(`Failed to import account: ${(error as Error).message}`);\n }\n }\n\n /**\n * Create BedrockCore from a wallet provider (e.g., MetaMask)\n * This will automatically request signature from the user\n * @param provider - EIP-1193 provider\n * @param config - Optional configuration\n */\n static async fromProvider(provider: any, config?: BedrockCoreConfig): Promise<BedrockCore> {\n try {\n // Request signature from user\n const accounts = await provider.request({ method: 'eth_requestAccounts' });\n if (!accounts || accounts.length === 0) {\n throw new AuthenticationError('No accounts found');\n }\n\n // Request signature\n const signature = await provider.request({\n method: 'personal_sign',\n params: [BEDROCK_MESSAGE, accounts[0]],\n });\n\n return await BedrockCore.fromSignature(signature, provider, config);\n } catch (error) {\n throw new AuthenticationError(`Failed to connect to provider: ${(error as Error).message}`);\n }\n }\n\n /**\n * Get the main account\n */\n getMainAccount(): ETHAccount {\n return this.mainAccount;\n }\n\n /**\n * Get the sub-account\n */\n getSubAccount(): ETHAccount {\n return this.subAccount;\n }\n\n /**\n * Get the AlephService instance\n */\n getAlephService(): AlephService {\n return this.alephService;\n }\n\n /**\n * Get the encryption key\n */\n getEncryptionKey(): Buffer {\n return Buffer.from(this.encryptionPrivateKey.secret);\n }\n\n /**\n * Get the encryption private key\n */\n getEncryptionPrivateKey(): PrivateKey {\n return this.encryptionPrivateKey;\n }\n\n /**\n * Get the main account's address\n */\n getMainAddress(): string {\n return this.mainAccount.address;\n }\n\n /**\n * Get the sub-account's address\n */\n getSubAddress(): string {\n return this.subAccount.address;\n }\n\n /**\n * Get the main account's public key\n */\n getPublicKey(): string {\n // Use encryption private key's compressed public key (matches old service)\n // This is derived from the signature and is consistent\n return this.encryptionPrivateKey.publicKey.compressed.toString('hex');\n }\n\n /**\n * Get the sub-account's private key (as hex string)\n */\n getSubAccountPrivateKey(): string {\n return this.encryptionPrivateKey.toHex();\n }\n\n // ============================================================================\n // Static helper methods\n // ============================================================================\n\n /**\n * Setup security permissions (matches Bedrock app pattern)\n */\n private static async setupSecurityPermissions(\n mainAccount: ETHAccount,\n subAccount: ETHAccount,\n config: Required<BedrockCoreConfig>\n ): Promise<void> {\n try {\n const accountClient = new AuthenticatedAlephHttpClient(mainAccount, config.apiServer);\n\n try {\n // Fetch existing security aggregate\n const securitySettings = (await accountClient.fetchAggregate(\n mainAccount.address,\n SECURITY_AGGREGATE_KEY\n )) as any;\n\n // Check if sub-account is already authorized\n const authorizations = securitySettings?.authorizations || [];\n const isAuthorized = authorizations.find(\n (auth: any) =>\n auth.address === subAccount.address && auth.types === undefined && auth.channels?.includes(config.channel)\n );\n\n if (!isAuthorized) {\n // Remove old authorizations for this sub-account and add new one\n const oldAuthorizations = authorizations.filter((a: any) => a.address !== subAccount.address);\n\n await accountClient.createAggregate({\n key: SECURITY_AGGREGATE_KEY,\n content: {\n authorizations: [\n ...oldAuthorizations,\n {\n address: subAccount.address,\n channels: [config.channel],\n },\n ],\n },\n });\n }\n } catch (_error) {\n // Security aggregate does not exist, create a new one\n await accountClient.createAggregate({\n key: SECURITY_AGGREGATE_KEY,\n content: {\n authorizations: [\n {\n address: subAccount.address,\n channels: [config.channel],\n },\n ],\n },\n });\n }\n } catch (error) {\n throw new AuthenticationError(`Failed to setup security permissions: ${(error as Error).message}`);\n }\n }\n}\n","/**\n * Base error class for Bedrock SDK\n */\nexport class BedrockError extends Error {\n constructor(\n message: string,\n public code?: string\n ) {\n super(message);\n this.name = 'BedrockError';\n Object.setPrototypeOf(this, BedrockError.prototype);\n }\n}\n\n/**\n * Authentication/authorization errors\n */\nexport class AuthenticationError extends BedrockError {\n constructor(message: string) {\n super(message, 'AUTH_ERROR');\n this.name = 'AuthenticationError';\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Encryption/decryption errors\n */\nexport class EncryptionError extends BedrockError {\n constructor(message: string) {\n super(message, 'ENCRYPTION_ERROR');\n this.name = 'EncryptionError';\n Object.setPrototypeOf(this, EncryptionError.prototype);\n }\n}\n\n/**\n * File operation errors\n */\nexport class FileError extends BedrockError {\n constructor(message: string) {\n super(message, 'FILE_ERROR');\n this.name = 'FileError';\n Object.setPrototypeOf(this, FileError.prototype);\n }\n}\n\n/**\n * File not found error\n */\nexport class FileNotFoundError extends FileError {\n constructor(path: string) {\n super(`File not found: ${path}`);\n this.name = 'FileNotFoundError';\n this.code = 'FILE_NOT_FOUND';\n Object.setPrototypeOf(this, FileNotFoundError.prototype);\n }\n}\n\n/**\n * Contact-related errors\n */\nexport class ContactError extends BedrockError {\n constructor(message: string) {\n super(message, 'CONTACT_ERROR');\n this.name = 'ContactError';\n Object.setPrototypeOf(this, ContactError.prototype);\n }\n}\n\n/**\n * Knowledge base errors\n */\nexport class KnowledgeBaseError extends BedrockError {\n constructor(message: string) {\n super(message, 'KB_ERROR');\n this.name = 'KnowledgeBaseError';\n Object.setPrototypeOf(this, KnowledgeBaseError.prototype);\n }\n}\n\n/**\n * Credit-related errors\n */\nexport class CreditError extends BedrockError {\n constructor(message: string) {\n super(message, 'CREDIT_ERROR');\n this.name = 'CreditError';\n Object.setPrototypeOf(this, CreditError.prototype);\n }\n}\n\n/**\n * Network/Aleph API errors\n */\nexport class NetworkError extends BedrockError {\n constructor(message: string) {\n super(message, 'NETWORK_ERROR');\n this.name = 'NetworkError';\n Object.setPrototypeOf(this, NetworkError.prototype);\n }\n}\n\n/**\n * Validation errors\n */\nexport class ValidationError extends BedrockError {\n constructor(message: string) {\n super(message, 'VALIDATION_ERROR');\n this.name = 'ValidationError';\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n}\n","import { z } from 'zod';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nexport const BEDROCK_MESSAGE = 'Bedrock.im';\nexport const SECURITY_AGGREGATE_KEY = 'security';\nexport const ALEPH_GENERAL_CHANNEL = 'BEDROCK_STORAGE';\n\nexport const AGGREGATE_KEYS = {\n FILE_ENTRIES: 'bedrock_file_entries',\n CONTACTS: 'bedrock_contacts',\n KNOWLEDGE_BASES: 'bedrock_knowledge_bases',\n CREDITS: 'credits',\n} as const;\n\nexport const POST_TYPES = {\n FILE: 'bedrock_file',\n PUBLIC_FILE: 'bedrock_public_file',\n} as const;\n\n// ============================================================================\n// Base Schemas\n// ============================================================================\n\n/**\n * 64-character hex string (32 bytes)\n */\nexport const HexString64Schema = z\n .string()\n .length(64)\n .regex(/^[0-9a-f]{64}$/);\n\n/**\n * 32-character hex string (16 bytes)\n */\nexport const HexString32Schema = z\n .string()\n .length(32)\n .regex(/^[0-9a-f]{32}$/);\n\n/**\n * ISO 8601 datetime string\n */\nexport const DatetimeSchema = z.string().datetime();\n\n/**\n * Ethereum address\n */\nexport const AddressSchema = z.string().regex(/^0x[a-fA-F0-9]{40}$/);\n\n// ============================================================================\n// File Schemas\n// ============================================================================\n\n/**\n * File entry in the file index aggregate\n */\nexport const FileEntrySchema = z.object({\n path: z.string(), // Encrypted path\n post_hash: HexString64Schema,\n shared_with: z.array(z.string()).default([]), // Public keys of contacts\n});\n\nexport type FileEntry = z.infer<typeof FileEntrySchema>;\n\n/**\n * File metadata stored in POST messages\n */\nexport const FileMetaEncryptedSchema = z.object({\n name: z.string(), // Encrypted filename\n path: z.string(), // Encrypted path\n key: z.string(), // Encrypted AES key (ECIES encrypted)\n iv: z.string(), // Encrypted IV (ECIES encrypted)\n store_hash: z.string(), // Encrypted Aleph STORE hash\n size: z.string(), // Encrypted size\n created_at: z.string(), // Encrypted datetime\n deleted_at: z.string().nullable(), // Encrypted datetime or null\n shared_keys: z\n .record(\n z.string(),\n z.object({\n key: z.string(), // Encrypted key for recipient\n iv: z.string(), // Encrypted IV for recipient\n })\n )\n .default({}),\n});\n\nexport type FileMetaEncrypted = z.infer<typeof FileMetaEncryptedSchema>;\n\n/**\n * Decrypted file metadata\n */\nexport const FileMetaSchema = z.object({\n name: z.string(),\n path: z.string(),\n key: HexString64Schema,\n iv: HexString32Schema,\n store_hash: HexString64Schema,\n size: z.number(),\n created_at: DatetimeSchema,\n deleted_at: DatetimeSchema.nullable(),\n shared_keys: z\n .record(\n z.string(),\n z.object({\n key: HexString64Schema,\n iv: HexString32Schema,\n })\n )\n .default({}),\n});\n\nexport type FileMeta = z.infer<typeof FileMetaSchema>;\n\n/**\n * Combined file entry and metadata\n */\nexport type FileFullInfo = FileEntry & FileMeta;\n\n/**\n * Public file metadata (unencrypted, accessible by anyone)\n */\nexport const PublicFileMetaSchema = z.object({\n name: z.string(),\n size: z.number(),\n created_at: DatetimeSchema,\n store_hash: HexString64Schema,\n username: z.string(),\n});\n\nexport type PublicFileMeta = z.infer<typeof PublicFileMetaSchema>;\n\n// ============================================================================\n// Contact Schemas\n// ============================================================================\n\n/**\n * Contact information\n */\nexport const ContactSchema = z.object({\n name: z.string(),\n address: AddressSchema,\n public_key: z.string(), // Hex-encoded public key\n});\n\nexport type Contact = z.infer<typeof ContactSchema>;\n\n/**\n * Contacts aggregate\n */\nexport const ContactsAggregateSchema = z.object({\n contacts: z.array(ContactSchema).default([]),\n});\n\nexport type ContactsAggregate = z.infer<typeof ContactsAggregateSchema>;\n\n// ============================================================================\n// Knowledge Base Schemas\n// ============================================================================\n\n/**\n * Knowledge base configuration\n */\nexport const KnowledgeBaseSchema = z.object({\n name: z.string(),\n file_paths: z.array(z.string()).default([]), // Encrypted paths\n created_at: DatetimeSchema,\n updated_at: DatetimeSchema,\n});\n\nexport type KnowledgeBase = z.infer<typeof KnowledgeBaseSchema>;\n\n/**\n * Knowledge bases aggregate\n */\nexport const KnowledgeBasesAggregateSchema = z.object({\n knowledge_bases: z.array(KnowledgeBaseSchema).default([]),\n});\n\nexport type KnowledgeBasesAggregate = z.infer<typeof KnowledgeBasesAggregateSchema>;\n\n// ============================================================================\n// Credit Schemas\n// ============================================================================\n\n/**\n * Credit transaction record\n */\nexport const CreditTransactionSchema = z.object({\n id: z.string(),\n amount: z.number(),\n type: z.enum(['top_up', 'deduct']),\n timestamp: z.number(),\n description: z.string(),\n txHash: z.string().optional(),\n});\n\nexport type CreditTransaction = z.infer<typeof CreditTransactionSchema>;\n\n/**\n * User credit data\n */\nexport const UserCreditSchema = z.object({\n balance: z.number().default(0),\n transactions: z.array(CreditTransactionSchema).default([]),\n});\n\nexport type UserCredit = z.infer<typeof UserCreditSchema>;\n\n/**\n * Credit aggregate (backend-managed)\n */\nexport const CreditAggregateSchema = z.record(z.string(), UserCreditSchema);\n\nexport type CreditAggregate = z.infer<typeof CreditAggregateSchema>;\n\n// ============================================================================\n// File Entries Aggregate\n// ============================================================================\n\n/**\n * File entries aggregate\n */\nexport const FileEntriesAggregateSchema = z.object({\n files: z.array(FileEntrySchema).default([]),\n});\n\nexport type FileEntriesAggregate = z.infer<typeof FileEntriesAggregateSchema>;\n\n// ============================================================================\n// Security Aggregate\n// ============================================================================\n\n/**\n * Sub-account authorization in security aggregate\n */\nexport const SecurityAggregateSchema = z.object({\n authorizations: z.array(\n z.object({\n address: AddressSchema,\n chain: z.string(),\n channels: z.array(z.string()).optional(),\n post_types: z.array(z.string()).optional(),\n aggregate_keys: z.array(z.string()).optional(),\n })\n ),\n});\n\nexport type SecurityAggregate = z.infer<typeof SecurityAggregateSchema>;\n\n// ============================================================================\n// Aleph Message Types\n// ============================================================================\n\n/**\n * Aleph POST message content\n */\nexport interface AlephPostContent<T = unknown> {\n time: number;\n type: string;\n ref?: string;\n content: T;\n}\n\n/**\n * Aleph AGGREGATE content\n */\nexport interface AlephAggregateContent<T = unknown> {\n key: string;\n content: T;\n}\n\n/**\n * Aleph STORE message\n */\nexport interface AlephStoreMessage {\n item_hash: string;\n size: number;\n}\n\n/**\n * Generic Aleph message response\n */\nexport interface AlephMessage {\n chain: string;\n item_hash: string;\n sender: string;\n type: string;\n channel: string;\n confirmed: boolean;\n content: unknown;\n item_content: string;\n item_type: string;\n signature: string;\n size: number;\n time: number;\n}\n","import { AuthenticatedAlephHttpClient } from '@aleph-sdk/client';\nimport type { ETHAccount } from '@aleph-sdk/ethereum';\nimport { AggregateMessage, ForgetMessage, ItemType, PostMessage, StoreMessage } from '@aleph-sdk/message';\nimport { z } from 'zod';\nimport { NetworkError } from '../types/errors';\nimport { ALEPH_GENERAL_CHANNEL } from '../types/schemas';\n\n/**\n * Low-level Aleph SDK wrapper (matches Bedrock implementation)\n */\nexport class AlephService {\n private readonly subAccountClient: AuthenticatedAlephHttpClient;\n private readonly account: ETHAccount;\n private readonly channel: string;\n\n constructor(\n account: ETHAccount,\n channel: string = ALEPH_GENERAL_CHANNEL,\n apiServer: string = 'https://api2.aleph.im'\n ) {\n this.account = account;\n this.channel = channel;\n this.subAccountClient = new AuthenticatedAlephHttpClient(account, apiServer);\n }\n\n /**\n * Get the account address\n */\n getAddress(): string {\n return this.account.address;\n }\n\n /**\n * Get the account's public key\n */\n getPublicKey(): string {\n return this.account.publicKey || '';\n }\n\n /**\n * Get the underlying Aleph client\n */\n getClient(): AuthenticatedAlephHttpClient {\n return this.subAccountClient;\n }\n\n /**\n * Get the account\n */\n getAccount(): ETHAccount {\n return this.account;\n }\n\n // ============================================================================\n // STORE operations (file storage)\n // ============================================================================\n\n /**\n * Upload a file to Aleph storage\n * @param fileObject - File content as Buffer or File\n * @returns Store message\n */\n async uploadFile(fileObject: Buffer | File): Promise<StoreMessage> {\n try {\n return await this.subAccountClient.createStore({\n fileObject,\n storageEngine: ItemType.ipfs,\n channel: this.channel,\n });\n } catch (error) {\n throw new NetworkError(`Failed to upload file: ${(error as Error).message}`);\n }\n }\n\n /**\n * Download a file from Aleph storage\n * @param storeHash - The STORE message item_hash\n * @returns File content as ArrayBuffer\n */\n async downloadFile(storeHash: string): Promise<ArrayBuffer> {\n try {\n const ipfsHash = await this.subAccountClient.getMessage(storeHash);\n const ContentSchema = z.object({\n address: z.string(),\n item_type: z.string(),\n item_hash: z.string(),\n time: z.number(),\n });\n const { success, data } = ContentSchema.safeParse(ipfsHash.content);\n if (!success) throw new Error(`Invalid data from Aleph: ${data}`);\n return this.subAccountClient.downloadFile(data.item_hash);\n } catch (error) {\n throw new NetworkError(`Failed to download file ${storeHash}: ${(error as Error).message}`);\n }\n }\n\n /**\n * Delete files from Aleph storage\n * @param itemHashes - Array of item hashes to forget\n * @returns Forget message\n */\n async deleteFiles(itemHashes: string[]): Promise<ForgetMessage> {\n try {\n return this.subAccountClient.forget({ hashes: itemHashes });\n } catch (error) {\n throw new NetworkError(`Failed to delete files: ${(error as Error).message}`);\n }\n }\n\n // ============================================================================\n // AGGREGATE operations (key-value storage)\n // ============================================================================\n\n async createAggregate<T extends Record<string, unknown>>(key: string, content: T): Promise<AggregateMessage<T>> {\n try {\n return this.subAccountClient.createAggregate({\n key,\n content,\n channel: this.channel,\n address: this.account.address,\n });\n } catch (error) {\n throw new NetworkError(`Failed to create aggregate: ${(error as Error).message}`);\n }\n }\n\n async fetchAggregate<T extends z.ZodTypeAny>(key: string, schema: T, owner: string = this.account.address) {\n try {\n const unparsedData = await this.subAccountClient.fetchAggregate(owner, key);\n const { success, data, error } = schema.safeParse(unparsedData);\n if (!success)\n throw new Error(`Invalid data from Aleph: ${error.message}, data was ${JSON.stringify(unparsedData)}`);\n return data as z.infer<T>;\n } catch (error) {\n throw new NetworkError(`Failed to fetch aggregate: ${(error as Error).message}`);\n }\n }\n\n async updateAggregate<S extends z.ZodTypeAny, T extends z.infer<S>>(\n key: string,\n schema: S,\n update_content: (content: T) => Promise<T>\n ): Promise<AggregateMessage<T>> {\n try {\n const currentContent = await this.fetchAggregate(key, schema);\n const newContent = await update_content(currentContent);\n return await this.createAggregate(key, newContent);\n } catch (error) {\n throw new NetworkError(`Failed to update aggregate: ${(error as Error).message}`);\n }\n }\n\n // ============================================================================\n // POST operations (JSON messages)\n // ============================================================================\n\n async createPost<T extends Record<string, unknown>>(type: string, content: T): Promise<PostMessage<T>> {\n try {\n return this.subAccountClient.createPost({\n postType: type,\n content,\n channel: this.channel,\n address: this.account.address,\n });\n } catch (error) {\n throw new NetworkError(`Failed to create post: ${(error as Error).message}`);\n }\n }\n\n async fetchPosts<T extends z.ZodTypeAny>(\n type: string,\n schema: T,\n addresses: string[] = [this.account.address],\n hashes: string[] = []\n ) {\n try {\n return z.array(schema).parse(\n (\n await this.subAccountClient.getPosts({\n channels: [this.channel],\n types: [type],\n addresses,\n hashes,\n })\n ).posts.map((post) => post.content)\n ) as z.infer<T>[];\n } catch (error) {\n throw new NetworkError(`Failed to fetch posts: ${(error as Error).message}`);\n }\n }\n\n async fetchPost<T extends z.ZodTypeAny>(\n type: string,\n schema: T,\n addresses: string[] = [this.account.address],\n hash: string\n ) {\n try {\n return schema.parse(\n (\n await this.subAccountClient.getPost({\n channels: [this.channel],\n types: [type],\n addresses,\n hashes: [hash],\n })\n ).content\n ) as z.infer<T>;\n } catch (error) {\n throw new NetworkError(`Failed to fetch post: ${(error as Error).message}`);\n }\n }\n\n async updatePost<S extends z.ZodTypeAny, T extends z.infer<S>>(\n type: string,\n hash: string,\n addresses: string[],\n schema: S,\n update_content: (content: T) => Promise<T>\n ): Promise<PostMessage<T>> {\n try {\n const currentContent = await this.fetchPost(type, schema, addresses, hash);\n const newContent = await update_content(currentContent);\n return await this.subAccountClient.createPost({\n postType: type,\n content: newContent,\n ref: hash,\n channel: this.channel,\n address: this.account.address,\n });\n } catch (error) {\n throw new NetworkError(`Failed to update post: ${(error as Error).message}`);\n }\n }\n}\n","import { AlephHttpClient } from '@aleph-sdk/client';\nimport { BedrockCore } from '../client/bedrock-core';\nimport { EncryptionService } from '../crypto/encryption';\nimport { EncryptionError, FileError, FileNotFoundError } from '../types/errors';\nimport {\n AGGREGATE_KEYS,\n ALEPH_GENERAL_CHANNEL,\n FileEntriesAggregateSchema,\n FileEntry,\n FileFullInfo,\n FileMeta,\n FileMetaEncryptedSchema,\n POST_TYPES,\n PublicFileMeta,\n PublicFileMetaSchema,\n} from '../types/schemas';\n\n/**\n * File input type for uploads\n */\nexport interface FileInput {\n name: string;\n path: string;\n content: Buffer | File;\n}\n\n/**\n * File service for managing encrypted files\n */\nexport class FileService {\n private readonly core: BedrockCore;\n\n constructor(core: BedrockCore) {\n this.core = core;\n }\n\n /**\n * Initialize file entries aggregate if it doesn't exist\n */\n async setup(): Promise<void> {\n const aleph = this.core.getAlephService();\n\n try {\n await aleph.fetchAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema);\n } catch {\n // Create empty aggregate if it doesn't exist\n await aleph.createAggregate(AGGREGATE_KEYS.FILE_ENTRIES, { files: [] });\n }\n }\n\n /**\n * Upload files with encryption\n * @param files - Array of files to upload\n * @param directoryPath - Optional directory path prefix\n * @returns Array of uploaded file info\n */\n async uploadFiles(files: FileInput[], directoryPath: string = ''): Promise<FileFullInfo[]> {\n const aleph = this.core.getAlephService();\n const publicKey = this.core.getPublicKey();\n const uploadedFiles: FileFullInfo[] = [];\n\n try {\n for (const file of files) {\n // Generate encryption key and IV\n const key = EncryptionService.generateKey();\n const iv = EncryptionService.generateIv();\n\n // Encrypt file content\n let fileBuffer: Buffer;\n if (file.content instanceof Buffer) {\n fileBuffer = file.content;\n } else {\n // It's a File object\n const arrayBuffer = await (file.content as File).arrayBuffer();\n fileBuffer = Buffer.from(arrayBuffer);\n }\n const encryptedContent = await EncryptionService.encryptFile(fileBuffer, key, iv);\n\n // Upload encrypted file to Aleph STORE\n const storeResult = await aleph.uploadFile(encryptedContent);\n\n // Prepare file metadata\n const fullPath = directoryPath ? `${directoryPath}${file.path}` : file.path;\n const createdAt = new Date().toISOString();\n\n const fileMeta: FileMeta = {\n name: file.name,\n path: fullPath,\n key: key.toString('hex'),\n iv: iv.toString('hex'),\n store_hash: storeResult.item_hash,\n size: fileBuffer.length,\n created_at: createdAt,\n deleted_at: null,\n shared_keys: {},\n };\n\n // Encrypt metadata\n const encryptedMeta = await this.encryptFileMeta(fileMeta);\n\n // Create POST message with encrypted metadata\n const postResult = await aleph.createPost(POST_TYPES.FILE, encryptedMeta);\n\n // Create file entry\n const encryptedPath = EncryptionService.encryptEcies(fullPath, publicKey);\n const fileEntry: FileEntry = {\n path: encryptedPath,\n post_hash: postResult.item_hash,\n shared_with: [],\n };\n\n uploadedFiles.push({ ...fileEntry, ...fileMeta });\n }\n\n // Save file entries to aggregate\n await this.saveFileEntries(uploadedFiles);\n\n return uploadedFiles;\n } catch (error) {\n throw new FileError(`Failed to upload files: ${(error as Error).message}`);\n }\n }\n\n /**\n * Download and decrypt a file\n * @param fileInfo - File information\n * @returns Decrypted file buffer\n */\n async downloadFile(fileInfo: FileFullInfo): Promise<Buffer> {\n const aleph = this.core.getAlephService();\n\n try {\n const key = Buffer.from(fileInfo.key, 'hex');\n const iv = Buffer.from(fileInfo.iv, 'hex');\n\n // Download encrypted file\n const encryptedContent = await aleph.downloadFile(fileInfo.store_hash);\n\n // Decrypt file\n const decryptedContent = await EncryptionService.decryptFile(encryptedContent, key, iv);\n\n return decryptedContent;\n } catch (error) {\n throw new FileError(`Failed to download file: ${(error as Error).message}`);\n }\n }\n\n /**\n * Fetch all file entries\n */\n async fetchFileEntries(): Promise<FileEntry[]> {\n const aleph = this.core.getAlephService();\n const privateKey = this.core.getSubAccountPrivateKey();\n\n try {\n const aggregate = await aleph.fetchAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema);\n\n // Decrypt paths (they're stored encrypted)\n return aggregate.files.map(({ post_hash, path, shared_with }) => ({\n post_hash,\n path: EncryptionService.decryptEcies(path, privateKey),\n shared_with,\n }));\n } catch (error) {\n throw new FileError(`Failed to fetch file entries: ${(error as Error).message}`);\n }\n }\n\n /**\n * Fetch file metadata from entries\n * @param entries - File entries\n * @param owner - Optional owner address\n * @returns Array of full file info\n */\n async fetchFilesMetaFromEntries(entries: FileEntry[], owner?: string): Promise<FileFullInfo[]> {\n const aleph = this.core.getAlephService();\n const privateKey = owner ? undefined : this.core.getSubAccountPrivateKey();\n const files: FileFullInfo[] = [];\n\n try {\n for (const entry of entries) {\n try {\n // Fetch encrypted metadata from POST\n const encryptedMeta = await aleph.fetchPost(\n POST_TYPES.FILE,\n FileMetaEncryptedSchema,\n owner ? [owner] : undefined,\n entry.post_hash\n );\n\n // Decrypt metadata\n const decryptedMeta = await this.decryptFileMeta(encryptedMeta, privateKey);\n\n files.push({\n ...entry,\n ...decryptedMeta,\n });\n } catch (error) {\n // Skip files that can't be decrypted\n console.warn(`Failed to fetch metadata for ${entry.post_hash}:`, error);\n }\n }\n\n return files;\n } catch (error) {\n throw new FileError(`Failed to fetch files metadata: ${(error as Error).message}`);\n }\n }\n\n /**\n * List all files\n * @param includeDeleted - Include soft-deleted files\n */\n async listFiles(includeDeleted: boolean = false): Promise<FileFullInfo[]> {\n const entries = await this.fetchFileEntries();\n const files = await this.fetchFilesMetaFromEntries(entries);\n\n if (!includeDeleted) {\n return files.filter((f) => !f.deleted_at);\n }\n\n return files;\n }\n\n /**\n * Get a file by path\n * @param path - File path\n */\n async getFile(path: string): Promise<FileFullInfo> {\n const files = await this.listFiles(true);\n const file = files.find((f) => f.path === path);\n\n if (!file) {\n throw new FileNotFoundError(path);\n }\n\n return file;\n }\n\n /**\n * Soft delete files\n * @param filePaths - Paths of files to delete\n * @param deletionDate - Optional deletion date\n */\n async softDeleteFiles(filePaths: string[], deletionDate?: Date): Promise<void> {\n const aleph = this.core.getAlephService();\n const deletedAt = (deletionDate || new Date()).toISOString();\n\n try {\n for (const path of filePaths) {\n const file = await this.getFile(path);\n\n // Update metadata with deleted_at (creates new POST)\n const updatedPost = await aleph.updatePost(\n POST_TYPES.FILE,\n file.post_hash,\n [aleph.getAddress()],\n FileMetaEncryptedSchema,\n async (encryptedMeta) => {\n const decryptedMeta = await this.decryptFileMeta(encryptedMeta);\n decryptedMeta.deleted_at = deletedAt;\n return await this.encryptFileMeta(decryptedMeta);\n }\n );\n\n // Update aggregate with new post_hash\n await aleph.updateAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema, async (aggregate) => ({\n files: aggregate.files.map((entry) =>\n entry.post_hash === file.post_hash ? { ...entry, post_hash: updatedPost.item_hash } : entry\n ),\n }));\n }\n } catch (error) {\n throw new FileError(`Failed to soft delete files: ${(error as Error).message}`);\n }\n }\n\n /**\n * Restore soft-deleted files\n * @param filePaths - Paths of files to restore\n */\n async restoreFiles(filePaths: string[]): Promise<void> {\n const aleph = this.core.getAlephService();\n\n try {\n for (const path of filePaths) {\n const file = await this.getFile(path);\n\n // Update metadata to remove deleted_at (creates new POST)\n const updatedPost = await aleph.updatePost(\n POST_TYPES.FILE,\n file.post_hash,\n [aleph.getAddress()],\n FileMetaEncryptedSchema,\n async (encryptedMeta) => {\n const decryptedMeta = await this.decryptFileMeta(encryptedMeta);\n decryptedMeta.deleted_at = null;\n return await this.encryptFileMeta(decryptedMeta);\n }\n );\n\n // Update aggregate with new post_hash\n await aleph.updateAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema, async (aggregate) => ({\n files: aggregate.files.map((entry) =>\n entry.post_hash === file.post_hash ? { ...entry, post_hash: updatedPost.item_hash } : entry\n ),\n }));\n }\n } catch (error) {\n throw new FileError(`Failed to restore files: ${(error as Error).message}`);\n }\n }\n\n /**\n * Hard delete files (permanently remove from Aleph)\n * @param filePaths - Paths of files to delete\n */\n async hardDeleteFiles(filePaths: string[]): Promise<void> {\n const aleph = this.core.getAlephService();\n\n try {\n const files = await Promise.all(filePaths.map((path) => this.getFile(path)));\n\n // Remove from file entries aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema, async (aggregate) => ({\n files: aggregate.files.filter((entry) => !files.some((f) => f.post_hash === entry.post_hash)),\n }));\n\n // Forget STORE and POST messages\n const hashesToForget = files.flatMap((f) => [f.store_hash, f.post_hash]);\n await aleph.deleteFiles(hashesToForget);\n } catch (error) {\n throw new FileError(`Failed to hard delete files: ${(error as Error).message}`);\n }\n }\n\n /**\n * Move/rename files\n * @param moves - Array of {oldPath, newPath} objects\n */\n async moveFiles(moves: Array<{ oldPath: string; newPath: string }>): Promise<void> {\n const aleph = this.core.getAlephService();\n const publicKey = this.core.getPublicKey();\n\n try {\n for (const { oldPath, newPath } of moves) {\n const file = await this.getFile(oldPath);\n\n // Update metadata with new path and name (creates new POST)\n const updatedPost = await aleph.updatePost(\n POST_TYPES.FILE,\n file.post_hash,\n [aleph.getAddress()],\n FileMetaEncryptedSchema,\n async (encryptedMeta) => {\n const decryptedMeta = await this.decryptFileMeta(encryptedMeta);\n decryptedMeta.path = newPath;\n decryptedMeta.name = newPath.split('/').pop() || newPath;\n return await this.encryptFileMeta(decryptedMeta);\n }\n );\n\n // Update file entry with new encrypted path and new post_hash\n const newEncryptedPath = EncryptionService.encryptEcies(newPath, publicKey);\n await aleph.updateAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema, async (aggregate) => ({\n files: aggregate.files.map((entry) =>\n entry.post_hash === file.post_hash\n ? { ...entry, path: newEncryptedPath, post_hash: updatedPost.item_hash }\n : entry\n ),\n }));\n }\n } catch (error) {\n throw new FileError(`Failed to move files: ${(error as Error).message}`);\n }\n }\n\n /**\n * Duplicate a file\n * @param sourcePath - Source file path\n * @param newPath - New file path\n */\n async duplicateFile(sourcePath: string, newPath: string): Promise<FileFullInfo> {\n try {\n const sourceFile = await this.getFile(sourcePath);\n const content = await this.downloadFile(sourceFile);\n\n const [newFile] = await this.uploadFiles([\n {\n name: newPath.split('/').pop() || newPath,\n path: newPath,\n content,\n },\n ]);\n\n return newFile;\n } catch (error) {\n throw new FileError(`Failed to duplicate file: ${(error as Error).message}`);\n }\n }\n\n /**\n * Share a file with a contact\n * @param filePath - File path\n * @param contactPublicKey - Contact's public key\n */\n async shareFile(filePath: string, contactPublicKey: string): Promise<void> {\n const aleph = this.core.getAlephService();\n\n try {\n const file = await this.getFile(filePath);\n\n // Encrypt file key and IV with contact's public key\n const encryptedKey = EncryptionService.encryptEcies(file.key, contactPublicKey);\n const encryptedIv = EncryptionService.encryptEcies(file.iv, contactPublicKey);\n\n // Update metadata with shared keys (creates new POST)\n const updatedPost = await aleph.updatePost(\n POST_TYPES.FILE,\n file.post_hash,\n [aleph.getAddress()],\n FileMetaEncryptedSchema,\n async (encryptedMeta) => {\n const decryptedMeta = await this.decryptFileMeta(encryptedMeta);\n decryptedMeta.shared_keys[contactPublicKey] = {\n key: encryptedKey,\n iv: encryptedIv,\n };\n return await this.encryptFileMeta(decryptedMeta);\n }\n );\n\n // Update file entry with new post_hash and shared_with list\n await aleph.updateAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema, async (aggregate) => ({\n files: aggregate.files.map((entry) =>\n entry.post_hash === file.post_hash\n ? {\n ...entry,\n post_hash: updatedPost.item_hash,\n shared_with: [...new Set([...entry.shared_with, contactPublicKey])],\n }\n : entry\n ),\n }));\n } catch (error) {\n throw new FileError(`Failed to share file: ${(error as Error).message}`);\n }\n }\n\n /**\n * Unshare a file with a contact\n * @param filePath - File path\n * @param contactPublicKey - Contact's public key\n */\n async unshareFile(filePath: string, contactPublicKey: string): Promise<void> {\n const aleph = this.core.getAlephService();\n\n try {\n const file = await this.getFile(filePath);\n\n // Remove shared keys from metadata (creates new POST)\n const updatedPost = await aleph.updatePost(\n POST_TYPES.FILE,\n file.post_hash,\n [aleph.getAddress()],\n FileMetaEncryptedSchema,\n async (encryptedMeta) => {\n const decryptedMeta = await this.decryptFileMeta(encryptedMeta);\n delete decryptedMeta.shared_keys[contactPublicKey];\n return await this.encryptFileMeta(decryptedMeta);\n }\n );\n\n // Update file entry with new post_hash and shared_with list\n await aleph.updateAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema, async (aggregate) => ({\n files: aggregate.files.map((entry) =>\n entry.post_hash === file.post_hash\n ? {\n ...entry,\n post_hash: updatedPost.item_hash,\n shared_with: entry.shared_with.filter((pk) => pk !== contactPublicKey),\n }\n : entry\n ),\n }));\n } catch (error) {\n throw new FileError(`Failed to unshare file: ${(error as Error).message}`);\n }\n }\n\n /**\n * Share a file publicly (unencrypted, anyone can access)\n * @param fileInfo - File to share publicly\n * @param username - Username for attribution\n * @returns Public post hash for sharing\n */\n async shareFilePublicly(fileInfo: FileFullInfo, username: string): Promise<string> {\n const aleph = this.core.getAlephService();\n\n try {\n // Download and decrypt file\n const decryptedContent = await this.downloadFile(fileInfo);\n\n // Re-upload without encryption\n const storeResult = await aleph.uploadFile(decryptedContent);\n\n // Create public metadata\n const publicMeta: PublicFileMeta = {\n name: fileInfo.name,\n size: fileInfo.size,\n created_at: new Date().toISOString(),\n store_hash: storeResult.item_hash,\n username,\n };\n\n // Create public POST\n const postResult = await aleph.createPost(POST_TYPES.PUBLIC_FILE, publicMeta);\n\n return postResult.item_hash;\n } catch (error) {\n throw new FileError(`Failed to share file publicly: ${(error as Error).message}`);\n }\n }\n\n /**\n * Fetch public file metadata (static - no auth required)\n * @param postHash - Public post hash\n * @returns Public file metadata or null if not found\n */\n static async fetchPublicFileMeta(postHash: string): Promise<PublicFileMeta | null> {\n try {\n const client = new AlephHttpClient('https://api2.aleph.im');\n const post = await client.getPost({\n channels: [ALEPH_GENERAL_CHANNEL],\n types: [POST_TYPES.PUBLIC_FILE],\n hashes: [postHash],\n });\n\n return PublicFileMetaSchema.parse(post.content);\n } catch {\n return null;\n }\n }\n\n /**\n * Download public file (static - no auth required)\n * @param storeHash - Store hash from public metadata\n * @returns File content as ArrayBuffer\n */\n static async downloadPublicFile(storeHash: string): Promise<ArrayBuffer> {\n try {\n const client = new AlephHttpClient('https://api2.aleph.im');\n return await client.downloadFile(storeHash);\n } catch (error) {\n throw new FileError(`Failed to download public file: ${(error as Error).message}`);\n }\n }\n\n // ============================================================================\n // Private helper methods\n // ============================================================================\n\n private async saveFileEntries(files: FileFullInfo[]): Promise<void> {\n const aleph = this.core.getAlephService();\n const publicKey = this.core.getPublicKey();\n\n await aleph.updateAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema, async (aggregate) => {\n const newEntries = files.map((f) => ({\n path: EncryptionService.encryptEcies(f.path, publicKey),\n post_hash: f.post_hash,\n shared_with: f.shared_with || [],\n }));\n return { files: [...aggregate.files, ...newEntries] };\n });\n }\n\n private async encryptFileMeta(meta: FileMeta): Promise<any> {\n const publicKey = this.core.getPublicKey();\n\n // Use file's own key/iv for all encryption\n const fileKey = Buffer.from(meta.key, 'hex');\n const fileIv = Buffer.from(meta.iv, 'hex');\n\n return {\n name: await EncryptionService.encrypt(meta.name, fileKey, fileIv),\n path: await EncryptionService.encrypt(meta.path, fileKey, fileIv),\n key: EncryptionService.encryptEcies(meta.key, publicKey),\n iv: EncryptionService.encryptEcies(meta.iv, publicKey),\n store_hash: await EncryptionService.encrypt(meta.store_hash, fileKey, fileIv),\n size: await EncryptionService.encrypt(meta.size.toString(), fileKey, fileIv),\n created_at: await EncryptionService.encrypt(meta.created_at, fileKey, fileIv),\n deleted_at: await EncryptionService.encrypt(meta.deleted_at ?? 'null', fileKey, fileIv),\n shared_keys: meta.shared_keys,\n };\n }\n\n private async decryptFileMeta(encryptedMeta: any, privateKey?: string): Promise<FileMeta> {\n const privKey = privateKey || this.core.getSubAccountPrivateKey();\n\n if (!privKey) {\n throw new EncryptionError('Private key not available');\n }\n\n // Decrypt file key and IV first\n const decryptedKey = EncryptionService.decryptEcies(encryptedMeta.key, privKey);\n const decryptedIv = EncryptionService.decryptEcies(encryptedMeta.iv, privKey);\n const fileKey = Buffer.from(decryptedKey, 'hex');\n const fileIv = Buffer.from(decryptedIv, 'hex');\n\n const decryptedDeletedAt = await EncryptionService.decrypt(encryptedMeta.deleted_at, fileKey, fileIv);\n\n return {\n name: await EncryptionService.decrypt(encryptedMeta.name, fileKey, fileIv),\n path: await EncryptionService.decrypt(encryptedMeta.path, fileKey, fileIv),\n key: decryptedKey,\n iv: decryptedIv,\n store_hash: await EncryptionService.decrypt(encryptedMeta.store_hash, fileKey, fileIv),\n size: Number.parseInt(await EncryptionService.decrypt(encryptedMeta.size, fileKey, fileIv)),\n created_at: await EncryptionService.decrypt(encryptedMeta.created_at, fileKey, fileIv),\n deleted_at: decryptedDeletedAt === 'null' ? null : decryptedDeletedAt,\n shared_keys: encryptedMeta.shared_keys || {},\n };\n }\n}\n","import { encrypt as eciesEncrypt, decrypt as eciesDecrypt } from 'eciesjs';\nimport { EncryptionError } from '../types/errors';\n\n/**\n * Universal crypto utilities that work in both Node.js and browser\n */\nclass CryptoUtils {\n static isBrowser = typeof window !== 'undefined' && typeof window.crypto !== 'undefined';\n\n /**\n * Get crypto implementation (Node.js or browser)\n */\n static getCrypto() {\n if (this.isBrowser) {\n return window.crypto;\n }\n // Node.js\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const nodeCrypto = require('crypto');\n return nodeCrypto.webcrypto || nodeCrypto;\n }\n\n /**\n * Generate random bytes\n */\n static getRandomBytes(length: number): Uint8Array {\n const crypto = this.getCrypto();\n const bytes = new Uint8Array(length);\n\n if (this.isBrowser) {\n crypto.getRandomValues(bytes);\n } else {\n // Node.js\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const nodeCrypto = require('crypto');\n const randomBytes = nodeCrypto.randomBytes(length);\n bytes.set(randomBytes);\n }\n\n return bytes;\n }\n\n /**\n * Convert buffer to hex string\n */\n static bufferToHex(buffer: Buffer | Uint8Array): string {\n return Buffer.from(buffer).toString('hex');\n }\n\n /**\n * Convert hex string to buffer\n */\n static hexToBuffer(hex: string): Buffer {\n return Buffer.from(hex, 'hex');\n }\n\n /**\n * Hash using SHA-256\n */\n static async sha256(data: string | Buffer): Promise<Buffer> {\n const bytes = typeof data === 'string' ? Buffer.from(data, 'utf-8') : data;\n\n if (this.isBrowser) {\n const crypto = this.getCrypto();\n const hashBuffer = await crypto.subtle.digest('SHA-256', bytes);\n return Buffer.from(hashBuffer);\n } else {\n // Node.js\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const nodeCrypto = require('crypto');\n return nodeCrypto.createHash('sha256').update(bytes).digest();\n }\n }\n}\n\n/**\n * Encryption service for AES-256-CBC and ECIES operations\n */\nexport class EncryptionService {\n /**\n * Generate a random encryption key (32 bytes for AES-256)\n */\n static generateKey(): Buffer {\n return Buffer.from(CryptoUtils.getRandomBytes(32));\n }\n\n /**\n * Generate a random initialization vector (16 bytes for AES)\n */\n static generateIv(): Buffer {\n return Buffer.from(CryptoUtils.getRandomBytes(16));\n }\n\n /**\n * Encrypt data using AES-256-CBC\n * @param data - Data to encrypt\n * @param key - 32-byte encryption key\n * @param iv - 16-byte initialization vector\n * @returns Hex-encoded encrypted data\n */\n static async encrypt(data: string, key: Buffer, iv: Buffer): Promise<string> {\n try {\n if (key.length !== 32) {\n throw new EncryptionError('Key must be 32 bytes for AES-256');\n }\n if (iv.length !== 16) {\n throw new EncryptionError('IV must be 16 bytes');\n }\n\n if (CryptoUtils.isBrowser) {\n return await this.encryptBrowser(data, key, iv);\n } else {\n return this.encryptNode(data, key, iv);\n }\n } catch (error) {\n throw new EncryptionError(`Encryption failed: ${(error as Error).message}`);\n }\n }\n\n /**\n * Decrypt data using AES-256-CBC\n * @param encryptedData - Hex-encoded encrypted data\n * @param key - 32-byte encryption key\n * @param iv - 16-byte initialization vector\n * @returns Decrypted string\n */\n static async decrypt(encryptedData: string, key: Buffer, iv: Buffer): Promise<string> {\n try {\n if (key.length !== 32) {\n throw new EncryptionError('Key must be 32 bytes for AES-256');\n }\n if (iv.length !== 16) {\n throw new EncryptionError('IV must be 16 bytes');\n }\n\n if (CryptoUtils.isBrowser) {\n return await this.decryptBrowser(encryptedData, key, iv);\n } else {\n return this.decryptNode(encryptedData, key, iv);\n }\n } catch (error) {\n throw new EncryptionError(`Decryption failed: ${(error as Error).message}`);\n }\n }\n\n /**\n * Encrypt file buffer using AES-256-CBC\n * @param fileBuffer - File data as Buffer or ArrayBuffer\n * @param key - 32-byte encryption key\n * @param iv - 16-byte initialization vector\n * @returns Encrypted file buffer\n */\n static async encryptFile(fileBuffer: Buffer | ArrayBuffer, key: Buffer, iv: Buffer): Promise<Buffer> {\n try {\n const buffer = Buffer.isBuffer(fileBuffer) ? fileBuffer : Buffer.from(fileBuffer);\n\n if (CryptoUtils.isBrowser) {\n return await this.encryptFileBrowser(buffer, key, iv);\n } else {\n return this.encryptFileNode(buffer, key, iv);\n }\n } catch (error) {\n throw new EncryptionError(`File encryption failed: ${(error as Error).message}`);\n }\n }\n\n /**\n * Decrypt file buffer using AES-256-CBC\n * @param encryptedBuffer - Encrypted file data\n * @param key - 32-byte encryption key\n * @param iv - 16-byte initialization vector\n * @returns Decrypted file buffer\n */\n static async decryptFile(encryptedBuffer: Buffer | ArrayBuffer, key: Buffer, iv: Buffer): Promise<Buffer> {\n try {\n const buffer = Buffer.isBuffer(encryptedBuffer) ? encryptedBuffer : Buffer.from(encryptedBuffer);\n\n if (CryptoUtils.isBrowser) {\n return await this.decryptFileBrowser(buffer, key, iv);\n } else {\n return this.decryptFileNode(buffer, key, iv);\n }\n } catch (error) {\n throw new EncryptionError(`File decryption failed: ${(error as Error).message}`);\n }\n }\n\n /**\n * Encrypt data using ECIES (Elliptic Curve Integrated Encryption Scheme)\n * @param data - Data to encrypt\n * @param publicKey - Recipient's public key (hex or Buffer)\n * @returns Hex-encoded encrypted data\n */\n static encryptEcies(data: string, publicKey: string | Buffer): string {\n try {\n const pubKeyBuffer = typeof publicKey === 'string' ? CryptoUtils.hexToBuffer(publicKey) : publicKey;\n\n const dataBuffer = Buffer.from(data, 'utf-8');\n const encrypted = eciesEncrypt(pubKeyBuffer, dataBuffer);\n return encrypted.toString('hex');\n } catch (error) {\n throw new EncryptionError(`ECIES encryption failed: ${(error as Error).message}`);\n }\n }\n\n /**\n * Decrypt data using ECIES\n * @param encryptedData - Hex-encoded encrypted data\n * @param privateKey - Recipient's private key (hex or Buffer)\n * @returns Decrypted string\n */\n static decryptEcies(encryptedData: string, privateKey: string | Buffer): string {\n try {\n const privKeyBuffer = typeof privateKey === 'string' ? CryptoUtils.hexToBuffer(privateKey) : privateKey;\n\n const encryptedBuffer = CryptoUtils.hexToBuffer(encryptedData);\n const decrypted = eciesDecrypt(privKeyBuffer, encryptedBuffer);\n return decrypted.toString('utf-8');\n } catch (error) {\n throw new EncryptionError(`ECIES decryption failed: ${(error as Error).message}`);\n }\n }\n\n /**\n * Hash data using SHA-256\n */\n static async hash(data: string | Buffer): Promise<string> {\n const hashBuffer = await CryptoUtils.sha256(data);\n return CryptoUtils.bufferToHex(hashBuffer);\n }\n\n // ============================================================================\n // Node.js implementations\n // ============================================================================\n\n private static encryptNode(data: string, key: Buffer, iv: Buffer): string {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const crypto = require('crypto');\n const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);\n let encrypted = cipher.update(data, 'utf-8', 'hex');\n encrypted += cipher.final('hex');\n return encrypted;\n }\n\n private static decryptNode(encryptedData: string, key: Buffer, iv: Buffer): string {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const crypto = require('crypto');\n const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);\n let decrypted = decipher.update(encryptedData, 'hex', 'utf-8');\n decrypted += decipher.final('utf-8');\n return decrypted;\n }\n\n private static encryptFileNode(buffer: Buffer, key: Buffer, iv: Buffer): Buffer {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const crypto = require('crypto');\n const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);\n return Buffer.concat([cipher.update(buffer), cipher.final()]);\n }\n\n private static decryptFileNode(buffer: Buffer, key: Buffer, iv: Buffer): Buffer {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const crypto = require('crypto');\n const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);\n return Buffer.concat([decipher.update(buffer), decipher.final()]);\n }\n\n // ============================================================================\n // Browser implementations\n // ============================================================================\n\n private static async encryptBrowser(data: string, key: Buffer, iv: Buffer): Promise<string> {\n const crypto = CryptoUtils.getCrypto();\n const cryptoKey = await crypto.subtle.importKey('raw', key, { name: 'AES-CBC' }, false, ['encrypt']);\n\n const dataBuffer = Buffer.from(data, 'utf-8');\n const encrypted = await crypto.subtle.encrypt({ name: 'AES-CBC', iv }, cryptoKey, dataBuffer);\n\n return CryptoUtils.bufferToHex(Buffer.from(encrypted));\n }\n\n private static async decryptBrowser(encryptedData: string, key: Buffer, iv: Buffer): Promise<string> {\n const crypto = CryptoUtils.getCrypto();\n const cryptoKey = await crypto.subtle.importKey('raw', key, { name: 'AES-CBC' }, false, ['decrypt']);\n\n const encryptedBuffer = CryptoUtils.hexToBuffer(encryptedData);\n const decrypted = await crypto.subtle.decrypt({ name: 'AES-CBC', iv }, cryptoKey, encryptedBuffer);\n\n return Buffer.from(decrypted).toString('utf-8');\n }\n\n private static async encryptFileBrowser(buffer: Buffer, key: Buffer, iv: Buffer): Promise<Buffer> {\n const crypto = CryptoUtils.getCrypto();\n const cryptoKey = await crypto.subtle.importKey('raw', key, { name: 'AES-CBC' }, false, ['encrypt']);\n\n const encrypted = await crypto.subtle.encrypt({ name: 'AES-CBC', iv }, cryptoKey, buffer);\n\n return Buffer.from(encrypted);\n }\n\n private static async decryptFileBrowser(buffer: Buffer, key: Buffer, iv: Buffer): Promise<Buffer> {\n const crypto = CryptoUtils.getCrypto();\n const cryptoKey = await crypto.subtle.importKey('raw', key, { name: 'AES-CBC' }, false, ['decrypt']);\n\n const decrypted = await crypto.subtle.decrypt({ name: 'AES-CBC', iv }, cryptoKey, buffer);\n\n return Buffer.from(decrypted);\n }\n}\n\nexport { CryptoUtils };\n","import { BedrockCore } from '../client/bedrock-core';\nimport { ContactError } from '../types/errors';\nimport type { FileFullInfo } from '../types/schemas';\nimport { AGGREGATE_KEYS, Contact, ContactsAggregateSchema, FileEntriesAggregateSchema } from '../types/schemas';\nimport { FileService } from './file-service';\n\n/**\n * Contact service for managing contacts and shared files\n */\nexport class ContactService {\n private readonly core: BedrockCore;\n private readonly fileService: FileService;\n\n constructor(core: BedrockCore, fileService: FileService) {\n this.core = core;\n this.fileService = fileService;\n }\n\n /**\n * Initialize contacts aggregate if it doesn't exist\n */\n async setup(): Promise<void> {\n const aleph = this.core.getAlephService();\n\n try {\n await aleph.fetchAggregate(AGGREGATE_KEYS.CONTACTS, ContactsAggregateSchema);\n } catch {\n // Create empty aggregate if it doesn't exist\n await aleph.createAggregate(AGGREGATE_KEYS.CONTACTS, { contacts: [] });\n }\n }\n\n /**\n * Fetch all contacts\n */\n async listContacts(): Promise<Contact[]> {\n const aleph = this.core.getAlephService();\n\n try {\n const aggregate = await aleph.fetchAggregate(AGGREGATE_KEYS.CONTACTS, ContactsAggregateSchema);\n return aggregate.contacts;\n } catch (error) {\n throw new ContactError(`Failed to fetch contacts: ${(error as Error).message}`);\n }\n }\n\n /**\n * Get a contact by public key\n * @param publicKey - Contact's public key\n */\n async getContact(publicKey: string): Promise<Contact> {\n const contacts = await this.listContacts();\n const contact = contacts.find((c) => c.public_key === publicKey);\n\n if (!contact) {\n throw new ContactError(`Contact not found: ${publicKey}`);\n }\n\n return contact;\n }\n\n /**\n * Get a contact by address\n * @param address - Contact's Ethereum address\n */\n async getContactByAddress(address: string): Promise<Contact> {\n const contacts = await this.listContacts();\n const contact = contacts.find((c) => c.address.toLowerCase() === address.toLowerCase());\n\n if (!contact) {\n throw new ContactError(`Contact not found: ${address}`);\n }\n\n return contact;\n }\n\n /**\n * Add a new contact\n * @param name - Contact name\n * @param address - Contact's Ethereum address\n * @param publicKey - Contact's public key (hex string)\n */\n async addContact(name: string, address: string, publicKey: string): Promise<Contact> {\n const aleph = this.core.getAlephService();\n\n try {\n // Check if contact already exists\n const contacts = await this.listContacts();\n const existingContact = contacts.find(\n (c) => c.public_key === publicKey || c.address.toLowerCase() === address.toLowerCase()\n );\n\n if (existingContact) {\n throw new ContactError('Contact already exists');\n }\n\n // Create new contact\n const newContact: Contact = {\n name,\n address,\n public_key: publicKey,\n };\n\n // Add to contacts aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.CONTACTS, ContactsAggregateSchema, async (aggregate) => ({\n contacts: [...aggregate.contacts, newContact],\n }));\n\n return newContact;\n } catch (error) {\n if (error instanceof ContactError) {\n throw error;\n }\n throw new ContactError(`Failed to add contact: ${(error as Error).message}`);\n }\n }\n\n /**\n * Remove a contact\n * @param publicKey - Contact's public key\n */\n async removeContact(publicKey: string): Promise<void> {\n const aleph = this.core.getAlephService();\n\n try {\n // Verify contact exists\n await this.getContact(publicKey);\n\n // Remove from contacts aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.CONTACTS, ContactsAggregateSchema, async (aggregate) => ({\n contacts: aggregate.contacts.filter((c) => c.public_key !== publicKey),\n }));\n } catch (error) {\n if (error instanceof ContactError) {\n throw error;\n }\n throw new ContactError(`Failed to remove contact: ${(error as Error).message}`);\n }\n }\n\n /**\n * Update a contact's name\n * @param publicKey - Contact's public key\n * @param newName - New name for the contact\n */\n async updateContactName(publicKey: string, newName: string): Promise<Contact> {\n const aleph = this.core.getAlephService();\n\n try {\n // Verify contact exists\n const existingContact = await this.getContact(publicKey);\n\n // Update contact\n const updatedContact: Contact = {\n ...existingContact,\n name: newName,\n };\n\n // Update in contacts aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.CONTACTS, ContactsAggregateSchema, async (aggregate) => ({\n contacts: aggregate.contacts.map((c) => (c.public_key === publicKey ? updatedContact : c)),\n }));\n\n return updatedContact;\n } catch (error) {\n if (error instanceof ContactError) {\n throw error;\n }\n throw new ContactError(`Failed to update contact: ${(error as Error).message}`);\n }\n }\n\n /**\n * Fetch files shared by a contact\n * @param publicKey - Contact's public key\n */\n async getSharedFiles(publicKey: string): Promise<FileFullInfo[]> {\n try {\n // Verify contact exists\n await this.getContact(publicKey);\n\n // Fetch file entries\n const entries = await this.fileService.fetchFileEntries();\n\n // Filter entries shared with this contact\n const sharedEntries = entries.filter((entry) => entry.shared_with.includes(publicKey));\n\n // Fetch metadata for shared files\n const files = await this.fileService.fetchFilesMetaFromEntries(sharedEntries);\n\n return files;\n } catch (error) {\n throw new ContactError(`Failed to fetch shared files: ${(error as Error).message}`);\n }\n }\n\n /**\n * Fetch files that a contact has shared with the current user\n * @param publicKey - Contact's public key\n * @returns Files shared by the contact with current user\n */\n async fetchFilesSharedByContact(publicKey: string): Promise<FileFullInfo[]> {\n try {\n // Verify contact exists and get their address\n const contact = await this.getContact(publicKey);\n const currentUserPublicKey = this.core.getPublicKey();\n\n // Fetch contact's file entries from THEIR aggregate\n const aleph = this.core.getAlephService();\n const contactEntries = await aleph.fetchAggregate(\n AGGREGATE_KEYS.FILE_ENTRIES,\n FileEntriesAggregateSchema,\n contact.address // Important: contact's address, not current user's\n );\n\n // Filter entries shared with current user\n const sharedEntries = contactEntries.files.filter((entry) => entry.shared_with.includes(currentUserPublicKey));\n\n // Fetch metadata from contact's POSTs using fileService\n const files = await this.fileService.fetchFilesMetaFromEntries(\n sharedEntries,\n contact.address // Owner is the contact\n );\n\n return files;\n } catch (error) {\n throw new ContactError(`Failed to fetch files shared by contact: ${(error as Error).message}`);\n }\n }\n\n /**\n * Share a file with a contact\n * @param filePath - Path of the file to share\n * @param publicKey - Contact's public key\n */\n async shareFileWithContact(filePath: string, publicKey: string): Promise<void> {\n try {\n // Verify contact exists\n await this.getContact(publicKey);\n\n // Share the file\n await this.fileService.shareFile(filePath, publicKey);\n } catch (error) {\n throw new ContactError(`Failed to share file with contact: ${(error as Error).message}`);\n }\n }\n\n /**\n * Unshare a file with a contact\n * @param filePath - Path of the file to unshare\n * @param publicKey - Contact's public key\n */\n async unshareFileWithContact(filePath: string, publicKey: string): Promise<void> {\n try {\n // Verify contact exists\n await this.getContact(publicKey);\n\n // Unshare the file\n await this.fileService.unshareFile(filePath, publicKey);\n } catch (error) {\n throw new ContactError(`Failed to unshare file with contact: ${(error as Error).message}`);\n }\n }\n}\n","import { BedrockCore } from '../client/bedrock-core';\nimport { KnowledgeBaseError } from '../types/errors';\nimport { AGGREGATE_KEYS, KnowledgeBase, KnowledgeBasesAggregateSchema } from '../types/schemas';\n\n/**\n * Knowledge base service for organizing files into collections\n */\nexport class KnowledgeBaseService {\n private readonly core: BedrockCore;\n\n constructor(core: BedrockCore) {\n this.core = core;\n }\n\n /**\n * Initialize knowledge bases aggregate if it doesn't exist\n */\n async setup(): Promise<void> {\n const aleph = this.core.getAlephService();\n\n try {\n await aleph.fetchAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, KnowledgeBasesAggregateSchema);\n } catch {\n // Create empty aggregate if it doesn't exist\n await aleph.createAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, { knowledge_bases: [] });\n }\n }\n\n /**\n * Fetch all knowledge bases\n */\n async listKnowledgeBases(): Promise<KnowledgeBase[]> {\n const aleph = this.core.getAlephService();\n\n try {\n const aggregate = await aleph.fetchAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, KnowledgeBasesAggregateSchema);\n return aggregate.knowledge_bases;\n } catch (error) {\n throw new KnowledgeBaseError(`Failed to fetch knowledge bases: ${(error as Error).message}`);\n }\n }\n\n /**\n * Get a knowledge base by name\n * @param name - Knowledge base name\n */\n async getKnowledgeBase(name: string): Promise<KnowledgeBase> {\n const kbs = await this.listKnowledgeBases();\n const kb = kbs.find((k) => k.name === name);\n\n if (!kb) {\n throw new KnowledgeBaseError(`Knowledge base not found: ${name}`);\n }\n\n return kb;\n }\n\n /**\n * Create a new knowledge base\n * @param name - Knowledge base name\n * @param filePaths - Optional initial file paths\n */\n async createKnowledgeBase(name: string, filePaths: string[] = []): Promise<KnowledgeBase> {\n const aleph = this.core.getAlephService();\n\n try {\n // Check if knowledge base already exists\n const kbs = await this.listKnowledgeBases();\n const existingKb = kbs.find((k) => k.name === name);\n\n if (existingKb) {\n throw new KnowledgeBaseError(`Knowledge base already exists: ${name}`);\n }\n\n // Create new knowledge base\n const now = new Date().toISOString();\n const newKb: KnowledgeBase = {\n name,\n file_paths: filePaths,\n created_at: now,\n updated_at: now,\n };\n\n // Add to knowledge bases aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, KnowledgeBasesAggregateSchema, async (aggregate) => ({\n knowledge_bases: [...aggregate.knowledge_bases, newKb],\n }));\n\n return newKb;\n } catch (error) {\n if (error instanceof KnowledgeBaseError) {\n throw error;\n }\n throw new KnowledgeBaseError(`Failed to create knowledge base: ${(error as Error).message}`);\n }\n }\n\n /**\n * Delete a knowledge base\n * @param name - Knowledge base name\n */\n async deleteKnowledgeBase(name: string): Promise<void> {\n const aleph = this.core.getAlephService();\n\n try {\n // Verify knowledge base exists\n await this.getKnowledgeBase(name);\n\n // Remove from knowledge bases aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, KnowledgeBasesAggregateSchema, async (aggregate) => ({\n knowledge_bases: aggregate.knowledge_bases.filter((k) => k.name !== name),\n }));\n } catch (error) {\n if (error instanceof KnowledgeBaseError) {\n throw error;\n }\n throw new KnowledgeBaseError(`Failed to delete knowledge base: ${(error as Error).message}`);\n }\n }\n\n /**\n * Rename a knowledge base\n * @param oldName - Current name\n * @param newName - New name\n */\n async renameKnowledgeBase(oldName: string, newName: string): Promise<KnowledgeBase> {\n const aleph = this.core.getAlephService();\n\n try {\n // Verify old knowledge base exists\n const existingKb = await this.getKnowledgeBase(oldName);\n\n // Check if new name already exists\n const kbs = await this.listKnowledgeBases();\n if (kbs.some((k) => k.name === newName)) {\n throw new KnowledgeBaseError(`Knowledge base already exists: ${newName}`);\n }\n\n // Update knowledge base\n const updatedKb: KnowledgeBase = {\n ...existingKb,\n name: newName,\n updated_at: new Date().toISOString(),\n };\n\n // Update in knowledge bases aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, KnowledgeBasesAggregateSchema, async (aggregate) => ({\n knowledge_bases: aggregate.knowledge_bases.map((k) => (k.name === oldName ? updatedKb : k)),\n }));\n\n return updatedKb;\n } catch (error) {\n if (error instanceof KnowledgeBaseError) {\n throw error;\n }\n throw new KnowledgeBaseError(`Failed to rename knowledge base: ${(error as Error).message}`);\n }\n }\n\n /**\n * Set the files in a knowledge base (replaces all existing files)\n * @param name - Knowledge base name\n * @param filePaths - File paths\n */\n async setFiles(name: string, filePaths: string[]): Promise<KnowledgeBase> {\n const aleph = this.core.getAlephService();\n\n try {\n // Verify knowledge base exists\n const existingKb = await this.getKnowledgeBase(name);\n\n // Update knowledge base\n const updatedKb: KnowledgeBase = {\n ...existingKb,\n file_paths: filePaths,\n updated_at: new Date().toISOString(),\n };\n\n // Update in knowledge bases aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, KnowledgeBasesAggregateSchema, async (aggregate) => ({\n knowledge_bases: aggregate.knowledge_bases.map((k) => (k.name === name ? updatedKb : k)),\n }));\n\n return updatedKb;\n } catch (error) {\n if (error instanceof KnowledgeBaseError) {\n throw error;\n }\n throw new KnowledgeBaseError(`Failed to set files: ${(error as Error).message}`);\n }\n }\n\n /**\n * Add files to a knowledge base\n * @param name - Knowledge base name\n * @param filePaths - File paths to add\n */\n async addFiles(name: string, filePaths: string[]): Promise<KnowledgeBase> {\n const aleph = this.core.getAlephService();\n\n try {\n // Verify knowledge base exists\n const existingKb = await this.getKnowledgeBase(name);\n\n // Add new file paths (avoid duplicates)\n const updatedFilePaths = [...new Set([...existingKb.file_paths, ...filePaths])];\n\n // Update knowledge base\n const updatedKb: KnowledgeBase = {\n ...existingKb,\n file_paths: updatedFilePaths,\n updated_at: new Date().toISOString(),\n };\n\n // Update in knowledge bases aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, KnowledgeBasesAggregateSchema, async (aggregate) => ({\n knowledge_bases: aggregate.knowledge_bases.map((k) => (k.name === name ? updatedKb : k)),\n }));\n\n return updatedKb;\n } catch (error) {\n if (error instanceof KnowledgeBaseError) {\n throw error;\n }\n throw new KnowledgeBaseError(`Failed to add files: ${(error as Error).message}`);\n }\n }\n\n /**\n * Remove files from a knowledge base\n * @param name - Knowledge base name\n * @param filePaths - File paths to remove\n */\n async removeFiles(name: string, filePaths: string[]): Promise<KnowledgeBase> {\n const aleph = this.core.getAlephService();\n\n try {\n // Verify knowledge base exists\n const existingKb = await this.getKnowledgeBase(name);\n\n // Remove file paths\n const updatedFilePaths = existingKb.file_paths.filter((path) => !filePaths.includes(path));\n\n // Update knowledge base\n const updatedKb: KnowledgeBase = {\n ...existingKb,\n file_paths: updatedFilePaths,\n updated_at: new Date().toISOString(),\n };\n\n // Update in knowledge bases aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, KnowledgeBasesAggregateSchema, async (aggregate) => ({\n knowledge_bases: aggregate.knowledge_bases.map((k) => (k.name === name ? updatedKb : k)),\n }));\n\n return updatedKb;\n } catch (error) {\n if (error instanceof KnowledgeBaseError) {\n throw error;\n }\n throw new KnowledgeBaseError(`Failed to remove files: ${(error as Error).message}`);\n }\n }\n\n /**\n * Clear all files from a knowledge base\n * @param name - Knowledge base name\n */\n async clearFiles(name: string): Promise<KnowledgeBase> {\n return await this.setFiles(name, []);\n }\n}\n","import { BedrockCore } from '../client/bedrock-core';\nimport { UserCredit, CreditAggregateSchema, AGGREGATE_KEYS } from '../types/schemas';\n\n/**\n * Service for managing user credits (read-only, backend-managed)\n */\nexport class CreditService {\n private core: BedrockCore;\n private static readonly BACKEND_ADDRESS = '0x1234567890123456789012345678901234567890';\n\n constructor(core: BedrockCore) {\n this.core = core;\n }\n\n /**\n * Get user's credit balance and transaction history\n * @returns User credit data with balance and transactions\n */\n async getCreditBalance(): Promise<UserCredit> {\n const aleph = this.core.getAlephService();\n const userAddress = this.core.getMainAddress();\n\n try {\n const creditAggregate = await aleph.fetchAggregate(\n AGGREGATE_KEYS.CREDITS,\n CreditAggregateSchema,\n CreditService.BACKEND_ADDRESS\n );\n\n return creditAggregate[userAddress] || { balance: 0, transactions: [] };\n } catch {\n // Graceful fallback if aggregate doesn't exist or user not found\n return { balance: 0, transactions: [] };\n }\n }\n}\n","import { BedrockCore, BedrockCoreConfig } from './client/bedrock-core';\nimport { FileService } from './services/file-service';\nimport { ContactService } from './services/contact-service';\nimport { KnowledgeBaseService } from './services/knowledge-base-service';\nimport { CreditService } from './services/credit-service';\n\n/**\n * Main Bedrock SDK client\n *\n * @example\n * ```typescript\n * // Initialize from private key\n * const client = await BedrockClient.fromPrivateKey('0x...');\n *\n * // Initialize from wallet provider (MetaMask, etc.)\n * const client = await BedrockClient.fromProvider(window.ethereum);\n *\n * // Upload files\n * const files = await client.files.uploadFiles([\n * { name: 'doc.txt', path: 'documents/doc.txt', content: buffer }\n * ]);\n *\n * // List files\n * const allFiles = await client.files.listFiles();\n *\n * // Add contact\n * await client.contacts.addContact('Alice', '0x...', 'publicKey');\n *\n * // Create knowledge base\n * await client.knowledgeBases.createKnowledgeBase('My Documents');\n *\n * // Check credit balance\n * const balance = await client.credits.getCreditBalance();\n *\n * // Share file publicly\n * const publicHash = await client.files.shareFilePublicly(file, 'username');\n * const meta = await FileService.fetchPublicFileMeta(publicHash);\n * const content = await FileService.downloadPublicFile(meta.store_hash);\n *\n * // Get files shared by contact\n * const sharedFiles = await client.contacts.fetchFilesSharedByContact(contactPubKey);\n * ```\n */\nexport class BedrockClient {\n private core: BedrockCore;\n\n /**\n * File operations service\n */\n public readonly files: FileService;\n\n /**\n * Contact management service\n */\n public readonly contacts: ContactService;\n\n /**\n * Knowledge base management service\n */\n public readonly knowledgeBases: KnowledgeBaseService;\n\n /**\n * Credit management service\n */\n public readonly credits: CreditService;\n\n private constructor(core: BedrockCore) {\n this.core = core;\n this.files = new FileService(core);\n this.contacts = new ContactService(core, this.files);\n this.knowledgeBases = new KnowledgeBaseService(core);\n this.credits = new CreditService(core);\n }\n\n /**\n * Create BedrockClient from a private key\n *\n * @param privateKey - Ethereum private key (hex string with or without 0x prefix)\n * @param config - Optional configuration\n * @returns Initialized BedrockClient\n *\n * @example\n * ```typescript\n * const client = await BedrockClient.fromPrivateKey('0xabc123...');\n * ```\n */\n static async fromPrivateKey(privateKey: string, config?: BedrockCoreConfig): Promise<BedrockClient> {\n const core = await BedrockCore.fromPrivateKey(privateKey, config);\n const client = new BedrockClient(core);\n await client.setup();\n return client;\n }\n\n /**\n * Create BedrockClient from a wallet provider (e.g., MetaMask)\n *\n * @param provider - EIP-1193 provider\n * @param config - Optional configuration\n * @returns Initialized BedrockClient\n *\n * @example\n * ```typescript\n * const client = await BedrockClient.fromProvider(window.ethereum);\n * ```\n */\n static async fromProvider(provider: any, config?: BedrockCoreConfig): Promise<BedrockClient> {\n const core = await BedrockCore.fromProvider(provider, config);\n const client = new BedrockClient(core);\n await client.setup();\n return client;\n }\n\n /**\n * Create BedrockClient from a signature hash\n *\n * @param signatureHash - Signature hash from wallet\n * @param provider - EIP-1193 provider\n * @param config - Optional configuration\n * @returns Initialized BedrockClient\n *\n * @example\n * ```typescript\n * const signature = await wallet.signMessage({ message: 'Bedrock.im' });\n * const client = await BedrockClient.fromSignature(signature, window.ethereum);\n * ```\n */\n static async fromSignature(signatureHash: string, provider: any, config?: BedrockCoreConfig): Promise<BedrockClient> {\n const core = await BedrockCore.fromSignature(signatureHash, provider, config);\n const client = new BedrockClient(core);\n await client.setup();\n return client;\n }\n\n /**\n * Get the main account address\n */\n getMainAddress(): string {\n return this.core.getMainAddress();\n }\n\n /**\n * Get the sub-account address\n */\n getSubAddress(): string {\n return this.core.getSubAddress();\n }\n\n /**\n * Get the account's public key\n */\n getPublicKey(): string {\n return this.core.getPublicKey();\n }\n\n /**\n * Get the encryption key (32 bytes derived from signature)\n */\n getEncryptionKey(): Buffer {\n return this.core.getEncryptionKey();\n }\n\n /**\n * Reset all data (files, contacts, knowledge bases)\n * WARNING: This will delete all user data from Aleph\n */\n async resetAllData(): Promise<void> {\n await Promise.all([this.resetFiles(), this.resetContacts(), this.resetKnowledgeBases()]);\n }\n\n /**\n * Reset all files\n * WARNING: This will delete all files from Aleph\n */\n async resetFiles(): Promise<void> {\n const aleph = this.core.getAlephService();\n await aleph.createAggregate(AGGREGATE_KEYS.FILE_ENTRIES, [] as any);\n }\n\n /**\n * Reset all contacts\n * WARNING: This will delete all contacts\n */\n async resetContacts(): Promise<void> {\n const aleph = this.core.getAlephService();\n await aleph.createAggregate(AGGREGATE_KEYS.CONTACTS, [] as any);\n }\n\n /**\n * Reset all knowledge bases\n * WARNING: This will delete all knowledge bases\n */\n async resetKnowledgeBases(): Promise<void> {\n const aleph = this.core.getAlephService();\n await aleph.createAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, [] as any);\n }\n\n // ============================================================================\n // Private methods\n // ============================================================================\n\n /**\n * Setup all services (create aggregates if they don't exist)\n */\n private async setup(): Promise<void> {\n await Promise.all([this.files.setup(), this.contacts.setup(), this.knowledgeBases.setup()]);\n }\n}\n\n// Re-export AGGREGATE_KEYS for use in reset methods\nimport { AGGREGATE_KEYS } from './types/schemas';\n","/**\n * Bedrock SDK - TypeScript SDK for Bedrock decentralized cloud storage\n * powered by Aleph\n *\n * @packageDocumentation\n */\n\n// Main client\nexport { BedrockClient } from './bedrock-client';\n\n// Core classes\nexport { BedrockCore, BedrockCoreConfig } from './client/bedrock-core';\nexport { AlephService } from './client/aleph-service';\n\n// Services\nexport { FileService, FileInput } from './services/file-service';\nexport { ContactService } from './services/contact-service';\nexport { KnowledgeBaseService } from './services/knowledge-base-service';\nexport { CreditService } from './services/credit-service';\n\n// Encryption\nexport { EncryptionService, CryptoUtils } from './crypto/encryption';\n\n// Types and schemas\nexport {\n // Constants\n BEDROCK_MESSAGE,\n SECURITY_AGGREGATE_KEY,\n ALEPH_GENERAL_CHANNEL,\n AGGREGATE_KEYS,\n POST_TYPES,\n\n // File types\n FileEntry,\n FileMeta,\n FileMetaEncrypted,\n FileFullInfo,\n FileEntrySchema,\n FileMetaSchema,\n FileMetaEncryptedSchema,\n FileEntriesAggregateSchema,\n\n // Public file types\n PublicFileMeta,\n PublicFileMetaSchema,\n\n // Contact types\n Contact,\n ContactSchema,\n ContactsAggregate,\n ContactsAggregateSchema,\n\n // Knowledge base types\n KnowledgeBase,\n KnowledgeBaseSchema,\n KnowledgeBasesAggregate,\n KnowledgeBasesAggregateSchema,\n\n // Credit types\n UserCredit,\n CreditTransaction,\n CreditAggregate,\n UserCreditSchema,\n CreditTransactionSchema,\n CreditAggregateSchema,\n\n // Security types\n SecurityAggregate,\n SecurityAggregateSchema,\n\n // Aleph message types\n AlephPostContent,\n AlephAggregateContent,\n AlephStoreMessage,\n AlephMessage,\n\n // Schema helpers\n HexString64Schema,\n HexString32Schema,\n DatetimeSchema,\n AddressSchema,\n} from './types/schemas';\n\n// Errors\nexport {\n BedrockError,\n AuthenticationError,\n EncryptionError,\n FileError,\n FileNotFoundError,\n ContactError,\n KnowledgeBaseError,\n CreditError,\n NetworkError,\n ValidationError,\n} from './types/errors';\n\n// Re-export Aleph SDK types for convenience\nexport type { Account } from '@aleph-sdk/account';\nexport { ETHAccount } from '@aleph-sdk/ethereum';\nexport { AlephHttpClient, AuthenticatedAlephHttpClient } from '@aleph-sdk/client';\n"],"mappings":"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","names":["AuthenticatedAlephHttpClient","z","z","AuthenticatedAlephHttpClient","ETHAccount","AlephHttpClient","AuthenticatedAlephHttpClient"]}
1
+ {"version":3,"sources":["../src/client/bedrock-core.ts","../src/types/errors.ts","../src/types/schemas.ts","../src/client/aleph-service.ts","../src/services/file-service.ts","../src/crypto/encryption.ts","../src/services/contact-service.ts","../src/services/knowledge-base-service.ts","../src/services/credit-service.ts","../src/bedrock-client.ts","../src/index.ts"],"sourcesContent":["import { AuthenticatedAlephHttpClient } from '@aleph-sdk/client';\nimport { ETHAccount, getAccountFromProvider, importAccountFromPrivateKey } from '@aleph-sdk/ethereum';\nimport { PrivateKey } from 'eciesjs';\nimport web3 from 'web3';\nimport { AuthenticationError } from '../types/errors';\nimport { ALEPH_GENERAL_CHANNEL, BEDROCK_MESSAGE, SECURITY_AGGREGATE_KEY } from '../types/schemas';\nimport { AlephService } from './aleph-service';\n\n/**\n * Configuration for BedrockCore\n */\nexport interface BedrockCoreConfig {\n channel?: string;\n apiServer?: string;\n}\n\n/**\n * Core Bedrock functionality: authentication, sub-accounts, encryption key derivation\n */\nexport class BedrockCore {\n private readonly mainAccount: ETHAccount;\n private readonly subAccount: ETHAccount;\n private readonly alephService: AlephService;\n private readonly encryptionPrivateKey: PrivateKey;\n\n private constructor(\n mainAccount: ETHAccount,\n subAccount: ETHAccount,\n alephService: AlephService,\n encryptionPrivateKey: PrivateKey,\n _config: Required<BedrockCoreConfig>\n ) {\n this.mainAccount = mainAccount;\n this.subAccount = subAccount;\n this.alephService = alephService;\n this.encryptionPrivateKey = encryptionPrivateKey;\n }\n\n /**\n * Initialize from signature hash (matches Bedrock app pattern)\n * @param signatureHash - Signature hash from wallet\n * @param provider - EIP-1193 provider (for MetaMask/Rabby)\n * @param config - Optional configuration\n */\n static async fromSignature(signatureHash: string, provider: any, config?: BedrockCoreConfig): Promise<BedrockCore> {\n try {\n const cfg = {\n channel: config?.channel || ALEPH_GENERAL_CHANNEL,\n apiServer: config?.apiServer || 'https://api2.aleph.im',\n };\n\n // Derive private key from signature\n const privateKey = web3.utils.sha3(signatureHash);\n if (!privateKey) {\n throw new AuthenticationError('Failed to derive private key from signature');\n }\n\n // Create encryption private key\n const encryptionPrivateKey = PrivateKey.fromHex(privateKey);\n\n // Get main account from provider\n // Handle different wallet types like the old service did\n let mainAccount: ETHAccount;\n\n if (provider?.id && ['io.rabby', 'io.metamask'].includes(provider.id)) {\n // For Rabby and MetaMask, use window.ethereum directly\n if (typeof window !== 'undefined' && (window as any).ethereum) {\n mainAccount = await getAccountFromProvider((window as any).ethereum);\n } else {\n throw new AuthenticationError('window.ethereum not available');\n }\n } else {\n // For other wallets or standard EIP-1193 providers\n mainAccount = await getAccountFromProvider(provider);\n }\n\n // Create sub-account\n const subAccount = importAccountFromPrivateKey(privateKey);\n\n // Setup security permissions\n await BedrockCore.setupSecurityPermissions(mainAccount, subAccount, cfg);\n\n // Create AlephService\n const alephService = new AlephService(subAccount, cfg.channel, cfg.apiServer);\n\n return new BedrockCore(mainAccount, subAccount, alephService, encryptionPrivateKey, cfg);\n } catch (error) {\n throw new AuthenticationError(`Failed to initialize from signature: ${(error as Error).message}`);\n }\n }\n\n /**\n * Create BedrockCore from a private key (for testing/CLI)\n * @param privateKey - Ethereum private key (hex string with or without 0x prefix)\n * @param config - Optional configuration\n */\n static async fromPrivateKey(privateKey: string, config?: BedrockCoreConfig): Promise<BedrockCore> {\n try {\n const cfg = {\n channel: config?.channel || ALEPH_GENERAL_CHANNEL,\n apiServer: config?.apiServer || 'https://api2.aleph.im',\n };\n\n // Ensure 0x prefix\n const key = privateKey.startsWith('0x') ? privateKey : `0x${privateKey}`;\n\n // Create main account\n const mainAccount = importAccountFromPrivateKey(key);\n\n // For private key, we simulate signing by hashing the key + message\n const signatureHash = web3.utils.sha3(key + BEDROCK_MESSAGE);\n if (!signatureHash) {\n throw new AuthenticationError('Failed to derive signature');\n }\n\n const subPrivateKey = web3.utils.sha3(signatureHash);\n if (!subPrivateKey) {\n throw new AuthenticationError('Failed to derive sub-account key');\n }\n\n // Create encryption private key\n const encryptionPrivateKey = PrivateKey.fromHex(subPrivateKey);\n\n // Create sub-account\n const subAccount = importAccountFromPrivateKey(subPrivateKey);\n\n // Setup security permissions\n await BedrockCore.setupSecurityPermissions(mainAccount, subAccount, cfg);\n\n // Create AlephService\n const alephService = new AlephService(subAccount, cfg.channel, cfg.apiServer);\n\n return new BedrockCore(mainAccount, subAccount, alephService, encryptionPrivateKey, cfg);\n } catch (error) {\n throw new AuthenticationError(`Failed to import account: ${(error as Error).message}`);\n }\n }\n\n /**\n * Create BedrockCore from a wallet provider (e.g., MetaMask)\n * This will automatically request signature from the user\n * @param provider - EIP-1193 provider\n * @param config - Optional configuration\n */\n static async fromProvider(provider: any, config?: BedrockCoreConfig): Promise<BedrockCore> {\n try {\n // Request signature from user\n const accounts = await provider.request({ method: 'eth_requestAccounts' });\n if (!accounts || accounts.length === 0) {\n throw new AuthenticationError('No accounts found');\n }\n\n // Request signature\n const signature = await provider.request({\n method: 'personal_sign',\n params: [BEDROCK_MESSAGE, accounts[0]],\n });\n\n return await BedrockCore.fromSignature(signature, provider, config);\n } catch (error) {\n throw new AuthenticationError(`Failed to connect to provider: ${(error as Error).message}`);\n }\n }\n\n /**\n * Get the main account\n */\n getMainAccount(): ETHAccount {\n return this.mainAccount;\n }\n\n /**\n * Get the sub-account\n */\n getSubAccount(): ETHAccount {\n return this.subAccount;\n }\n\n /**\n * Get the AlephService instance\n */\n getAlephService(): AlephService {\n return this.alephService;\n }\n\n /**\n * Get the encryption key\n */\n getEncryptionKey(): Buffer {\n return Buffer.from(this.encryptionPrivateKey.secret);\n }\n\n /**\n * Get the encryption private key\n */\n getEncryptionPrivateKey(): PrivateKey {\n return this.encryptionPrivateKey;\n }\n\n /**\n * Get the main account's address\n */\n getMainAddress(): string {\n return this.mainAccount.address;\n }\n\n /**\n * Get the sub-account's address\n */\n getSubAddress(): string {\n return this.subAccount.address;\n }\n\n /**\n * Get the main account's public key\n */\n getPublicKey(): string {\n // Use encryption private key's compressed public key (matches old service)\n // This is derived from the signature and is consistent\n return this.encryptionPrivateKey.publicKey.compressed.toString('hex');\n }\n\n /**\n * Get the sub-account's private key (as hex string)\n */\n getSubAccountPrivateKey(): string {\n return this.encryptionPrivateKey.toHex();\n }\n\n // ============================================================================\n // Static helper methods\n // ============================================================================\n\n /**\n * Setup security permissions (matches Bedrock app pattern)\n */\n private static async setupSecurityPermissions(\n mainAccount: ETHAccount,\n subAccount: ETHAccount,\n config: Required<BedrockCoreConfig>\n ): Promise<void> {\n try {\n const accountClient = new AuthenticatedAlephHttpClient(mainAccount, config.apiServer);\n\n try {\n // Fetch existing security aggregate\n const securitySettings = (await accountClient.fetchAggregate(\n mainAccount.address,\n SECURITY_AGGREGATE_KEY\n )) as any;\n\n // Check if sub-account is already authorized\n const authorizations = securitySettings?.authorizations || [];\n const isAuthorized = authorizations.find(\n (auth: any) =>\n auth.address === subAccount.address && auth.types === undefined && auth.channels?.includes(config.channel)\n );\n\n if (!isAuthorized) {\n // Remove old authorizations for this sub-account and add new one\n const oldAuthorizations = authorizations.filter((a: any) => a.address !== subAccount.address);\n\n await accountClient.createAggregate({\n key: SECURITY_AGGREGATE_KEY,\n content: {\n authorizations: [\n ...oldAuthorizations,\n {\n address: subAccount.address,\n channels: [config.channel],\n },\n ],\n },\n });\n }\n } catch (_error) {\n // Security aggregate does not exist, create a new one\n await accountClient.createAggregate({\n key: SECURITY_AGGREGATE_KEY,\n content: {\n authorizations: [\n {\n address: subAccount.address,\n channels: [config.channel],\n },\n ],\n },\n });\n }\n } catch (error) {\n throw new AuthenticationError(`Failed to setup security permissions: ${(error as Error).message}`);\n }\n }\n}\n","/**\n * Base error class for Bedrock SDK\n */\nexport class BedrockError extends Error {\n constructor(\n message: string,\n public code?: string\n ) {\n super(message);\n this.name = 'BedrockError';\n Object.setPrototypeOf(this, BedrockError.prototype);\n }\n}\n\n/**\n * Authentication/authorization errors\n */\nexport class AuthenticationError extends BedrockError {\n constructor(message: string) {\n super(message, 'AUTH_ERROR');\n this.name = 'AuthenticationError';\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Encryption/decryption errors\n */\nexport class EncryptionError extends BedrockError {\n constructor(message: string) {\n super(message, 'ENCRYPTION_ERROR');\n this.name = 'EncryptionError';\n Object.setPrototypeOf(this, EncryptionError.prototype);\n }\n}\n\n/**\n * File operation errors\n */\nexport class FileError extends BedrockError {\n constructor(message: string) {\n super(message, 'FILE_ERROR');\n this.name = 'FileError';\n Object.setPrototypeOf(this, FileError.prototype);\n }\n}\n\n/**\n * File not found error\n */\nexport class FileNotFoundError extends FileError {\n constructor(path: string) {\n super(`File not found: ${path}`);\n this.name = 'FileNotFoundError';\n this.code = 'FILE_NOT_FOUND';\n Object.setPrototypeOf(this, FileNotFoundError.prototype);\n }\n}\n\n/**\n * Contact-related errors\n */\nexport class ContactError extends BedrockError {\n constructor(message: string) {\n super(message, 'CONTACT_ERROR');\n this.name = 'ContactError';\n Object.setPrototypeOf(this, ContactError.prototype);\n }\n}\n\n/**\n * Knowledge base errors\n */\nexport class KnowledgeBaseError extends BedrockError {\n constructor(message: string) {\n super(message, 'KB_ERROR');\n this.name = 'KnowledgeBaseError';\n Object.setPrototypeOf(this, KnowledgeBaseError.prototype);\n }\n}\n\n/**\n * Credit-related errors\n */\nexport class CreditError extends BedrockError {\n constructor(message: string) {\n super(message, 'CREDIT_ERROR');\n this.name = 'CreditError';\n Object.setPrototypeOf(this, CreditError.prototype);\n }\n}\n\n/**\n * Network/Aleph API errors\n */\nexport class NetworkError extends BedrockError {\n constructor(message: string) {\n super(message, 'NETWORK_ERROR');\n this.name = 'NetworkError';\n Object.setPrototypeOf(this, NetworkError.prototype);\n }\n}\n\n/**\n * Validation errors\n */\nexport class ValidationError extends BedrockError {\n constructor(message: string) {\n super(message, 'VALIDATION_ERROR');\n this.name = 'ValidationError';\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n}\n","import { z } from 'zod';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nexport const BEDROCK_MESSAGE = 'Bedrock.im';\nexport const SECURITY_AGGREGATE_KEY = 'security';\nexport const ALEPH_GENERAL_CHANNEL = 'BEDROCK_STORAGE';\n\nexport const AGGREGATE_KEYS = {\n FILE_ENTRIES: 'bedrock_file_entries',\n CONTACTS: 'bedrock_contacts',\n KNOWLEDGE_BASES: 'bedrock_knowledge_bases',\n CREDITS: 'credits',\n} as const;\n\nexport const POST_TYPES = {\n FILE: 'bedrock_file',\n PUBLIC_FILE: 'bedrock_public_file',\n} as const;\n\n// ============================================================================\n// Base Schemas\n// ============================================================================\n\n/**\n * 64-character hex string (32 bytes)\n */\nexport const HexString64Schema = z\n .string()\n .length(64)\n .regex(/^[0-9a-f]{64}$/);\n\n/**\n * 32-character hex string (16 bytes)\n */\nexport const HexString32Schema = z\n .string()\n .length(32)\n .regex(/^[0-9a-f]{32}$/);\n\n/**\n * ISO 8601 datetime string\n */\nexport const DatetimeSchema = z.string().datetime();\n\n/**\n * Ethereum address\n */\nexport const AddressSchema = z.string().regex(/^0x[a-fA-F0-9]{40}$/);\n\n// ============================================================================\n// File Schemas\n// ============================================================================\n\n/**\n * File entry in the file index aggregate\n */\nexport const FileEntrySchema = z.object({\n path: z.string(), // Encrypted path\n post_hash: HexString64Schema,\n shared_with: z.array(z.string()).default([]), // Public keys of contacts\n});\n\nexport type FileEntry = z.infer<typeof FileEntrySchema>;\n\n/**\n * File metadata stored in POST messages\n */\nexport const FileMetaEncryptedSchema = z.object({\n name: z.string(), // Encrypted filename\n path: z.string(), // Encrypted path\n key: z.string(), // Encrypted AES key (ECIES encrypted)\n iv: z.string(), // Encrypted IV (ECIES encrypted)\n store_hash: z.string(), // Encrypted Aleph STORE hash\n size: z.string(), // Encrypted size\n created_at: z.string(), // Encrypted datetime\n deleted_at: z.string().nullable(), // Encrypted datetime or null\n shared_keys: z\n .record(\n z.string(),\n z.object({\n key: z.string(), // Encrypted key for recipient\n iv: z.string(), // Encrypted IV for recipient\n })\n )\n .default({}),\n});\n\nexport type FileMetaEncrypted = z.infer<typeof FileMetaEncryptedSchema>;\n\n/**\n * Decrypted file metadata\n */\nexport const FileMetaSchema = z.object({\n name: z.string(),\n path: z.string(),\n key: HexString64Schema,\n iv: HexString32Schema,\n store_hash: HexString64Schema,\n size: z.number(),\n created_at: DatetimeSchema,\n deleted_at: DatetimeSchema.nullable(),\n shared_keys: z\n .record(\n z.string(),\n z.object({\n key: HexString64Schema,\n iv: HexString32Schema,\n })\n )\n .default({}),\n});\n\nexport type FileMeta = z.infer<typeof FileMetaSchema>;\n\n/**\n * Combined file entry and metadata\n */\nexport type FileFullInfo = FileEntry & FileMeta;\n\n/**\n * Public file metadata (unencrypted, accessible by anyone)\n */\nexport const PublicFileMetaSchema = z.object({\n name: z.string(),\n size: z.number(),\n created_at: DatetimeSchema,\n store_hash: HexString64Schema,\n username: z.string(),\n});\n\nexport type PublicFileMeta = z.infer<typeof PublicFileMetaSchema>;\n\n// ============================================================================\n// Contact Schemas\n// ============================================================================\n\n/**\n * Contact information\n */\nexport const ContactSchema = z.object({\n name: z.string(),\n address: AddressSchema,\n public_key: z.string(), // Hex-encoded public key\n});\n\nexport type Contact = z.infer<typeof ContactSchema>;\n\n/**\n * Contacts aggregate\n */\nexport const ContactsAggregateSchema = z.object({\n contacts: z.array(ContactSchema).default([]),\n});\n\nexport type ContactsAggregate = z.infer<typeof ContactsAggregateSchema>;\n\n// ============================================================================\n// Knowledge Base Schemas\n// ============================================================================\n\n/**\n * Knowledge base configuration\n */\nexport const KnowledgeBaseSchema = z.object({\n name: z.string(),\n file_paths: z.array(z.string()).default([]), // Encrypted paths\n created_at: DatetimeSchema,\n updated_at: DatetimeSchema,\n});\n\nexport type KnowledgeBase = z.infer<typeof KnowledgeBaseSchema>;\n\n/**\n * Knowledge bases aggregate\n */\nexport const KnowledgeBasesAggregateSchema = z.object({\n knowledge_bases: z.array(KnowledgeBaseSchema).default([]),\n});\n\nexport type KnowledgeBasesAggregate = z.infer<typeof KnowledgeBasesAggregateSchema>;\n\n// ============================================================================\n// Credit Schemas\n// ============================================================================\n\n/**\n * Credit transaction record\n */\nexport const CreditTransactionSchema = z.object({\n id: z.string(),\n amount: z.number(),\n type: z.enum(['top_up', 'deduct']),\n timestamp: z.number(),\n description: z.string(),\n txHash: z.string().optional(),\n});\n\nexport type CreditTransaction = z.infer<typeof CreditTransactionSchema>;\n\n/**\n * User credit data\n */\nexport const UserCreditSchema = z.object({\n balance: z.number().default(0),\n transactions: z.array(CreditTransactionSchema).default([]),\n});\n\nexport type UserCredit = z.infer<typeof UserCreditSchema>;\n\n/**\n * Credit aggregate (backend-managed)\n */\nexport const CreditAggregateSchema = z.record(z.string(), UserCreditSchema);\n\nexport type CreditAggregate = z.infer<typeof CreditAggregateSchema>;\n\n// ============================================================================\n// File Entries Aggregate\n// ============================================================================\n\n/**\n * File entries aggregate\n */\nexport const FileEntriesAggregateSchema = z.object({\n files: z.array(FileEntrySchema).default([]),\n});\n\nexport type FileEntriesAggregate = z.infer<typeof FileEntriesAggregateSchema>;\n\n// ============================================================================\n// Security Aggregate\n// ============================================================================\n\n/**\n * Sub-account authorization in security aggregate\n */\nexport const SecurityAggregateSchema = z.object({\n authorizations: z.array(\n z.object({\n address: AddressSchema,\n chain: z.string(),\n channels: z.array(z.string()).optional(),\n post_types: z.array(z.string()).optional(),\n aggregate_keys: z.array(z.string()).optional(),\n })\n ),\n});\n\nexport type SecurityAggregate = z.infer<typeof SecurityAggregateSchema>;\n\n// ============================================================================\n// Aleph Message Types\n// ============================================================================\n\n/**\n * Aleph POST message content\n */\nexport interface AlephPostContent<T = unknown> {\n time: number;\n type: string;\n ref?: string;\n content: T;\n}\n\n/**\n * Aleph AGGREGATE content\n */\nexport interface AlephAggregateContent<T = unknown> {\n key: string;\n content: T;\n}\n\n/**\n * Aleph STORE message\n */\nexport interface AlephStoreMessage {\n item_hash: string;\n size: number;\n}\n\n/**\n * Generic Aleph message response\n */\nexport interface AlephMessage {\n chain: string;\n item_hash: string;\n sender: string;\n type: string;\n channel: string;\n confirmed: boolean;\n content: unknown;\n item_content: string;\n item_type: string;\n signature: string;\n size: number;\n time: number;\n}\n","import { AuthenticatedAlephHttpClient } from '@aleph-sdk/client';\nimport type { ETHAccount } from '@aleph-sdk/ethereum';\nimport { AggregateMessage, ForgetMessage, ItemType, PostMessage, StoreMessage } from '@aleph-sdk/message';\nimport { z } from 'zod';\nimport { NetworkError } from '../types/errors';\nimport { ALEPH_GENERAL_CHANNEL } from '../types/schemas';\n\n/**\n * Low-level Aleph SDK wrapper (matches Bedrock implementation)\n */\nexport class AlephService {\n private readonly subAccountClient: AuthenticatedAlephHttpClient;\n private readonly account: ETHAccount;\n private readonly channel: string;\n\n constructor(\n account: ETHAccount,\n channel: string = ALEPH_GENERAL_CHANNEL,\n apiServer: string = 'https://api2.aleph.im'\n ) {\n this.account = account;\n this.channel = channel;\n this.subAccountClient = new AuthenticatedAlephHttpClient(account, apiServer);\n }\n\n /**\n * Get the account address\n */\n getAddress(): string {\n return this.account.address;\n }\n\n /**\n * Get the account's public key\n */\n getPublicKey(): string {\n return this.account.publicKey || '';\n }\n\n /**\n * Get the underlying Aleph client\n */\n getClient(): AuthenticatedAlephHttpClient {\n return this.subAccountClient;\n }\n\n /**\n * Get the account\n */\n getAccount(): ETHAccount {\n return this.account;\n }\n\n // ============================================================================\n // STORE operations (file storage)\n // ============================================================================\n\n /**\n * Upload a file to Aleph storage\n * @param fileObject - File content as Buffer or File\n * @returns Store message\n */\n async uploadFile(fileObject: Buffer | File): Promise<StoreMessage> {\n try {\n return await this.subAccountClient.createStore({\n fileObject,\n storageEngine: ItemType.ipfs,\n channel: this.channel,\n });\n } catch (error) {\n throw new NetworkError(`Failed to upload file: ${(error as Error).message}`);\n }\n }\n\n /**\n * Download a file from Aleph storage\n * @param storeHash - The STORE message item_hash\n * @returns File content as ArrayBuffer\n */\n async downloadFile(storeHash: string): Promise<ArrayBuffer> {\n try {\n const ipfsHash = await this.subAccountClient.getMessage(storeHash);\n const ContentSchema = z.object({\n address: z.string(),\n item_type: z.string(),\n item_hash: z.string(),\n time: z.number(),\n });\n const { success, data } = ContentSchema.safeParse(ipfsHash.content);\n if (!success) throw new Error(`Invalid data from Aleph: ${data}`);\n return this.subAccountClient.downloadFile(data.item_hash);\n } catch (error) {\n throw new NetworkError(`Failed to download file ${storeHash}: ${(error as Error).message}`);\n }\n }\n\n /**\n * Delete files from Aleph storage\n * @param itemHashes - Array of item hashes to forget\n * @returns Forget message\n */\n async deleteFiles(itemHashes: string[]): Promise<ForgetMessage> {\n try {\n return this.subAccountClient.forget({ hashes: itemHashes });\n } catch (error) {\n throw new NetworkError(`Failed to delete files: ${(error as Error).message}`);\n }\n }\n\n // ============================================================================\n // AGGREGATE operations (key-value storage)\n // ============================================================================\n\n async createAggregate<T extends Record<string, unknown>>(key: string, content: T): Promise<AggregateMessage<T>> {\n try {\n return this.subAccountClient.createAggregate({\n key,\n content,\n channel: this.channel,\n address: this.account.address,\n });\n } catch (error) {\n throw new NetworkError(`Failed to create aggregate: ${(error as Error).message}`);\n }\n }\n\n async fetchAggregate<T extends z.ZodTypeAny>(key: string, schema: T, owner: string = this.account.address) {\n try {\n const unparsedData = await this.subAccountClient.fetchAggregate(owner, key);\n const { success, data, error } = schema.safeParse(unparsedData);\n if (!success)\n throw new Error(`Invalid data from Aleph: ${error.message}, data was ${JSON.stringify(unparsedData)}`);\n return data as z.infer<T>;\n } catch (error) {\n throw new NetworkError(`Failed to fetch aggregate: ${(error as Error).message}`);\n }\n }\n\n async updateAggregate<S extends z.ZodTypeAny, T extends z.infer<S>>(\n key: string,\n schema: S,\n update_content: (content: T) => Promise<T>\n ): Promise<AggregateMessage<T>> {\n try {\n const currentContent = await this.fetchAggregate(key, schema);\n const newContent = await update_content(currentContent);\n return await this.createAggregate(key, newContent);\n } catch (error) {\n throw new NetworkError(`Failed to update aggregate: ${(error as Error).message}`);\n }\n }\n\n // ============================================================================\n // POST operations (JSON messages)\n // ============================================================================\n\n async createPost<T extends Record<string, unknown>>(type: string, content: T): Promise<PostMessage<T>> {\n try {\n return this.subAccountClient.createPost({\n postType: type,\n content,\n channel: this.channel,\n address: this.account.address,\n });\n } catch (error) {\n throw new NetworkError(`Failed to create post: ${(error as Error).message}`);\n }\n }\n\n async fetchPosts<T extends z.ZodTypeAny>(\n type: string,\n schema: T,\n addresses: string[] = [this.account.address],\n hashes: string[] = []\n ) {\n try {\n return z.array(schema).parse(\n (\n await this.subAccountClient.getPosts({\n channels: [this.channel],\n types: [type],\n addresses,\n hashes,\n })\n ).posts.map((post) => post.content)\n ) as z.infer<T>[];\n } catch (error) {\n throw new NetworkError(`Failed to fetch posts: ${(error as Error).message}`);\n }\n }\n\n async fetchPost<T extends z.ZodTypeAny>(\n type: string,\n schema: T,\n addresses: string[] = [this.account.address],\n hash: string\n ) {\n try {\n return schema.parse(\n (\n await this.subAccountClient.getPost({\n channels: [this.channel],\n types: [type],\n addresses,\n hashes: [hash],\n })\n ).content\n ) as z.infer<T>;\n } catch (error) {\n throw new NetworkError(`Failed to fetch post: ${(error as Error).message}`);\n }\n }\n\n async updatePost<S extends z.ZodTypeAny, T extends z.infer<S>>(\n type: string,\n hash: string,\n addresses: string[],\n schema: S,\n update_content: (content: T) => Promise<T>\n ): Promise<PostMessage<T>> {\n try {\n const currentContent = await this.fetchPost(type, schema, addresses, hash);\n const newContent = await update_content(currentContent);\n return await this.subAccountClient.createPost({\n postType: type,\n content: newContent,\n ref: hash,\n channel: this.channel,\n address: this.account.address,\n });\n } catch (error) {\n throw new NetworkError(`Failed to update post: ${(error as Error).message}`);\n }\n }\n}\n","import { AlephHttpClient } from '@aleph-sdk/client';\nimport { BedrockCore } from '../client/bedrock-core';\nimport { EncryptionService } from '../crypto/encryption';\nimport { EncryptionError, FileError, FileNotFoundError } from '../types/errors';\nimport {\n AGGREGATE_KEYS,\n ALEPH_GENERAL_CHANNEL,\n FileEntriesAggregateSchema,\n FileEntry,\n FileFullInfo,\n FileMeta,\n FileMetaEncryptedSchema,\n POST_TYPES,\n PublicFileMeta,\n PublicFileMetaSchema,\n} from '../types/schemas';\n\n/**\n * File input type for uploads\n */\nexport interface FileInput {\n name: string;\n path: string;\n content: Buffer | File;\n}\n\n/**\n * File service for managing encrypted files\n */\nexport class FileService {\n private readonly core: BedrockCore;\n\n constructor(core: BedrockCore) {\n this.core = core;\n }\n\n /**\n * Initialize file entries aggregate if it doesn't exist\n */\n async setup(): Promise<void> {\n const aleph = this.core.getAlephService();\n\n try {\n await aleph.fetchAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema);\n } catch {\n // Create empty aggregate if it doesn't exist\n await aleph.createAggregate(AGGREGATE_KEYS.FILE_ENTRIES, { files: [] });\n }\n }\n\n /**\n * Upload files with encryption\n * @param files - Array of files to upload\n * @param directoryPath - Optional directory path prefix\n * @returns Array of uploaded file info\n */\n async uploadFiles(files: FileInput[], directoryPath: string = ''): Promise<FileFullInfo[]> {\n const aleph = this.core.getAlephService();\n const publicKey = this.core.getPublicKey();\n const uploadedFiles: FileFullInfo[] = [];\n const existingFiles = await this.listFiles();\n\n const filesToUpload = files.filter((file) => {\n const filterIn = !existingFiles.some(\n (existingFile) =>\n !existingFile.deleted_at && existingFile.path === (directoryPath ? `${directoryPath}${file.path}` : file.path)\n );\n console.log(`Keeping ${file} in ? ${filterIn ? 'yes' : 'no'}`);\n return filterIn;\n });\n\n try {\n for (const file of filesToUpload) {\n // Generate encryption key and IV\n const key = EncryptionService.generateKey();\n const iv = EncryptionService.generateIv();\n\n // Encrypt file content\n let fileBuffer: Buffer;\n if (file.content instanceof Buffer) {\n fileBuffer = file.content;\n } else {\n // It's a File object\n const arrayBuffer = await (file.content as File).arrayBuffer();\n fileBuffer = Buffer.from(arrayBuffer);\n }\n const encryptedContent = await EncryptionService.encryptFile(fileBuffer, key, iv);\n\n // Upload encrypted file to Aleph STORE\n const storeResult = await aleph.uploadFile(encryptedContent);\n\n // Prepare file metadata\n const fullPath = directoryPath ? `${directoryPath}${file.path}` : file.path;\n const createdAt = new Date().toISOString();\n\n const fileMeta: FileMeta = {\n name: file.name,\n path: fullPath,\n key: key.toString('hex'),\n iv: iv.toString('hex'),\n store_hash: storeResult.item_hash,\n size: fileBuffer.length,\n created_at: createdAt,\n deleted_at: null,\n shared_keys: {},\n };\n\n // Encrypt metadata\n const encryptedMeta = await this.encryptFileMeta(fileMeta);\n\n // Create POST message with encrypted metadata\n const postResult = await aleph.createPost(POST_TYPES.FILE, encryptedMeta);\n\n // Create file entry\n const encryptedPath = EncryptionService.encryptEcies(fullPath, publicKey);\n const fileEntry: FileEntry = {\n path: encryptedPath,\n post_hash: postResult.item_hash,\n shared_with: [],\n };\n\n uploadedFiles.push({ ...fileEntry, ...fileMeta });\n }\n\n // Save file entries to aggregate\n await this.saveFileEntries(uploadedFiles);\n\n return uploadedFiles;\n } catch (error) {\n throw new FileError(`Failed to upload files: ${(error as Error).message}`);\n }\n }\n\n async editFileContent(fileInfo: FileFullInfo, newContent: Buffer): Promise<FileFullInfo> {\n const aleph = this.core.getAlephService();\n const privateKey = this.core.getSubAccountPrivateKey();\n try {\n const postResult = await aleph.updatePost(\n POST_TYPES.FILE,\n fileInfo.post_hash,\n [aleph.getAddress()],\n FileMetaEncryptedSchema,\n async (encryptedMeta) => {\n const decryptedMeta = await this.decryptFileMeta(encryptedMeta);\n const encryptedContent = await EncryptionService.encryptFile(\n newContent,\n Buffer.from(decryptedMeta.key, 'hex'),\n Buffer.from(decryptedMeta.iv, 'hex')\n );\n const uploadResult = await aleph.uploadFile(encryptedContent);\n decryptedMeta.store_hash = uploadResult.item_hash;\n fileInfo.store_hash = decryptedMeta.store_hash;\n return await this.encryptFileMeta(decryptedMeta);\n }\n );\n fileInfo.post_hash = postResult.item_hash;\n await aleph.updateAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema, async (aggregate) => ({\n files: aggregate.files.map((entry) =>\n fileInfo.path === EncryptionService.decryptEcies(entry.path, privateKey)\n ? { ...entry, post_hash: fileInfo.post_hash }\n : entry\n ),\n }));\n return fileInfo;\n } catch (error) {\n throw new FileError(`Failed to edit file's content: ${(error as Error).message}`);\n }\n }\n\n /**\n * Download and decrypt a file\n * @param fileInfo - File information\n * @returns Decrypted file buffer\n */\n async downloadFile(fileInfo: FileFullInfo): Promise<Buffer> {\n const aleph = this.core.getAlephService();\n\n try {\n const key = Buffer.from(fileInfo.key, 'hex');\n const iv = Buffer.from(fileInfo.iv, 'hex');\n\n // Download encrypted file\n const encryptedContent = await aleph.downloadFile(fileInfo.store_hash);\n\n // Decrypt file\n const decryptedContent = await EncryptionService.decryptFile(encryptedContent, key, iv);\n\n return decryptedContent;\n } catch (error) {\n throw new FileError(`Failed to download file: ${(error as Error).message}`);\n }\n }\n\n /**\n * Fetch all file entries\n */\n async fetchFileEntries(): Promise<FileEntry[]> {\n const aleph = this.core.getAlephService();\n const privateKey = this.core.getSubAccountPrivateKey();\n\n try {\n const aggregate = await aleph.fetchAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema);\n\n // Decrypt paths (they're stored encrypted)\n return aggregate.files.map(({ post_hash, path, shared_with }) => ({\n post_hash,\n path: EncryptionService.decryptEcies(path, privateKey),\n shared_with,\n }));\n } catch (error) {\n throw new FileError(`Failed to fetch file entries: ${(error as Error).message}`);\n }\n }\n\n /**\n * Fetch file metadata from entries\n * @param entries - File entries\n * @param owner - Optional owner address\n * @returns Array of full file info\n */\n async fetchFilesMetaFromEntries(entries: FileEntry[], owner?: string): Promise<FileFullInfo[]> {\n const aleph = this.core.getAlephService();\n const privateKey = owner ? undefined : this.core.getSubAccountPrivateKey();\n const files: FileFullInfo[] = [];\n\n try {\n for (const entry of entries) {\n try {\n // Fetch encrypted metadata from POST\n const encryptedMeta = await aleph.fetchPost(\n POST_TYPES.FILE,\n FileMetaEncryptedSchema,\n owner ? [owner] : undefined,\n entry.post_hash\n );\n\n // Decrypt metadata\n const decryptedMeta = await this.decryptFileMeta(encryptedMeta, privateKey);\n\n files.push({\n ...entry,\n ...decryptedMeta,\n });\n } catch (error) {\n // Skip files that can't be decrypted\n console.warn(`Failed to fetch metadata for ${entry.post_hash}:`, error);\n }\n }\n\n return files;\n } catch (error) {\n throw new FileError(`Failed to fetch files metadata: ${(error as Error).message}`);\n }\n }\n\n /**\n * List all files\n * @param includeDeleted - Include soft-deleted files\n */\n async listFiles(includeDeleted: boolean = false): Promise<FileFullInfo[]> {\n const entries = await this.fetchFileEntries();\n const files = await this.fetchFilesMetaFromEntries(entries);\n\n if (!includeDeleted) {\n return files.filter((f) => !f.deleted_at);\n }\n\n return files;\n }\n\n /**\n * Get a file by path\n * @param path - File path\n */\n async getFile(path: string): Promise<FileFullInfo> {\n const files = await this.listFiles(true);\n const file = files.find((f) => f.path === path);\n\n if (!file) {\n throw new FileNotFoundError(path);\n }\n\n return file;\n }\n\n /**\n * Soft delete files\n * @param filePaths - Paths of files to delete\n * @param deletionDate - Optional deletion date\n */\n async softDeleteFiles(filePaths: string[], deletionDate?: Date): Promise<void> {\n const aleph = this.core.getAlephService();\n const deletedAt = (deletionDate || new Date()).toISOString();\n\n try {\n for (const path of filePaths) {\n const file = await this.getFile(path);\n\n // Update metadata with deleted_at (creates new POST)\n const updatedPost = await aleph.updatePost(\n POST_TYPES.FILE,\n file.post_hash,\n [aleph.getAddress()],\n FileMetaEncryptedSchema,\n async (encryptedMeta) => {\n const decryptedMeta = await this.decryptFileMeta(encryptedMeta);\n decryptedMeta.deleted_at = deletedAt;\n return await this.encryptFileMeta(decryptedMeta);\n }\n );\n\n // Update aggregate with new post_hash\n await aleph.updateAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema, async (aggregate) => ({\n files: aggregate.files.map((entry) =>\n entry.post_hash === file.post_hash ? { ...entry, post_hash: updatedPost.item_hash } : entry\n ),\n }));\n }\n } catch (error) {\n throw new FileError(`Failed to soft delete files: ${(error as Error).message}`);\n }\n }\n\n /**\n * Restore soft-deleted files\n * @param filePaths - Paths of files to restore\n */\n async restoreFiles(filePaths: string[]): Promise<void> {\n const aleph = this.core.getAlephService();\n\n try {\n for (const path of filePaths) {\n const file = await this.getFile(path);\n\n // Update metadata to remove deleted_at (creates new POST)\n const updatedPost = await aleph.updatePost(\n POST_TYPES.FILE,\n file.post_hash,\n [aleph.getAddress()],\n FileMetaEncryptedSchema,\n async (encryptedMeta) => {\n const decryptedMeta = await this.decryptFileMeta(encryptedMeta);\n decryptedMeta.deleted_at = null;\n return await this.encryptFileMeta(decryptedMeta);\n }\n );\n\n // Update aggregate with new post_hash\n await aleph.updateAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema, async (aggregate) => ({\n files: aggregate.files.map((entry) =>\n entry.post_hash === file.post_hash ? { ...entry, post_hash: updatedPost.item_hash } : entry\n ),\n }));\n }\n } catch (error) {\n throw new FileError(`Failed to restore files: ${(error as Error).message}`);\n }\n }\n\n /**\n * Hard delete files (permanently remove from Aleph)\n * @param filePaths - Paths of files to delete\n */\n async hardDeleteFiles(filePaths: string[]): Promise<void> {\n const aleph = this.core.getAlephService();\n\n try {\n const files = await Promise.all(filePaths.map((path) => this.getFile(path)));\n\n // Remove from file entries aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema, async (aggregate) => ({\n files: aggregate.files.filter((entry) => !files.some((f) => f.post_hash === entry.post_hash)),\n }));\n\n // Forget STORE and POST messages\n const hashesToForget = files.flatMap((f) => [f.store_hash, f.post_hash]);\n await aleph.deleteFiles(hashesToForget);\n } catch (error) {\n throw new FileError(`Failed to hard delete files: ${(error as Error).message}`);\n }\n }\n\n /**\n * Move/rename files\n * @param moves - Array of {oldPath, newPath} objects\n */\n async moveFiles(moves: Array<{ oldPath: string; newPath: string }>): Promise<void> {\n const aleph = this.core.getAlephService();\n const publicKey = this.core.getPublicKey();\n\n try {\n for (const { oldPath, newPath } of moves) {\n const file = await this.getFile(oldPath);\n\n // Update metadata with new path and name (creates new POST)\n const updatedPost = await aleph.updatePost(\n POST_TYPES.FILE,\n file.post_hash,\n [aleph.getAddress()],\n FileMetaEncryptedSchema,\n async (encryptedMeta) => {\n const decryptedMeta = await this.decryptFileMeta(encryptedMeta);\n decryptedMeta.path = newPath;\n decryptedMeta.name = newPath.split('/').pop() || newPath;\n return await this.encryptFileMeta(decryptedMeta);\n }\n );\n\n // Update file entry with new encrypted path and new post_hash\n const newEncryptedPath = EncryptionService.encryptEcies(newPath, publicKey);\n await aleph.updateAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema, async (aggregate) => ({\n files: aggregate.files.map((entry) =>\n entry.post_hash === file.post_hash\n ? { ...entry, path: newEncryptedPath, post_hash: updatedPost.item_hash }\n : entry\n ),\n }));\n }\n } catch (error) {\n throw new FileError(`Failed to move files: ${(error as Error).message}`);\n }\n }\n\n /**\n * Duplicate a file\n * @param sourcePath - Source file path\n * @param newPath - New file path\n */\n async duplicateFile(sourcePath: string, newPath: string): Promise<FileFullInfo> {\n try {\n const sourceFile = await this.getFile(sourcePath);\n const content = await this.downloadFile(sourceFile);\n\n const [newFile] = await this.uploadFiles([\n {\n name: newPath.split('/').pop() || newPath,\n path: newPath,\n content,\n },\n ]);\n\n return newFile;\n } catch (error) {\n throw new FileError(`Failed to duplicate file: ${(error as Error).message}`);\n }\n }\n\n /**\n * Share a file with a contact\n * @param filePath - File path\n * @param contactPublicKey - Contact's public key\n */\n async shareFile(filePath: string, contactPublicKey: string): Promise<void> {\n const aleph = this.core.getAlephService();\n\n try {\n const file = await this.getFile(filePath);\n\n // Encrypt file key and IV with contact's public key\n const encryptedKey = EncryptionService.encryptEcies(file.key, contactPublicKey);\n const encryptedIv = EncryptionService.encryptEcies(file.iv, contactPublicKey);\n\n // Update metadata with shared keys (creates new POST)\n const updatedPost = await aleph.updatePost(\n POST_TYPES.FILE,\n file.post_hash,\n [aleph.getAddress()],\n FileMetaEncryptedSchema,\n async (encryptedMeta) => {\n const decryptedMeta = await this.decryptFileMeta(encryptedMeta);\n decryptedMeta.shared_keys[contactPublicKey] = {\n key: encryptedKey,\n iv: encryptedIv,\n };\n return await this.encryptFileMeta(decryptedMeta);\n }\n );\n\n // Update file entry with new post_hash and shared_with list\n await aleph.updateAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema, async (aggregate) => ({\n files: aggregate.files.map((entry) =>\n entry.post_hash === file.post_hash\n ? {\n ...entry,\n post_hash: updatedPost.item_hash,\n shared_with: [...new Set([...entry.shared_with, contactPublicKey])],\n }\n : entry\n ),\n }));\n } catch (error) {\n throw new FileError(`Failed to share file: ${(error as Error).message}`);\n }\n }\n\n /**\n * Unshare a file with a contact\n * @param filePath - File path\n * @param contactPublicKey - Contact's public key\n */\n async unshareFile(filePath: string, contactPublicKey: string): Promise<void> {\n const aleph = this.core.getAlephService();\n\n try {\n const file = await this.getFile(filePath);\n\n // Remove shared keys from metadata (creates new POST)\n const updatedPost = await aleph.updatePost(\n POST_TYPES.FILE,\n file.post_hash,\n [aleph.getAddress()],\n FileMetaEncryptedSchema,\n async (encryptedMeta) => {\n const decryptedMeta = await this.decryptFileMeta(encryptedMeta);\n delete decryptedMeta.shared_keys[contactPublicKey];\n return await this.encryptFileMeta(decryptedMeta);\n }\n );\n\n // Update file entry with new post_hash and shared_with list\n await aleph.updateAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema, async (aggregate) => ({\n files: aggregate.files.map((entry) =>\n entry.post_hash === file.post_hash\n ? {\n ...entry,\n post_hash: updatedPost.item_hash,\n shared_with: entry.shared_with.filter((pk) => pk !== contactPublicKey),\n }\n : entry\n ),\n }));\n } catch (error) {\n throw new FileError(`Failed to unshare file: ${(error as Error).message}`);\n }\n }\n\n /**\n * Share a file publicly (unencrypted, anyone can access)\n * @param fileInfo - File to share publicly\n * @param username - Username for attribution\n * @returns Public post hash for sharing\n */\n async shareFilePublicly(fileInfo: FileFullInfo, username: string): Promise<string> {\n const aleph = this.core.getAlephService();\n\n try {\n // Download and decrypt file\n const decryptedContent = await this.downloadFile(fileInfo);\n\n // Re-upload without encryption\n const storeResult = await aleph.uploadFile(decryptedContent);\n\n // Create public metadata\n const publicMeta: PublicFileMeta = {\n name: fileInfo.name,\n size: fileInfo.size,\n created_at: new Date().toISOString(),\n store_hash: storeResult.item_hash,\n username,\n };\n\n // Create public POST\n const postResult = await aleph.createPost(POST_TYPES.PUBLIC_FILE, publicMeta);\n\n return postResult.item_hash;\n } catch (error) {\n throw new FileError(`Failed to share file publicly: ${(error as Error).message}`);\n }\n }\n\n /**\n * Fetch public file metadata (static - no auth required)\n * @param postHash - Public post hash\n * @returns Public file metadata or null if not found\n */\n static async fetchPublicFileMeta(postHash: string): Promise<PublicFileMeta | null> {\n try {\n const client = new AlephHttpClient('https://api2.aleph.im');\n const post = await client.getPost({\n channels: [ALEPH_GENERAL_CHANNEL],\n types: [POST_TYPES.PUBLIC_FILE],\n hashes: [postHash],\n });\n\n return PublicFileMetaSchema.parse(post.content);\n } catch {\n return null;\n }\n }\n\n /**\n * Download public file (static - no auth required)\n * @param storeHash - Store hash from public metadata\n * @returns File content as ArrayBuffer\n */\n static async downloadPublicFile(storeHash: string): Promise<ArrayBuffer> {\n try {\n const client = new AlephHttpClient('https://api2.aleph.im');\n return await client.downloadFile(storeHash);\n } catch (error) {\n throw new FileError(`Failed to download public file: ${(error as Error).message}`);\n }\n }\n\n // ============================================================================\n // Private helper methods\n // ============================================================================\n\n private async saveFileEntries(files: FileFullInfo[]): Promise<void> {\n const aleph = this.core.getAlephService();\n const publicKey = this.core.getPublicKey();\n\n await aleph.updateAggregate(AGGREGATE_KEYS.FILE_ENTRIES, FileEntriesAggregateSchema, async (aggregate) => {\n const newEntries = files.map((f) => ({\n path: EncryptionService.encryptEcies(f.path, publicKey),\n post_hash: f.post_hash,\n shared_with: f.shared_with || [],\n }));\n return { files: [...aggregate.files, ...newEntries] };\n });\n }\n\n private async encryptFileMeta(meta: FileMeta): Promise<any> {\n const publicKey = this.core.getPublicKey();\n\n // Use file's own key/iv for all encryption\n const fileKey = Buffer.from(meta.key, 'hex');\n const fileIv = Buffer.from(meta.iv, 'hex');\n\n return {\n name: await EncryptionService.encrypt(meta.name, fileKey, fileIv),\n path: await EncryptionService.encrypt(meta.path, fileKey, fileIv),\n key: EncryptionService.encryptEcies(meta.key, publicKey),\n iv: EncryptionService.encryptEcies(meta.iv, publicKey),\n store_hash: await EncryptionService.encrypt(meta.store_hash, fileKey, fileIv),\n size: await EncryptionService.encrypt(meta.size.toString(), fileKey, fileIv),\n created_at: await EncryptionService.encrypt(meta.created_at, fileKey, fileIv),\n deleted_at: await EncryptionService.encrypt(meta.deleted_at ?? 'null', fileKey, fileIv),\n shared_keys: meta.shared_keys,\n };\n }\n\n private async decryptFileMeta(encryptedMeta: any, privateKey?: string): Promise<FileMeta> {\n const privKey = privateKey || this.core.getSubAccountPrivateKey();\n\n if (!privKey) {\n throw new EncryptionError('Private key not available');\n }\n\n // Decrypt file key and IV first\n const decryptedKey = EncryptionService.decryptEcies(encryptedMeta.key, privKey);\n const decryptedIv = EncryptionService.decryptEcies(encryptedMeta.iv, privKey);\n const fileKey = Buffer.from(decryptedKey, 'hex');\n const fileIv = Buffer.from(decryptedIv, 'hex');\n\n const decryptedDeletedAt = await EncryptionService.decrypt(encryptedMeta.deleted_at, fileKey, fileIv);\n\n return {\n name: await EncryptionService.decrypt(encryptedMeta.name, fileKey, fileIv),\n path: await EncryptionService.decrypt(encryptedMeta.path, fileKey, fileIv),\n key: decryptedKey,\n iv: decryptedIv,\n store_hash: await EncryptionService.decrypt(encryptedMeta.store_hash, fileKey, fileIv),\n size: Number.parseInt(await EncryptionService.decrypt(encryptedMeta.size, fileKey, fileIv)),\n created_at: await EncryptionService.decrypt(encryptedMeta.created_at, fileKey, fileIv),\n deleted_at: decryptedDeletedAt === 'null' ? null : decryptedDeletedAt,\n shared_keys: encryptedMeta.shared_keys || {},\n };\n }\n}\n","import { encrypt as eciesEncrypt, decrypt as eciesDecrypt } from 'eciesjs';\nimport { EncryptionError } from '../types/errors';\n\n/**\n * Universal crypto utilities that work in both Node.js and browser\n */\nclass CryptoUtils {\n static isBrowser = typeof window !== 'undefined' && typeof window.crypto !== 'undefined';\n\n /**\n * Get crypto implementation (Node.js or browser)\n */\n static getCrypto() {\n if (this.isBrowser) {\n return window.crypto;\n }\n // Node.js\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const nodeCrypto = require('crypto');\n return nodeCrypto.webcrypto || nodeCrypto;\n }\n\n /**\n * Generate random bytes\n */\n static getRandomBytes(length: number): Uint8Array {\n const crypto = this.getCrypto();\n const bytes = new Uint8Array(length);\n\n if (this.isBrowser) {\n crypto.getRandomValues(bytes);\n } else {\n // Node.js\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const nodeCrypto = require('crypto');\n const randomBytes = nodeCrypto.randomBytes(length);\n bytes.set(randomBytes);\n }\n\n return bytes;\n }\n\n /**\n * Convert buffer to hex string\n */\n static bufferToHex(buffer: Buffer | Uint8Array): string {\n return Buffer.from(buffer).toString('hex');\n }\n\n /**\n * Convert hex string to buffer\n */\n static hexToBuffer(hex: string): Buffer {\n return Buffer.from(hex, 'hex');\n }\n\n /**\n * Hash using SHA-256\n */\n static async sha256(data: string | Buffer): Promise<Buffer> {\n const bytes = typeof data === 'string' ? Buffer.from(data, 'utf-8') : data;\n\n if (this.isBrowser) {\n const crypto = this.getCrypto();\n const hashBuffer = await crypto.subtle.digest('SHA-256', bytes);\n return Buffer.from(hashBuffer);\n } else {\n // Node.js\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const nodeCrypto = require('crypto');\n return nodeCrypto.createHash('sha256').update(bytes).digest();\n }\n }\n}\n\n/**\n * Encryption service for AES-256-CBC and ECIES operations\n */\nexport class EncryptionService {\n /**\n * Generate a random encryption key (32 bytes for AES-256)\n */\n static generateKey(): Buffer {\n return Buffer.from(CryptoUtils.getRandomBytes(32));\n }\n\n /**\n * Generate a random initialization vector (16 bytes for AES)\n */\n static generateIv(): Buffer {\n return Buffer.from(CryptoUtils.getRandomBytes(16));\n }\n\n /**\n * Encrypt data using AES-256-CBC\n * @param data - Data to encrypt\n * @param key - 32-byte encryption key\n * @param iv - 16-byte initialization vector\n * @returns Hex-encoded encrypted data\n */\n static async encrypt(data: string, key: Buffer, iv: Buffer): Promise<string> {\n try {\n if (key.length !== 32) {\n throw new EncryptionError('Key must be 32 bytes for AES-256');\n }\n if (iv.length !== 16) {\n throw new EncryptionError('IV must be 16 bytes');\n }\n\n if (CryptoUtils.isBrowser) {\n return await this.encryptBrowser(data, key, iv);\n } else {\n return this.encryptNode(data, key, iv);\n }\n } catch (error) {\n throw new EncryptionError(`Encryption failed: ${(error as Error).message}`);\n }\n }\n\n /**\n * Decrypt data using AES-256-CBC\n * @param encryptedData - Hex-encoded encrypted data\n * @param key - 32-byte encryption key\n * @param iv - 16-byte initialization vector\n * @returns Decrypted string\n */\n static async decrypt(encryptedData: string, key: Buffer, iv: Buffer): Promise<string> {\n try {\n if (key.length !== 32) {\n throw new EncryptionError('Key must be 32 bytes for AES-256');\n }\n if (iv.length !== 16) {\n throw new EncryptionError('IV must be 16 bytes');\n }\n\n if (CryptoUtils.isBrowser) {\n return await this.decryptBrowser(encryptedData, key, iv);\n } else {\n return this.decryptNode(encryptedData, key, iv);\n }\n } catch (error) {\n throw new EncryptionError(`Decryption failed: ${(error as Error).message}`);\n }\n }\n\n /**\n * Encrypt file buffer using AES-256-CBC\n * @param fileBuffer - File data as Buffer or ArrayBuffer\n * @param key - 32-byte encryption key\n * @param iv - 16-byte initialization vector\n * @returns Encrypted file buffer\n */\n static async encryptFile(fileBuffer: Buffer | ArrayBuffer, key: Buffer, iv: Buffer): Promise<Buffer> {\n try {\n const buffer = Buffer.isBuffer(fileBuffer) ? fileBuffer : Buffer.from(fileBuffer);\n\n if (CryptoUtils.isBrowser) {\n return await this.encryptFileBrowser(buffer, key, iv);\n } else {\n return this.encryptFileNode(buffer, key, iv);\n }\n } catch (error) {\n throw new EncryptionError(`File encryption failed: ${(error as Error).message}`);\n }\n }\n\n /**\n * Decrypt file buffer using AES-256-CBC\n * @param encryptedBuffer - Encrypted file data\n * @param key - 32-byte encryption key\n * @param iv - 16-byte initialization vector\n * @returns Decrypted file buffer\n */\n static async decryptFile(encryptedBuffer: Buffer | ArrayBuffer, key: Buffer, iv: Buffer): Promise<Buffer> {\n try {\n const buffer = Buffer.isBuffer(encryptedBuffer) ? encryptedBuffer : Buffer.from(encryptedBuffer);\n\n if (CryptoUtils.isBrowser) {\n return await this.decryptFileBrowser(buffer, key, iv);\n } else {\n return this.decryptFileNode(buffer, key, iv);\n }\n } catch (error) {\n throw new EncryptionError(`File decryption failed: ${(error as Error).message}`);\n }\n }\n\n /**\n * Encrypt data using ECIES (Elliptic Curve Integrated Encryption Scheme)\n * @param data - Data to encrypt\n * @param publicKey - Recipient's public key (hex or Buffer)\n * @returns Hex-encoded encrypted data\n */\n static encryptEcies(data: string, publicKey: string | Buffer): string {\n try {\n const pubKeyBuffer = typeof publicKey === 'string' ? CryptoUtils.hexToBuffer(publicKey) : publicKey;\n\n const dataBuffer = Buffer.from(data, 'utf-8');\n const encrypted = eciesEncrypt(pubKeyBuffer, dataBuffer);\n return encrypted.toString('hex');\n } catch (error) {\n throw new EncryptionError(`ECIES encryption failed: ${(error as Error).message}`);\n }\n }\n\n /**\n * Decrypt data using ECIES\n * @param encryptedData - Hex-encoded encrypted data\n * @param privateKey - Recipient's private key (hex or Buffer)\n * @returns Decrypted string\n */\n static decryptEcies(encryptedData: string, privateKey: string | Buffer): string {\n try {\n const privKeyBuffer = typeof privateKey === 'string' ? CryptoUtils.hexToBuffer(privateKey) : privateKey;\n\n const encryptedBuffer = CryptoUtils.hexToBuffer(encryptedData);\n const decrypted = eciesDecrypt(privKeyBuffer, encryptedBuffer);\n return decrypted.toString('utf-8');\n } catch (error) {\n throw new EncryptionError(`ECIES decryption failed: ${(error as Error).message}`);\n }\n }\n\n /**\n * Hash data using SHA-256\n */\n static async hash(data: string | Buffer): Promise<string> {\n const hashBuffer = await CryptoUtils.sha256(data);\n return CryptoUtils.bufferToHex(hashBuffer);\n }\n\n // ============================================================================\n // Node.js implementations\n // ============================================================================\n\n private static encryptNode(data: string, key: Buffer, iv: Buffer): string {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const crypto = require('crypto');\n const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);\n let encrypted = cipher.update(data, 'utf-8', 'hex');\n encrypted += cipher.final('hex');\n return encrypted;\n }\n\n private static decryptNode(encryptedData: string, key: Buffer, iv: Buffer): string {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const crypto = require('crypto');\n const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);\n let decrypted = decipher.update(encryptedData, 'hex', 'utf-8');\n decrypted += decipher.final('utf-8');\n return decrypted;\n }\n\n private static encryptFileNode(buffer: Buffer, key: Buffer, iv: Buffer): Buffer {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const crypto = require('crypto');\n const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);\n return Buffer.concat([cipher.update(buffer), cipher.final()]);\n }\n\n private static decryptFileNode(buffer: Buffer, key: Buffer, iv: Buffer): Buffer {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const crypto = require('crypto');\n const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);\n return Buffer.concat([decipher.update(buffer), decipher.final()]);\n }\n\n // ============================================================================\n // Browser implementations\n // ============================================================================\n\n private static async encryptBrowser(data: string, key: Buffer, iv: Buffer): Promise<string> {\n const crypto = CryptoUtils.getCrypto();\n const cryptoKey = await crypto.subtle.importKey('raw', key, { name: 'AES-CBC' }, false, ['encrypt']);\n\n const dataBuffer = Buffer.from(data, 'utf-8');\n const encrypted = await crypto.subtle.encrypt({ name: 'AES-CBC', iv }, cryptoKey, dataBuffer);\n\n return CryptoUtils.bufferToHex(Buffer.from(encrypted));\n }\n\n private static async decryptBrowser(encryptedData: string, key: Buffer, iv: Buffer): Promise<string> {\n const crypto = CryptoUtils.getCrypto();\n const cryptoKey = await crypto.subtle.importKey('raw', key, { name: 'AES-CBC' }, false, ['decrypt']);\n\n const encryptedBuffer = CryptoUtils.hexToBuffer(encryptedData);\n const decrypted = await crypto.subtle.decrypt({ name: 'AES-CBC', iv }, cryptoKey, encryptedBuffer);\n\n return Buffer.from(decrypted).toString('utf-8');\n }\n\n private static async encryptFileBrowser(buffer: Buffer, key: Buffer, iv: Buffer): Promise<Buffer> {\n const crypto = CryptoUtils.getCrypto();\n const cryptoKey = await crypto.subtle.importKey('raw', key, { name: 'AES-CBC' }, false, ['encrypt']);\n\n const encrypted = await crypto.subtle.encrypt({ name: 'AES-CBC', iv }, cryptoKey, buffer);\n\n return Buffer.from(encrypted);\n }\n\n private static async decryptFileBrowser(buffer: Buffer, key: Buffer, iv: Buffer): Promise<Buffer> {\n const crypto = CryptoUtils.getCrypto();\n const cryptoKey = await crypto.subtle.importKey('raw', key, { name: 'AES-CBC' }, false, ['decrypt']);\n\n const decrypted = await crypto.subtle.decrypt({ name: 'AES-CBC', iv }, cryptoKey, buffer);\n\n return Buffer.from(decrypted);\n }\n}\n\nexport { CryptoUtils };\n","import { BedrockCore } from '../client/bedrock-core';\nimport { ContactError } from '../types/errors';\nimport type { FileFullInfo } from '../types/schemas';\nimport { AGGREGATE_KEYS, Contact, ContactsAggregateSchema, FileEntriesAggregateSchema } from '../types/schemas';\nimport { FileService } from './file-service';\n\n/**\n * Contact service for managing contacts and shared files\n */\nexport class ContactService {\n private readonly core: BedrockCore;\n private readonly fileService: FileService;\n\n constructor(core: BedrockCore, fileService: FileService) {\n this.core = core;\n this.fileService = fileService;\n }\n\n /**\n * Initialize contacts aggregate if it doesn't exist\n */\n async setup(): Promise<void> {\n const aleph = this.core.getAlephService();\n\n try {\n await aleph.fetchAggregate(AGGREGATE_KEYS.CONTACTS, ContactsAggregateSchema);\n } catch {\n // Create empty aggregate if it doesn't exist\n await aleph.createAggregate(AGGREGATE_KEYS.CONTACTS, { contacts: [] });\n }\n }\n\n /**\n * Fetch all contacts\n */\n async listContacts(): Promise<Contact[]> {\n const aleph = this.core.getAlephService();\n\n try {\n const aggregate = await aleph.fetchAggregate(AGGREGATE_KEYS.CONTACTS, ContactsAggregateSchema);\n return aggregate.contacts;\n } catch (error) {\n throw new ContactError(`Failed to fetch contacts: ${(error as Error).message}`);\n }\n }\n\n /**\n * Get a contact by public key\n * @param publicKey - Contact's public key\n */\n async getContact(publicKey: string): Promise<Contact> {\n const contacts = await this.listContacts();\n const contact = contacts.find((c) => c.public_key === publicKey);\n\n if (!contact) {\n throw new ContactError(`Contact not found: ${publicKey}`);\n }\n\n return contact;\n }\n\n /**\n * Get a contact by address\n * @param address - Contact's Ethereum address\n */\n async getContactByAddress(address: string): Promise<Contact> {\n const contacts = await this.listContacts();\n const contact = contacts.find((c) => c.address.toLowerCase() === address.toLowerCase());\n\n if (!contact) {\n throw new ContactError(`Contact not found: ${address}`);\n }\n\n return contact;\n }\n\n /**\n * Add a new contact\n * @param name - Contact name\n * @param address - Contact's Ethereum address\n * @param publicKey - Contact's public key (hex string)\n */\n async addContact(name: string, address: string, publicKey: string): Promise<Contact> {\n const aleph = this.core.getAlephService();\n\n try {\n // Check if contact already exists\n const contacts = await this.listContacts();\n const existingContact = contacts.find(\n (c) => c.public_key === publicKey || c.address.toLowerCase() === address.toLowerCase()\n );\n\n if (existingContact) {\n throw new ContactError('Contact already exists');\n }\n\n // Create new contact\n const newContact: Contact = {\n name,\n address,\n public_key: publicKey,\n };\n\n // Add to contacts aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.CONTACTS, ContactsAggregateSchema, async (aggregate) => ({\n contacts: [...aggregate.contacts, newContact],\n }));\n\n return newContact;\n } catch (error) {\n if (error instanceof ContactError) {\n throw error;\n }\n throw new ContactError(`Failed to add contact: ${(error as Error).message}`);\n }\n }\n\n /**\n * Remove a contact\n * @param publicKey - Contact's public key\n */\n async removeContact(publicKey: string): Promise<void> {\n const aleph = this.core.getAlephService();\n\n try {\n // Verify contact exists\n await this.getContact(publicKey);\n\n // Remove from contacts aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.CONTACTS, ContactsAggregateSchema, async (aggregate) => ({\n contacts: aggregate.contacts.filter((c) => c.public_key !== publicKey),\n }));\n } catch (error) {\n if (error instanceof ContactError) {\n throw error;\n }\n throw new ContactError(`Failed to remove contact: ${(error as Error).message}`);\n }\n }\n\n /**\n * Update a contact's name\n * @param publicKey - Contact's public key\n * @param newName - New name for the contact\n */\n async updateContactName(publicKey: string, newName: string): Promise<Contact> {\n const aleph = this.core.getAlephService();\n\n try {\n // Verify contact exists\n const existingContact = await this.getContact(publicKey);\n\n // Update contact\n const updatedContact: Contact = {\n ...existingContact,\n name: newName,\n };\n\n // Update in contacts aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.CONTACTS, ContactsAggregateSchema, async (aggregate) => ({\n contacts: aggregate.contacts.map((c) => (c.public_key === publicKey ? updatedContact : c)),\n }));\n\n return updatedContact;\n } catch (error) {\n if (error instanceof ContactError) {\n throw error;\n }\n throw new ContactError(`Failed to update contact: ${(error as Error).message}`);\n }\n }\n\n /**\n * Fetch files shared by a contact\n * @param publicKey - Contact's public key\n */\n async getSharedFiles(publicKey: string): Promise<FileFullInfo[]> {\n try {\n // Verify contact exists\n await this.getContact(publicKey);\n\n // Fetch file entries\n const entries = await this.fileService.fetchFileEntries();\n\n // Filter entries shared with this contact\n const sharedEntries = entries.filter((entry) => entry.shared_with.includes(publicKey));\n\n // Fetch metadata for shared files\n const files = await this.fileService.fetchFilesMetaFromEntries(sharedEntries);\n\n return files;\n } catch (error) {\n throw new ContactError(`Failed to fetch shared files: ${(error as Error).message}`);\n }\n }\n\n /**\n * Fetch files that a contact has shared with the current user\n * @param publicKey - Contact's public key\n * @returns Files shared by the contact with current user\n */\n async fetchFilesSharedByContact(publicKey: string): Promise<FileFullInfo[]> {\n try {\n // Verify contact exists and get their address\n const contact = await this.getContact(publicKey);\n const currentUserPublicKey = this.core.getPublicKey();\n\n // Fetch contact's file entries from THEIR aggregate\n const aleph = this.core.getAlephService();\n const contactEntries = await aleph.fetchAggregate(\n AGGREGATE_KEYS.FILE_ENTRIES,\n FileEntriesAggregateSchema,\n contact.address // Important: contact's address, not current user's\n );\n\n // Filter entries shared with current user\n const sharedEntries = contactEntries.files.filter((entry) => entry.shared_with.includes(currentUserPublicKey));\n\n // Fetch metadata from contact's POSTs using fileService\n const files = await this.fileService.fetchFilesMetaFromEntries(\n sharedEntries,\n contact.address // Owner is the contact\n );\n\n return files;\n } catch (error) {\n throw new ContactError(`Failed to fetch files shared by contact: ${(error as Error).message}`);\n }\n }\n\n /**\n * Share a file with a contact\n * @param filePath - Path of the file to share\n * @param publicKey - Contact's public key\n */\n async shareFileWithContact(filePath: string, publicKey: string): Promise<void> {\n try {\n // Verify contact exists\n await this.getContact(publicKey);\n\n // Share the file\n await this.fileService.shareFile(filePath, publicKey);\n } catch (error) {\n throw new ContactError(`Failed to share file with contact: ${(error as Error).message}`);\n }\n }\n\n /**\n * Unshare a file with a contact\n * @param filePath - Path of the file to unshare\n * @param publicKey - Contact's public key\n */\n async unshareFileWithContact(filePath: string, publicKey: string): Promise<void> {\n try {\n // Verify contact exists\n await this.getContact(publicKey);\n\n // Unshare the file\n await this.fileService.unshareFile(filePath, publicKey);\n } catch (error) {\n throw new ContactError(`Failed to unshare file with contact: ${(error as Error).message}`);\n }\n }\n}\n","import { BedrockCore } from '../client/bedrock-core';\nimport { KnowledgeBaseError } from '../types/errors';\nimport { AGGREGATE_KEYS, KnowledgeBase, KnowledgeBasesAggregateSchema } from '../types/schemas';\n\n/**\n * Knowledge base service for organizing files into collections\n */\nexport class KnowledgeBaseService {\n private readonly core: BedrockCore;\n\n constructor(core: BedrockCore) {\n this.core = core;\n }\n\n /**\n * Initialize knowledge bases aggregate if it doesn't exist\n */\n async setup(): Promise<void> {\n const aleph = this.core.getAlephService();\n\n try {\n await aleph.fetchAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, KnowledgeBasesAggregateSchema);\n } catch {\n // Create empty aggregate if it doesn't exist\n await aleph.createAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, { knowledge_bases: [] });\n }\n }\n\n /**\n * Fetch all knowledge bases\n */\n async listKnowledgeBases(): Promise<KnowledgeBase[]> {\n const aleph = this.core.getAlephService();\n\n try {\n const aggregate = await aleph.fetchAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, KnowledgeBasesAggregateSchema);\n return aggregate.knowledge_bases;\n } catch (error) {\n throw new KnowledgeBaseError(`Failed to fetch knowledge bases: ${(error as Error).message}`);\n }\n }\n\n /**\n * Get a knowledge base by name\n * @param name - Knowledge base name\n */\n async getKnowledgeBase(name: string): Promise<KnowledgeBase> {\n const kbs = await this.listKnowledgeBases();\n const kb = kbs.find((k) => k.name === name);\n\n if (!kb) {\n throw new KnowledgeBaseError(`Knowledge base not found: ${name}`);\n }\n\n return kb;\n }\n\n /**\n * Create a new knowledge base\n * @param name - Knowledge base name\n * @param filePaths - Optional initial file paths\n */\n async createKnowledgeBase(name: string, filePaths: string[] = []): Promise<KnowledgeBase> {\n const aleph = this.core.getAlephService();\n\n try {\n // Check if knowledge base already exists\n const kbs = await this.listKnowledgeBases();\n const existingKb = kbs.find((k) => k.name === name);\n\n if (existingKb) {\n throw new KnowledgeBaseError(`Knowledge base already exists: ${name}`);\n }\n\n // Create new knowledge base\n const now = new Date().toISOString();\n const newKb: KnowledgeBase = {\n name,\n file_paths: filePaths,\n created_at: now,\n updated_at: now,\n };\n\n // Add to knowledge bases aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, KnowledgeBasesAggregateSchema, async (aggregate) => ({\n knowledge_bases: [...aggregate.knowledge_bases, newKb],\n }));\n\n return newKb;\n } catch (error) {\n if (error instanceof KnowledgeBaseError) {\n throw error;\n }\n throw new KnowledgeBaseError(`Failed to create knowledge base: ${(error as Error).message}`);\n }\n }\n\n /**\n * Delete a knowledge base\n * @param name - Knowledge base name\n */\n async deleteKnowledgeBase(name: string): Promise<void> {\n const aleph = this.core.getAlephService();\n\n try {\n // Verify knowledge base exists\n await this.getKnowledgeBase(name);\n\n // Remove from knowledge bases aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, KnowledgeBasesAggregateSchema, async (aggregate) => ({\n knowledge_bases: aggregate.knowledge_bases.filter((k) => k.name !== name),\n }));\n } catch (error) {\n if (error instanceof KnowledgeBaseError) {\n throw error;\n }\n throw new KnowledgeBaseError(`Failed to delete knowledge base: ${(error as Error).message}`);\n }\n }\n\n /**\n * Rename a knowledge base\n * @param oldName - Current name\n * @param newName - New name\n */\n async renameKnowledgeBase(oldName: string, newName: string): Promise<KnowledgeBase> {\n const aleph = this.core.getAlephService();\n\n try {\n // Verify old knowledge base exists\n const existingKb = await this.getKnowledgeBase(oldName);\n\n // Check if new name already exists\n const kbs = await this.listKnowledgeBases();\n if (kbs.some((k) => k.name === newName)) {\n throw new KnowledgeBaseError(`Knowledge base already exists: ${newName}`);\n }\n\n // Update knowledge base\n const updatedKb: KnowledgeBase = {\n ...existingKb,\n name: newName,\n updated_at: new Date().toISOString(),\n };\n\n // Update in knowledge bases aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, KnowledgeBasesAggregateSchema, async (aggregate) => ({\n knowledge_bases: aggregate.knowledge_bases.map((k) => (k.name === oldName ? updatedKb : k)),\n }));\n\n return updatedKb;\n } catch (error) {\n if (error instanceof KnowledgeBaseError) {\n throw error;\n }\n throw new KnowledgeBaseError(`Failed to rename knowledge base: ${(error as Error).message}`);\n }\n }\n\n /**\n * Set the files in a knowledge base (replaces all existing files)\n * @param name - Knowledge base name\n * @param filePaths - File paths\n */\n async setFiles(name: string, filePaths: string[]): Promise<KnowledgeBase> {\n const aleph = this.core.getAlephService();\n\n try {\n // Verify knowledge base exists\n const existingKb = await this.getKnowledgeBase(name);\n\n // Update knowledge base\n const updatedKb: KnowledgeBase = {\n ...existingKb,\n file_paths: filePaths,\n updated_at: new Date().toISOString(),\n };\n\n // Update in knowledge bases aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, KnowledgeBasesAggregateSchema, async (aggregate) => ({\n knowledge_bases: aggregate.knowledge_bases.map((k) => (k.name === name ? updatedKb : k)),\n }));\n\n return updatedKb;\n } catch (error) {\n if (error instanceof KnowledgeBaseError) {\n throw error;\n }\n throw new KnowledgeBaseError(`Failed to set files: ${(error as Error).message}`);\n }\n }\n\n /**\n * Add files to a knowledge base\n * @param name - Knowledge base name\n * @param filePaths - File paths to add\n */\n async addFiles(name: string, filePaths: string[]): Promise<KnowledgeBase> {\n const aleph = this.core.getAlephService();\n\n try {\n // Verify knowledge base exists\n const existingKb = await this.getKnowledgeBase(name);\n\n // Add new file paths (avoid duplicates)\n const updatedFilePaths = [...new Set([...existingKb.file_paths, ...filePaths])];\n\n // Update knowledge base\n const updatedKb: KnowledgeBase = {\n ...existingKb,\n file_paths: updatedFilePaths,\n updated_at: new Date().toISOString(),\n };\n\n // Update in knowledge bases aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, KnowledgeBasesAggregateSchema, async (aggregate) => ({\n knowledge_bases: aggregate.knowledge_bases.map((k) => (k.name === name ? updatedKb : k)),\n }));\n\n return updatedKb;\n } catch (error) {\n if (error instanceof KnowledgeBaseError) {\n throw error;\n }\n throw new KnowledgeBaseError(`Failed to add files: ${(error as Error).message}`);\n }\n }\n\n /**\n * Remove files from a knowledge base\n * @param name - Knowledge base name\n * @param filePaths - File paths to remove\n */\n async removeFiles(name: string, filePaths: string[]): Promise<KnowledgeBase> {\n const aleph = this.core.getAlephService();\n\n try {\n // Verify knowledge base exists\n const existingKb = await this.getKnowledgeBase(name);\n\n // Remove file paths\n const updatedFilePaths = existingKb.file_paths.filter((path) => !filePaths.includes(path));\n\n // Update knowledge base\n const updatedKb: KnowledgeBase = {\n ...existingKb,\n file_paths: updatedFilePaths,\n updated_at: new Date().toISOString(),\n };\n\n // Update in knowledge bases aggregate\n await aleph.updateAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, KnowledgeBasesAggregateSchema, async (aggregate) => ({\n knowledge_bases: aggregate.knowledge_bases.map((k) => (k.name === name ? updatedKb : k)),\n }));\n\n return updatedKb;\n } catch (error) {\n if (error instanceof KnowledgeBaseError) {\n throw error;\n }\n throw new KnowledgeBaseError(`Failed to remove files: ${(error as Error).message}`);\n }\n }\n\n /**\n * Clear all files from a knowledge base\n * @param name - Knowledge base name\n */\n async clearFiles(name: string): Promise<KnowledgeBase> {\n return await this.setFiles(name, []);\n }\n}\n","import { BedrockCore } from '../client/bedrock-core';\nimport { UserCredit, CreditAggregateSchema, AGGREGATE_KEYS } from '../types/schemas';\n\n/**\n * Service for managing user credits (read-only, backend-managed)\n */\nexport class CreditService {\n private core: BedrockCore;\n private static readonly BACKEND_ADDRESS = '0x1234567890123456789012345678901234567890';\n\n constructor(core: BedrockCore) {\n this.core = core;\n }\n\n /**\n * Get user's credit balance and transaction history\n * @returns User credit data with balance and transactions\n */\n async getCreditBalance(): Promise<UserCredit> {\n const aleph = this.core.getAlephService();\n const userAddress = this.core.getMainAddress();\n\n try {\n const creditAggregate = await aleph.fetchAggregate(\n AGGREGATE_KEYS.CREDITS,\n CreditAggregateSchema,\n CreditService.BACKEND_ADDRESS\n );\n\n return creditAggregate[userAddress] || { balance: 0, transactions: [] };\n } catch {\n // Graceful fallback if aggregate doesn't exist or user not found\n return { balance: 0, transactions: [] };\n }\n }\n}\n","import { BedrockCore, BedrockCoreConfig } from './client/bedrock-core';\nimport { FileService } from './services/file-service';\nimport { ContactService } from './services/contact-service';\nimport { KnowledgeBaseService } from './services/knowledge-base-service';\nimport { CreditService } from './services/credit-service';\n\n/**\n * Main Bedrock SDK client\n *\n * @example\n * ```typescript\n * // Initialize from private key\n * const client = await BedrockClient.fromPrivateKey('0x...');\n *\n * // Initialize from wallet provider (MetaMask, etc.)\n * const client = await BedrockClient.fromProvider(window.ethereum);\n *\n * // Upload files\n * const files = await client.files.uploadFiles([\n * { name: 'doc.txt', path: 'documents/doc.txt', content: buffer }\n * ]);\n *\n * // List files\n * const allFiles = await client.files.listFiles();\n *\n * // Add contact\n * await client.contacts.addContact('Alice', '0x...', 'publicKey');\n *\n * // Create knowledge base\n * await client.knowledgeBases.createKnowledgeBase('My Documents');\n *\n * // Check credit balance\n * const balance = await client.credits.getCreditBalance();\n *\n * // Share file publicly\n * const publicHash = await client.files.shareFilePublicly(file, 'username');\n * const meta = await FileService.fetchPublicFileMeta(publicHash);\n * const content = await FileService.downloadPublicFile(meta.store_hash);\n *\n * // Get files shared by contact\n * const sharedFiles = await client.contacts.fetchFilesSharedByContact(contactPubKey);\n * ```\n */\nexport class BedrockClient {\n private core: BedrockCore;\n\n /**\n * File operations service\n */\n public readonly files: FileService;\n\n /**\n * Contact management service\n */\n public readonly contacts: ContactService;\n\n /**\n * Knowledge base management service\n */\n public readonly knowledgeBases: KnowledgeBaseService;\n\n /**\n * Credit management service\n */\n public readonly credits: CreditService;\n\n private constructor(core: BedrockCore) {\n this.core = core;\n this.files = new FileService(core);\n this.contacts = new ContactService(core, this.files);\n this.knowledgeBases = new KnowledgeBaseService(core);\n this.credits = new CreditService(core);\n }\n\n /**\n * Create BedrockClient from a private key\n *\n * @param privateKey - Ethereum private key (hex string with or without 0x prefix)\n * @param config - Optional configuration\n * @returns Initialized BedrockClient\n *\n * @example\n * ```typescript\n * const client = await BedrockClient.fromPrivateKey('0xabc123...');\n * ```\n */\n static async fromPrivateKey(privateKey: string, config?: BedrockCoreConfig): Promise<BedrockClient> {\n const core = await BedrockCore.fromPrivateKey(privateKey, config);\n const client = new BedrockClient(core);\n await client.setup();\n return client;\n }\n\n /**\n * Create BedrockClient from a wallet provider (e.g., MetaMask)\n *\n * @param provider - EIP-1193 provider\n * @param config - Optional configuration\n * @returns Initialized BedrockClient\n *\n * @example\n * ```typescript\n * const client = await BedrockClient.fromProvider(window.ethereum);\n * ```\n */\n static async fromProvider(provider: any, config?: BedrockCoreConfig): Promise<BedrockClient> {\n const core = await BedrockCore.fromProvider(provider, config);\n const client = new BedrockClient(core);\n await client.setup();\n return client;\n }\n\n /**\n * Create BedrockClient from a signature hash\n *\n * @param signatureHash - Signature hash from wallet\n * @param provider - EIP-1193 provider\n * @param config - Optional configuration\n * @returns Initialized BedrockClient\n *\n * @example\n * ```typescript\n * const signature = await wallet.signMessage({ message: 'Bedrock.im' });\n * const client = await BedrockClient.fromSignature(signature, window.ethereum);\n * ```\n */\n static async fromSignature(signatureHash: string, provider: any, config?: BedrockCoreConfig): Promise<BedrockClient> {\n const core = await BedrockCore.fromSignature(signatureHash, provider, config);\n const client = new BedrockClient(core);\n await client.setup();\n return client;\n }\n\n /**\n * Get the main account address\n */\n getMainAddress(): string {\n return this.core.getMainAddress();\n }\n\n /**\n * Get the sub-account address\n */\n getSubAddress(): string {\n return this.core.getSubAddress();\n }\n\n /**\n * Get the account's public key\n */\n getPublicKey(): string {\n return this.core.getPublicKey();\n }\n\n /**\n * Get the encryption key (32 bytes derived from signature)\n */\n getEncryptionKey(): Buffer {\n return this.core.getEncryptionKey();\n }\n\n /**\n * Reset all data (files, contacts, knowledge bases)\n * WARNING: This will delete all user data from Aleph\n */\n async resetAllData(): Promise<void> {\n await Promise.all([this.resetFiles(), this.resetContacts(), this.resetKnowledgeBases()]);\n }\n\n /**\n * Reset all files\n * WARNING: This will delete all files from Aleph\n */\n async resetFiles(): Promise<void> {\n const aleph = this.core.getAlephService();\n await aleph.createAggregate(AGGREGATE_KEYS.FILE_ENTRIES, [] as any);\n }\n\n /**\n * Reset all contacts\n * WARNING: This will delete all contacts\n */\n async resetContacts(): Promise<void> {\n const aleph = this.core.getAlephService();\n await aleph.createAggregate(AGGREGATE_KEYS.CONTACTS, [] as any);\n }\n\n /**\n * Reset all knowledge bases\n * WARNING: This will delete all knowledge bases\n */\n async resetKnowledgeBases(): Promise<void> {\n const aleph = this.core.getAlephService();\n await aleph.createAggregate(AGGREGATE_KEYS.KNOWLEDGE_BASES, [] as any);\n }\n\n // ============================================================================\n // Private methods\n // ============================================================================\n\n /**\n * Setup all services (create aggregates if they don't exist)\n */\n private async setup(): Promise<void> {\n await Promise.all([this.files.setup(), this.contacts.setup(), this.knowledgeBases.setup()]);\n }\n}\n\n// Re-export AGGREGATE_KEYS for use in reset methods\nimport { AGGREGATE_KEYS } from './types/schemas';\n","/**\n * Bedrock SDK - TypeScript SDK for Bedrock decentralized cloud storage\n * powered by Aleph\n *\n * @packageDocumentation\n */\n\n// Main client\nexport { BedrockClient } from './bedrock-client';\n\n// Core classes\nexport { BedrockCore, BedrockCoreConfig } from './client/bedrock-core';\nexport { AlephService } from './client/aleph-service';\n\n// Services\nexport { FileService, FileInput } from './services/file-service';\nexport { ContactService } from './services/contact-service';\nexport { KnowledgeBaseService } from './services/knowledge-base-service';\nexport { CreditService } from './services/credit-service';\n\n// Encryption\nexport { EncryptionService, CryptoUtils } from './crypto/encryption';\n\n// Types and schemas\nexport {\n // Constants\n BEDROCK_MESSAGE,\n SECURITY_AGGREGATE_KEY,\n ALEPH_GENERAL_CHANNEL,\n AGGREGATE_KEYS,\n POST_TYPES,\n\n // File types\n FileEntry,\n FileMeta,\n FileMetaEncrypted,\n FileFullInfo,\n FileEntrySchema,\n FileMetaSchema,\n FileMetaEncryptedSchema,\n FileEntriesAggregateSchema,\n\n // Public file types\n PublicFileMeta,\n PublicFileMetaSchema,\n\n // Contact types\n Contact,\n ContactSchema,\n ContactsAggregate,\n ContactsAggregateSchema,\n\n // Knowledge base types\n KnowledgeBase,\n KnowledgeBaseSchema,\n KnowledgeBasesAggregate,\n KnowledgeBasesAggregateSchema,\n\n // Credit types\n UserCredit,\n CreditTransaction,\n CreditAggregate,\n UserCreditSchema,\n CreditTransactionSchema,\n CreditAggregateSchema,\n\n // Security types\n SecurityAggregate,\n SecurityAggregateSchema,\n\n // Aleph message types\n AlephPostContent,\n AlephAggregateContent,\n AlephStoreMessage,\n AlephMessage,\n\n // Schema helpers\n HexString64Schema,\n HexString32Schema,\n DatetimeSchema,\n AddressSchema,\n} from './types/schemas';\n\n// Errors\nexport {\n BedrockError,\n AuthenticationError,\n EncryptionError,\n FileError,\n FileNotFoundError,\n ContactError,\n KnowledgeBaseError,\n CreditError,\n NetworkError,\n ValidationError,\n} from './types/errors';\n\n// Re-export Aleph SDK types for convenience\nexport type { Account } from '@aleph-sdk/account';\nexport { ETHAccount } from '@aleph-sdk/ethereum';\nexport { AlephHttpClient, AuthenticatedAlephHttpClient } from '@aleph-sdk/client';\n"],"mappings":"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","names":["AuthenticatedAlephHttpClient","z","z","AuthenticatedAlephHttpClient","ETHAccount","AlephHttpClient","AuthenticatedAlephHttpClient"]}