@ghostspeak/sdk 2.0.7 → 2.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +145 -2
- package/dist/{GhostSpeakClient-CWmGaM9Q.d.ts → GhostSpeakClient-bnXwUPHI.d.ts} +10 -6
- package/dist/{StakingModule-C5rzuOWb.d.ts → StakingModule-DunDShLq.d.ts} +263 -343
- package/dist/{agent-5YLZ7DAC.js → agent-S42FIMR7.js} +3 -3
- package/dist/{agent-5YLZ7DAC.js.map → agent-S42FIMR7.js.map} +1 -1
- package/dist/browser-CI5_6Gzk.d.ts +234 -0
- package/dist/browser.d.ts +3 -64
- package/dist/browser.js +9 -9
- package/dist/{chunk-SFTSZ3LC.js → chunk-46QWY3MG.js} +3 -3
- package/dist/{chunk-SFTSZ3LC.js.map → chunk-46QWY3MG.js.map} +1 -1
- package/dist/{chunk-G7S6B6WB.js → chunk-5QBSC4T4.js} +7 -7
- package/dist/{chunk-G7S6B6WB.js.map → chunk-5QBSC4T4.js.map} +1 -1
- package/dist/{chunk-IHVDQ4YI.js → chunk-5QZVFUXB.js} +201 -256
- package/dist/chunk-5QZVFUXB.js.map +1 -0
- package/dist/{chunk-E3FD2CNY.js → chunk-6XCCMJ6M.js} +19 -23
- package/dist/chunk-6XCCMJ6M.js.map +1 -0
- package/dist/{chunk-JV2SWONF.js → chunk-A7ALCVUI.js} +3 -3
- package/dist/{chunk-JV2SWONF.js.map → chunk-A7ALCVUI.js.map} +1 -1
- package/dist/{chunk-AL3HQN73.js → chunk-AWMGX3OX.js} +172 -112
- package/dist/chunk-AWMGX3OX.js.map +1 -0
- package/dist/{chunk-S74EH3KD.js → chunk-IQM5RASO.js} +637 -25
- package/dist/chunk-IQM5RASO.js.map +1 -0
- package/dist/{chunk-SZGFSCNU.js → chunk-JYXSOXCP.js} +467 -299
- package/dist/chunk-JYXSOXCP.js.map +1 -0
- package/dist/{chunk-C5CDA3WX.js → chunk-OXA7MECJ.js} +476 -3
- package/dist/chunk-OXA7MECJ.js.map +1 -0
- package/dist/{chunk-KB6CKIUK.js → chunk-QLRWUHN2.js} +3 -3
- package/dist/{chunk-KB6CKIUK.js.map → chunk-QLRWUHN2.js.map} +1 -1
- package/dist/client.d.ts +2 -3
- package/dist/client.js +9 -9
- package/dist/{createAgentAuthorization-ULG47ZJI.js → createAgentAuthorization-KGZNXZBT.js} +4 -4
- package/dist/{createAgentAuthorization-ULG47ZJI.js.map → createAgentAuthorization-KGZNXZBT.js.map} +1 -1
- package/dist/generated-QJREJQ2C.js +9 -0
- package/dist/{generated-EG5USUFG.js.map → generated-QJREJQ2C.js.map} +1 -1
- package/dist/index.d.ts +209 -231
- package/dist/index.js +231 -521
- package/dist/index.js.map +1 -1
- package/dist/metafile-esm.json +1 -1
- package/dist/minimal/core-minimal.d.ts +266 -184
- package/dist/minimal/core-minimal.js +6 -6
- package/dist/minimal/core-minimal.js.map +1 -1
- package/dist/{revokeAuthorization-OK7E7OK3.js → revokeAuthorization-2ZRO6GUZ.js} +4 -4
- package/dist/{revokeAuthorization-OK7E7OK3.js.map → revokeAuthorization-2ZRO6GUZ.js.map} +1 -1
- package/dist/{updateReputationWithAuth-Y4ONEVSP.js → updateReputationWithAuth-PCEUOCFV.js} +4 -4
- package/dist/{updateReputationWithAuth-Y4ONEVSP.js.map → updateReputationWithAuth-PCEUOCFV.js.map} +1 -1
- package/dist/utils.js +9 -9
- package/package.json +4 -4
- package/dist/chunk-AL3HQN73.js.map +0 -1
- package/dist/chunk-C5CDA3WX.js.map +0 -1
- package/dist/chunk-E3FD2CNY.js.map +0 -1
- package/dist/chunk-IHVDQ4YI.js.map +0 -1
- package/dist/chunk-S74EH3KD.js.map +0 -1
- package/dist/chunk-SZGFSCNU.js.map +0 -1
- package/dist/generated-EG5USUFG.js +0 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/discriminator-validator.ts","../src/utils/account-migration.ts","../src/utils/account-diagnostics.ts","../src/utils/token-utils.ts","../src/utils/governance-helpers.ts","../src/utils/feature-flags.ts","../src/utils/client-encryption.ts","../src/utils/elgamal.ts"],"names":["AGENT_DISCRIMINATOR","TokenProgram","TokenExtension","getProgramDerivedAddress","getAddressEncoder","sha256","bytesToHex","randomBytes"],"mappings":"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","file":"chunk-G7S6B6WB.js","sourcesContent":["/**\n * Discriminator Validation Utilities\n * \n * Handles discriminator validation and provides fallback mechanisms\n * for accounts with mismatched discriminators\n */\n\nimport type { Address } from '@solana/addresses'\nimport type { EncodedAccount, MaybeEncodedAccount } from '@solana/kit'\n\ninterface RpcResponse {\n value: {\n data: [string, string]\n executable: boolean\n lamports: number\n owner: string\n rentEpoch: number\n } | null\n}\n\ninterface RpcInterface {\n getAccountInfo: (address: Address, options: { encoding: string }) => {\n send: () => Promise<RpcResponse>\n }\n}\n\nexport interface DiscriminatorValidationResult {\n isValid: boolean\n expectedLength: number\n actualLength: number\n canDecode: boolean\n needsMigration: boolean\n errorMessage?: string\n}\n\nexport interface AccountInspectionResult {\n address: string\n dataLength: number\n discriminator: Uint8Array | null\n discriminatorLength: number\n isAgentAccount: boolean\n needsMigration: boolean\n rawData: Uint8Array\n}\n\n/**\n * Validates account discriminator before attempting to decode\n */\nexport function validateAccountDiscriminator(\n accountData: Uint8Array,\n expectedDiscriminator: Uint8Array\n): DiscriminatorValidationResult {\n // Check if we have enough data for a discriminator\n if (accountData.length < expectedDiscriminator.length) {\n return {\n isValid: false,\n expectedLength: expectedDiscriminator.length,\n actualLength: accountData.length,\n canDecode: false,\n needsMigration: true,\n errorMessage: `Account too small. Expected at least ${expectedDiscriminator.length} bytes, got ${accountData.length}`\n }\n }\n\n // Extract the discriminator from account data\n const actualDiscriminator = accountData.slice(0, expectedDiscriminator.length)\n\n // Check if discriminators match\n const isValid = actualDiscriminator.every((byte, index) => byte === expectedDiscriminator[index])\n\n if (isValid) {\n return {\n isValid: true,\n expectedLength: expectedDiscriminator.length,\n actualLength: actualDiscriminator.length,\n canDecode: true,\n needsMigration: false\n }\n }\n\n // Check for common legacy discriminator patterns\n if (actualDiscriminator.length >= 2) {\n const first2Bytes = actualDiscriminator.slice(0, 2)\n // If first 2 bytes are non-zero, might be legacy format\n if (first2Bytes[0] !== 0 || first2Bytes[1] !== 0) {\n return {\n isValid: false,\n expectedLength: expectedDiscriminator.length,\n actualLength: 2, // Legacy format\n canDecode: false,\n needsMigration: true,\n errorMessage: `Legacy discriminator format detected. Account needs migration.`\n }\n }\n }\n\n return {\n isValid: false,\n expectedLength: expectedDiscriminator.length,\n actualLength: actualDiscriminator.length,\n canDecode: false,\n needsMigration: true,\n errorMessage: `Discriminator mismatch. Expected [${Array.from(expectedDiscriminator).join(', ')}], got [${Array.from(actualDiscriminator).join(', ')}]`\n }\n}\n\n/**\n * Safe account decoding with discriminator validation\n */\nexport async function safeDecodeAccount<T>(\n rpc: unknown,\n address: Address,\n decoder: (data: Uint8Array) => T,\n expectedDiscriminator: Uint8Array,\n accountType = 'account'\n): Promise<{ account: T | null; validation: DiscriminatorValidationResult; needsAttention: boolean }> {\n try {\n // Fetch raw account data using compatible RPC interface\n const rpcClient = rpc as RpcInterface\n const response = await rpcClient.getAccountInfo(address, { encoding: 'base64' }).send()\n \n if (!response.value) {\n return {\n account: null,\n validation: {\n isValid: false,\n expectedLength: expectedDiscriminator.length,\n actualLength: 0,\n canDecode: false,\n needsMigration: false,\n errorMessage: `${accountType} account not found`\n },\n needsAttention: false\n }\n }\n\n // Decode base64 data\n const rawData = response.value.data[0]\n if (typeof rawData !== 'string') {\n throw new Error('Expected base64 string from RPC response')\n }\n const accountData = Buffer.from(rawData, 'base64')\n \n // Validate discriminator\n const validation = validateAccountDiscriminator(accountData, expectedDiscriminator)\n \n if (validation.canDecode) {\n // Try to decode the account\n try {\n const account = decoder(accountData)\n return { account, validation, needsAttention: false }\n } catch (decodeError) {\n return {\n account: null,\n validation: {\n ...validation,\n canDecode: false,\n errorMessage: `Decoding failed: ${decodeError instanceof Error ? decodeError.message : String(decodeError)}`\n },\n needsAttention: true\n }\n }\n }\n\n return {\n account: null,\n validation,\n needsAttention: validation.needsMigration\n }\n\n } catch (error) {\n return {\n account: null,\n validation: {\n isValid: false,\n expectedLength: expectedDiscriminator.length,\n actualLength: 0,\n canDecode: false,\n needsMigration: false,\n errorMessage: `Failed to fetch account: ${error instanceof Error ? error.message : String(error)}`\n },\n needsAttention: true\n }\n }\n}\n\n/**\n * Create user-friendly error message for discriminator issues\n */\nexport function createDiscriminatorErrorMessage(\n validation: DiscriminatorValidationResult,\n accountType: string,\n address: string\n): string {\n if (validation.needsMigration) {\n return [\n `⚠️ ${accountType} account needs attention: ${address}`,\n ` Issue: ${validation.errorMessage}`,\n ` Resolution: Account may need to be recreated with current program version`,\n ` Use 'ghost diagnose account ${address}' for detailed analysis`\n ].join('\\n')\n }\n\n if (!validation.canDecode) {\n return [\n `❌ Failed to decode ${accountType} account: ${address}`,\n ` Issue: ${validation.errorMessage}`,\n ` This may indicate a corrupt or incompatible account`\n ].join('\\n')\n }\n\n return `✅ ${accountType} account is valid: ${address}`\n}\n\n/**\n * Safe Agent account decoding with discriminator validation\n * Returns a compatibility result with exists property\n */\nexport async function safeDecodeAgent(\n encodedAccount: { address: Address; data: Uint8Array }\n): Promise<{ exists: boolean; data?: unknown } | null> {\n try {\n // Import Agent discriminator and decoder\n const { AGENT_DISCRIMINATOR, getAgentDecoder } = await import('../generated/accounts/agent.js')\n \n // Validate discriminator\n const validation = validateAccountDiscriminator(encodedAccount.data, AGENT_DISCRIMINATOR)\n \n if (validation.canDecode) {\n try {\n const decoder = getAgentDecoder()\n const data = decoder.decode(encodedAccount.data)\n return { exists: true, data }\n } catch (decodeError) {\n console.warn(`Failed to decode Agent account ${encodedAccount.address}:`, decodeError)\n return { exists: false }\n }\n }\n \n // Account exists but can't be decoded due to discriminator issues\n return { exists: false }\n } catch (error) {\n console.warn(`Safe decode failed for ${encodedAccount.address}:`, error)\n return null\n }\n}\n\n/**\n * Inspects account data and extracts useful information about discriminator\n */\nexport function inspectAccountData(\n encodedAccount: EncodedAccount | MaybeEncodedAccount,\n address: string\n): AccountInspectionResult {\n if (!('exists' in encodedAccount) || !encodedAccount.exists) {\n return {\n address,\n dataLength: 0,\n discriminator: null,\n discriminatorLength: 0,\n isAgentAccount: false,\n needsMigration: false,\n rawData: new Uint8Array(0)\n }\n }\n\n const data = 'data' in encodedAccount ? encodedAccount.data : new Uint8Array(0)\n \n // Extract discriminator (first 8 bytes if available)\n const discriminatorLength = Math.min(data.length, 8)\n const discriminator = discriminatorLength > 0 ? data.slice(0, discriminatorLength) : null\n\n return {\n address,\n dataLength: data.length,\n discriminator,\n discriminatorLength,\n isAgentAccount: false, // Would need more logic to determine this\n needsMigration: discriminatorLength > 0 && discriminatorLength < 8,\n rawData: data\n }\n}","/**\n * Account Migration Utility\n * \n * Handles migration of old Agent accounts that were created with\n * different discriminator formats to the current format.\n */\n\nimport type { EncodedAccount, MaybeEncodedAccount } from '@solana/kit';\nimport { \n validateAccountDiscriminator, \n inspectAccountData \n} from './discriminator-validator.js';\n\nexport interface MigrationPlan {\n address: string;\n currentState: 'valid' | 'needs_migration' | 'invalid' | 'not_exists';\n migrationType: 'none' | 'recreate' | 'data_conversion' | 'unsupported';\n issues: string[];\n recommendations: string[];\n canAutoMigrate: boolean;\n}\n\nexport interface MigrationResult {\n success: boolean;\n address: string;\n action: 'skipped' | 'migrated' | 'failed';\n error?: string;\n newAccountData?: Uint8Array;\n}\n\nexport interface LegacyAgentData {\n // Define potential old Agent format fields here\n // This would need to be updated based on actual legacy formats\n discriminator: Uint8Array;\n owner?: string;\n name?: string;\n // ... other legacy fields\n}\n\n/**\n * Analyzes an account and creates a migration plan\n */\nexport async function createMigrationPlan(\n encodedAccount: EncodedAccount | MaybeEncodedAccount,\n address: string\n): Promise<MigrationPlan> {\n const plan: MigrationPlan = {\n address,\n currentState: 'not_exists',\n migrationType: 'none',\n issues: [],\n recommendations: [],\n canAutoMigrate: false\n };\n\n if (!('exists' in encodedAccount) || !encodedAccount.exists) {\n plan.recommendations.push('Account does not exist - no migration needed');\n return plan;\n }\n\n // Import the discriminator\n const { AGENT_DISCRIMINATOR } = await import('../generated/accounts/agent.js');\n const validation = validateAccountDiscriminator(encodedAccount.data, AGENT_DISCRIMINATOR);\n const inspection = inspectAccountData(encodedAccount, address);\n\n // Determine current state\n if (validation.isValid) {\n plan.currentState = 'valid';\n plan.recommendations.push('Account is already in the correct format');\n return plan;\n }\n\n if (validation.needsMigration) {\n plan.currentState = 'needs_migration';\n plan.issues.push(`Discriminator length mismatch: expected 8 bytes, got ${validation.actualLength} bytes`);\n } else {\n plan.currentState = 'invalid';\n plan.issues.push('Account has invalid or corrupted discriminator');\n }\n\n // Determine migration type based on data analysis\n if (inspection.discriminatorLength === 2) {\n // This is likely an old format with 2-byte discriminator\n plan.migrationType = 'recreate';\n plan.issues.push('Account uses legacy 2-byte discriminator format');\n plan.recommendations.push('Recreate account using current register_agent instruction');\n plan.recommendations.push('Export existing data first if valuable');\n } else if (inspection.discriminatorLength === 0) {\n // Account has no discriminator\n plan.migrationType = 'unsupported';\n plan.issues.push('Account has no discriminator - may not be an Agent account');\n plan.recommendations.push('Verify this is actually an Agent account');\n } else if (inspection.discriminatorLength < 8) {\n // Partial discriminator\n plan.migrationType = 'unsupported';\n plan.issues.push(`Partial discriminator detected (${inspection.discriminatorLength} bytes)`);\n plan.recommendations.push('Account data may be corrupted - consider recreation');\n } else {\n // Full 8-byte discriminator but wrong values\n plan.migrationType = 'data_conversion';\n plan.issues.push('Discriminator has correct length but wrong values');\n plan.recommendations.push('May be from a different program version');\n plan.recommendations.push('Check if this account belongs to the correct program');\n }\n\n // Determine if auto-migration is possible\n plan.canAutoMigrate = plan.migrationType === 'recreate' && inspection.dataLength > 8;\n\n return plan;\n}\n\n/**\n * Attempts to extract meaningful data from a legacy account\n */\nexport function extractLegacyData(\n encodedAccount: EncodedAccount | MaybeEncodedAccount\n): LegacyAgentData | null {\n if (!('exists' in encodedAccount) || !encodedAccount.exists || !('data' in encodedAccount) || encodedAccount.data.length < 2) {\n return null;\n }\n\n const data = ('data' in encodedAccount) ? encodedAccount.data : new Uint8Array(0);\n \n try {\n // For accounts with 2-byte discriminator, try to extract what we can\n if (data.length >= 2) {\n return {\n discriminator: data.slice(0, 2),\n // Add more extraction logic here based on known legacy formats\n // This would need to be customized based on actual legacy account structures\n };\n }\n } catch (error) {\n console.warn('Failed to extract legacy data:', error);\n }\n\n return null;\n}\n\n/**\n * Creates a detailed migration report for multiple accounts\n */\nexport async function createMigrationReport(\n accounts: { address: string; encodedAccount: EncodedAccount | MaybeEncodedAccount }[]\n): Promise<{\n summary: {\n total: number;\n valid: number;\n needsMigration: number;\n invalid: number;\n canAutoMigrate: number;\n };\n plans: MigrationPlan[];\n recommendations: string[];\n}> {\n const plans = await Promise.all(accounts.map(({ address, encodedAccount }) => \n createMigrationPlan(encodedAccount, address)\n ));\n\n const summary = {\n total: plans.length,\n valid: plans.filter(p => p.currentState === 'valid').length,\n needsMigration: plans.filter(p => p.currentState === 'needs_migration').length,\n invalid: plans.filter(p => p.currentState === 'invalid').length,\n canAutoMigrate: plans.filter(p => p.canAutoMigrate).length\n };\n\n const recommendations: string[] = [];\n\n if (summary.needsMigration > 0) {\n recommendations.push(`${summary.needsMigration} accounts need migration`);\n }\n\n if (summary.canAutoMigrate > 0) {\n recommendations.push(`${summary.canAutoMigrate} accounts can be auto-migrated`);\n }\n\n if (summary.invalid > 0) {\n recommendations.push(`${summary.invalid} accounts have invalid data and should be investigated`);\n }\n\n if (summary.needsMigration === 0 && summary.invalid === 0) {\n recommendations.push('All accounts are in the correct format');\n } else {\n recommendations.push('Consider running migration utilities to fix account format issues');\n recommendations.push('Backup important account data before migration');\n }\n\n return {\n summary,\n plans,\n recommendations\n };\n}\n\n/**\n * Simulates migration without actually performing it\n */\nexport async function simulateMigration(\n encodedAccount: EncodedAccount | MaybeEncodedAccount,\n address: string\n): Promise<{\n plan: MigrationPlan;\n simulation: {\n wouldSucceed: boolean;\n estimatedSteps: string[];\n warnings: string[];\n requiredActions: string[];\n };\n}> {\n const plan = await createMigrationPlan(encodedAccount, address);\n \n const simulation = {\n wouldSucceed: false,\n estimatedSteps: [] as string[],\n warnings: [] as string[],\n requiredActions: [] as string[]\n };\n\n if (plan.currentState === 'valid') {\n simulation.wouldSucceed = true;\n simulation.estimatedSteps.push('No migration needed - account is already valid');\n return { plan, simulation };\n }\n\n switch (plan.migrationType) {\n case 'recreate':\n simulation.estimatedSteps.push('1. Extract existing account data');\n simulation.estimatedSteps.push('2. Create new account with correct format');\n simulation.estimatedSteps.push('3. Transfer any salvageable data');\n simulation.estimatedSteps.push('4. Close old account');\n simulation.requiredActions.push('User must re-register the agent');\n simulation.warnings.push('Some data may be lost during recreation');\n simulation.wouldSucceed = plan.canAutoMigrate;\n break;\n\n case 'data_conversion':\n simulation.estimatedSteps.push('1. Analyze existing data format');\n simulation.estimatedSteps.push('2. Convert to new format');\n simulation.estimatedSteps.push('3. Update discriminator');\n simulation.warnings.push('Data conversion is experimental');\n simulation.requiredActions.push('Manual verification required');\n simulation.wouldSucceed = false;\n break;\n\n case 'unsupported':\n simulation.estimatedSteps.push('1. Manual investigation required');\n simulation.estimatedSteps.push('2. Determine if account is recoverable');\n simulation.warnings.push('Account may not be recoverable');\n simulation.requiredActions.push('Manual inspection and possible recreation');\n simulation.wouldSucceed = false;\n break;\n\n default:\n simulation.estimatedSteps.push('No migration strategy available');\n simulation.wouldSucceed = false;\n }\n\n return { plan, simulation };\n}\n\n/**\n * Provides user-friendly migration instructions\n */\nexport function getMigrationInstructions(plan: MigrationPlan): string[] {\n const instructions: string[] = [];\n\n switch (plan.migrationType) {\n case 'none':\n instructions.push('✅ No migration needed - your account is up to date');\n break;\n\n case 'recreate':\n instructions.push('🔄 Account Recreation Required:');\n instructions.push('1. Use the CLI command: `ghost agent register` to create a new account');\n instructions.push('2. Configure your agent with the same settings as before');\n instructions.push('3. The old account will be automatically replaced');\n instructions.push('⚠️ Note: You may need to re-verify your agent after recreation');\n break;\n\n case 'data_conversion':\n instructions.push('🔧 Data Conversion Required:');\n instructions.push('1. Contact support for assistance with account conversion');\n instructions.push('2. Manual intervention may be required');\n instructions.push('3. Backup your account data before proceeding');\n break;\n\n case 'unsupported':\n instructions.push('❌ Migration Not Supported:');\n instructions.push('1. This account cannot be automatically migrated');\n instructions.push('2. Consider creating a new account');\n instructions.push('3. Contact support if this account contains important data');\n break;\n }\n\n return instructions;\n}","/**\n * Account Diagnostics Utility\n * \n * Comprehensive diagnostic tools for inspecting and debugging\n * account discriminator issues and data format problems.\n */\n\nimport type { \n Address, \n EncodedAccount, \n MaybeEncodedAccount\n} from '@solana/kit';\n\nimport { \n fetchEncodedAccount\n} from '@solana/kit';\nimport { \n validateAccountDiscriminator, \n inspectAccountData, \n type AccountInspectionResult \n} from './discriminator-validator.js';\nimport { \n createMigrationPlan, \n simulateMigration,\n getMigrationInstructions \n} from './account-migration.js';\nimport { AGENT_DISCRIMINATOR } from '../generated/accounts/agent.js';\n\nexport interface DiagnosticReport {\n address: string;\n timestamp: string;\n accountExists: boolean;\n discriminatorValidation: ReturnType<typeof validateAccountDiscriminator>;\n inspection: AccountInspectionResult;\n migrationPlan: Awaited<ReturnType<typeof createMigrationPlan>>;\n migrationSimulation: Awaited<ReturnType<typeof simulateMigration>>;\n recommendations: string[];\n debugInfo: {\n expectedDiscriminator: number[];\n actualDiscriminator: number[] | null;\n dataPreview: number[];\n programId?: string;\n };\n}\n\nexport interface BatchDiagnosticReport {\n summary: {\n total: number;\n valid: number;\n invalid: number;\n needsMigration: number;\n notExists: number;\n };\n reports: DiagnosticReport[];\n globalRecommendations: string[];\n timestamp: string;\n}\n\n/**\n * Runs comprehensive diagnostics on a single account\n */\nexport async function runAccountDiagnostics(\n encodedAccount: EncodedAccount | MaybeEncodedAccount,\n address: string\n): Promise<DiagnosticReport> {\n const timestamp = new Date().toISOString();\n const accountExists = ('exists' in encodedAccount) && encodedAccount.exists;\n \n let discriminatorValidation, inspection, migrationPlan, migrationSimulation;\n \n if (accountExists) {\n // Import the discriminator\n const { AGENT_DISCRIMINATOR } = await import('../generated/accounts/agent.js');\n discriminatorValidation = validateAccountDiscriminator(encodedAccount.data, AGENT_DISCRIMINATOR);\n inspection = inspectAccountData(encodedAccount, address);\n migrationPlan = await createMigrationPlan(encodedAccount, address);\n migrationSimulation = await simulateMigration(encodedAccount, address);\n } else {\n // Default values for non-existent accounts\n discriminatorValidation = {\n isValid: false,\n actualLength: 0,\n expectedLength: 8,\n canDecode: false,\n needsMigration: false,\n errorMessage: 'Account does not exist'\n };\n inspection = {\n address,\n dataLength: 0,\n discriminator: null,\n discriminatorLength: 0,\n isAgentAccount: false,\n needsMigration: false,\n rawData: new Uint8Array(0)\n };\n migrationPlan = {\n address,\n currentState: 'not_exists' as const,\n migrationType: 'none' as const,\n issues: ['Account does not exist'],\n recommendations: ['Create account using register_agent instruction'],\n canAutoMigrate: false\n };\n migrationSimulation = {\n plan: migrationPlan,\n simulation: {\n wouldSucceed: false,\n estimatedSteps: ['Account must be created first'],\n warnings: [],\n requiredActions: ['Use register_agent instruction']\n }\n };\n }\n\n // Generate recommendations\n const recommendations: string[] = [];\n \n if (!accountExists) {\n recommendations.push('Account does not exist - create using register_agent');\n } else if (discriminatorValidation.isValid) {\n recommendations.push('Account is valid - no action needed');\n } else {\n recommendations.push(...getMigrationInstructions(migrationPlan));\n }\n\n // Create debug info\n const debugInfo = {\n expectedDiscriminator: Array.from(AGENT_DISCRIMINATOR),\n actualDiscriminator: inspection.discriminator ? Array.from(inspection.discriminator) : null,\n dataPreview: Array.from(inspection.rawData.slice(0, 32)),\n programId: (accountExists && ('owner' in encodedAccount) ? encodedAccount.owner : undefined) as string | undefined\n };\n\n return {\n address,\n timestamp,\n accountExists,\n discriminatorValidation,\n inspection,\n migrationPlan,\n migrationSimulation,\n recommendations,\n debugInfo\n };\n}\n\n/**\n * Runs diagnostics on multiple accounts\n */\nexport async function runBatchDiagnostics(\n accounts: { address: string; encodedAccount: EncodedAccount | MaybeEncodedAccount }[]\n): Promise<BatchDiagnosticReport> {\n const timestamp = new Date().toISOString();\n const reports = await Promise.all(accounts.map(({ address, encodedAccount }) => \n runAccountDiagnostics(encodedAccount, address)\n ));\n\n const summary = {\n total: reports.length,\n valid: reports.filter(r => r.accountExists && r.discriminatorValidation.isValid).length,\n invalid: reports.filter(r => r.accountExists && !r.discriminatorValidation.isValid).length,\n needsMigration: reports.filter(r => r.migrationPlan.currentState === 'needs_migration').length,\n notExists: reports.filter(r => !r.accountExists).length\n };\n\n const globalRecommendations: string[] = [];\n \n if (summary.notExists > 0) {\n globalRecommendations.push(`${summary.notExists} accounts need to be created`);\n }\n if (summary.needsMigration > 0) {\n globalRecommendations.push(`${summary.needsMigration} accounts need migration`);\n }\n if (summary.invalid > 0) {\n globalRecommendations.push(`${summary.invalid} accounts have data issues`);\n }\n if (summary.valid === summary.total) {\n globalRecommendations.push('All accounts are healthy');\n }\n\n return {\n summary,\n reports,\n globalRecommendations,\n timestamp\n };\n}\n\n/**\n * Fetches and diagnoses an account directly from the blockchain\n */\nexport async function diagnoseAccountFromChain(\n rpc: Parameters<typeof fetchEncodedAccount>[0],\n address: Address,\n options?: { logToConsole?: boolean }\n): Promise<DiagnosticReport> {\n try {\n const encodedAccount = await fetchEncodedAccount(rpc, address);\n const report = await runAccountDiagnostics(encodedAccount, address);\n \n if (options?.logToConsole) {\n console.group(`🔍 Account Diagnostics: ${address}`);\n console.log('Exists:', report.accountExists);\n console.log('Valid:', report.discriminatorValidation.isValid);\n console.log('Needs Migration:', report.migrationPlan.currentState === 'needs_migration');\n console.log('Recommendations:');\n report.recommendations.forEach(rec => console.log(` - ${rec}`));\n \n if (!report.discriminatorValidation.isValid) {\n console.log('Issues:');\n if (Array.isArray(report.migrationPlan.issues)) {\n report.migrationPlan.issues.forEach((issue: string) => console.log(` - ${issue}`));\n }\n }\n \n console.groupEnd();\n }\n \n return report;\n } catch (err) {\n console.error(`Failed to diagnose account ${address}:`, err);\n \n // Return a diagnostic report for the error case\n return {\n address,\n timestamp: new Date().toISOString(),\n accountExists: false,\n discriminatorValidation: {\n isValid: false,\n actualLength: 0,\n expectedLength: 8,\n canDecode: false,\n needsMigration: false,\n errorMessage: `Failed to fetch account: ${err instanceof Error ? err.message : String(err)}`\n },\n inspection: {\n address,\n dataLength: 0,\n discriminator: null,\n discriminatorLength: 0,\n isAgentAccount: false,\n needsMigration: false,\n rawData: new Uint8Array(0)\n },\n migrationPlan: {\n address,\n currentState: 'invalid',\n migrationType: 'unsupported',\n issues: [`Failed to fetch account: ${err instanceof Error ? err.message : String(err)}`],\n recommendations: ['Check network connection and account address'],\n canAutoMigrate: false\n },\n migrationSimulation: {\n plan: {\n address,\n currentState: 'invalid',\n migrationType: 'unsupported',\n issues: [`Failed to fetch account: ${err instanceof Error ? err.message : String(err)}`],\n recommendations: ['Check network connection and account address'],\n canAutoMigrate: false\n },\n simulation: {\n wouldSucceed: false,\n estimatedSteps: ['Fix network connectivity issues'],\n warnings: ['Account could not be fetched'],\n requiredActions: ['Verify account address and network connection']\n }\n },\n recommendations: ['Check network connection and account address'],\n debugInfo: {\n expectedDiscriminator: Array.from(AGENT_DISCRIMINATOR),\n actualDiscriminator: null,\n dataPreview: [],\n programId: undefined\n }\n };\n }\n}\n\n/**\n * Fetches and diagnoses multiple accounts from the blockchain\n */\nexport async function diagnoseBatchFromChain(\n rpc: Parameters<typeof fetchEncodedAccount>[0],\n addresses: Address[],\n options?: { \n logToConsole?: boolean;\n maxConcurrent?: number;\n }\n): Promise<BatchDiagnosticReport> {\n const maxConcurrent = options?.maxConcurrent ?? 10;\n const reports: DiagnosticReport[] = [];\n \n // Process accounts in batches to avoid overwhelming the RPC\n for (let i = 0; i < addresses.length; i += maxConcurrent) {\n const batch = addresses.slice(i, i + maxConcurrent);\n const batchPromises = batch.map(address => \n diagnoseAccountFromChain(rpc, address, { logToConsole: false })\n );\n \n const batchReports = await Promise.allSettled(batchPromises);\n \n for (const result of batchReports) {\n if (result.status === 'fulfilled') {\n reports.push(result.value);\n } else {\n console.error('Failed to diagnose account:', result.reason);\n // Add a fallback report for failed fetches\n reports.push({\n address: 'unknown',\n timestamp: new Date().toISOString(),\n accountExists: false,\n discriminatorValidation: {\n isValid: false,\n actualLength: 0,\n expectedLength: 8,\n canDecode: false,\n needsMigration: false,\n errorMessage: 'Failed to fetch account'\n },\n inspection: {\n address: 'unknown',\n dataLength: 0,\n discriminator: null,\n discriminatorLength: 0,\n isAgentAccount: false,\n needsMigration: false,\n rawData: new Uint8Array(0)\n },\n migrationPlan: {\n address: 'unknown',\n currentState: 'invalid',\n migrationType: 'unsupported',\n issues: ['Failed to fetch account'],\n recommendations: ['Check network connection'],\n canAutoMigrate: false\n },\n migrationSimulation: {\n plan: {\n address: 'unknown',\n currentState: 'invalid' as const,\n migrationType: 'unsupported' as const,\n issues: ['Failed to fetch account'],\n recommendations: ['Check network connection'],\n canAutoMigrate: false\n },\n simulation: {\n wouldSucceed: false,\n estimatedSteps: ['Fix fetch issues'],\n warnings: ['Account could not be fetched'],\n requiredActions: ['Check network']\n }\n },\n recommendations: ['Check network connection'],\n debugInfo: {\n expectedDiscriminator: Array.from(AGENT_DISCRIMINATOR),\n actualDiscriminator: null,\n dataPreview: [],\n programId: undefined\n }\n });\n }\n }\n }\n\n const batchReport = await runBatchDiagnostics(\n reports.map(report => ({\n address: report.address,\n encodedAccount: {\n exists: report.accountExists,\n data: report.inspection.rawData,\n address: report.address,\n owner: report.debugInfo.programId ?? '',\n executable: false,\n lamports: 0n,\n programAddress: report.debugInfo.programId ?? '',\n space: report.inspection.rawData.length\n } as unknown as EncodedAccount\n }))\n );\n\n if (options?.logToConsole) {\n console.group('🔍 Batch Diagnostics Summary');\n console.log('Total accounts:', batchReport.summary.total);\n console.log('Valid accounts:', batchReport.summary.valid);\n console.log('Invalid accounts:', batchReport.summary.invalid);\n console.log('Need migration:', batchReport.summary.needsMigration);\n console.log('Do not exist:', batchReport.summary.notExists);\n console.log('Global recommendations:');\n batchReport.globalRecommendations.forEach(rec => console.log(` - ${rec}`));\n console.groupEnd();\n }\n\n return batchReport;\n}\n\n/**\n * Exports a diagnostic report as JSON\n */\nexport function exportDiagnosticReport(\n report: DiagnosticReport | BatchDiagnosticReport,\n filename?: string\n): string {\n const json = JSON.stringify(report, null, 2);\n \n if (filename) {\n // In a browser environment, you might want to trigger a download\n // In Node.js, you might want to write to file\n console.log(`Diagnostic report would be saved as: ${filename}`);\n console.log('Report data:', json);\n }\n \n return json;\n}","/**\n * Token Utilities for SPL Token and Token 2022 (Token Extensions)\n * \n * Provides comprehensive token handling utilities including:\n * - Associated Token Account (ATA) derivation for both SPL Token and Token 2022\n * - Token 2022 specific features (transfer fees, confidential transfers, etc.)\n * - Token program detection and validation\n * - Account creation and management utilities\n * \n * Based on the latest SPL Token 2022 specification and @solana/kit v2.3.0\n */\n\nimport type { Address } from '@solana/addresses'\nimport { \n getProgramDerivedAddress,\n getAddressEncoder\n} from '@solana/kit'\nimport { \n TOKEN_PROGRAM_ADDRESS,\n TOKEN_2022_PROGRAM_ADDRESS,\n ASSOCIATED_TOKEN_PROGRAM_ADDRESS \n} from '../constants/system-addresses.js'\n\n// =====================================================\n// TYPES AND INTERFACES\n// =====================================================\n\n/**\n * Token program variants supported by GhostSpeak\n */\nexport enum TokenProgram {\n /** Original SPL Token Program */\n SPL_TOKEN = 'spl-token',\n /** SPL Token 2022 (Token Extensions) Program */\n TOKEN_2022 = 'token-2022'\n}\n\n/**\n * Associated Token Account information\n */\nexport interface AssociatedTokenAccount {\n /** The derived ATA address */\n address: Address\n /** The wallet/owner address */\n owner: Address\n /** The token mint address */\n mint: Address\n /** The token program used (SPL Token or Token 2022) */\n tokenProgram: Address\n /** Whether this is a Token 2022 ATA */\n isToken2022: boolean\n}\n\n/**\n * Token 2022 Extension Types\n * Based on the latest Token Extensions specification\n */\nexport enum TokenExtension {\n /** Uninitialized account */\n UNINITIALIZED = 0,\n /** Transfer fee extension */\n TRANSFER_FEE_CONFIG = 1,\n /** Transfer fee amount */\n TRANSFER_FEE_AMOUNT = 2,\n /** Mint close authority */\n MINT_CLOSE_AUTHORITY = 3,\n /** Confidential transfer mint */\n CONFIDENTIAL_TRANSFER_MINT = 4,\n /** Confidential transfer account */\n CONFIDENTIAL_TRANSFER_ACCOUNT = 5,\n /** Default account state */\n DEFAULT_ACCOUNT_STATE = 6,\n /** Immutable owner */\n IMMUTABLE_OWNER = 7,\n /** Memo transfer */\n MEMO_TRANSFER = 8,\n /** Non-transferable */\n NON_TRANSFERABLE = 9,\n /** Interest bearing mint */\n INTEREST_BEARING_MINT = 10,\n /** CPI guard */\n CPI_GUARD = 11,\n /** Permanent delegate */\n PERMANENT_DELEGATE = 12,\n /** Non-transferable account */\n NON_TRANSFERABLE_ACCOUNT = 13,\n /** Transfer hook */\n TRANSFER_HOOK = 14,\n /** Transfer hook account */\n TRANSFER_HOOK_ACCOUNT = 15,\n /** Metadata pointer */\n METADATA_POINTER = 16,\n /** Token metadata */\n TOKEN_METADATA = 17,\n /** Group pointer */\n GROUP_POINTER = 18,\n /** Token group */\n TOKEN_GROUP = 19,\n /** Group member pointer */\n GROUP_MEMBER_POINTER = 20,\n /** Token group member */\n TOKEN_GROUP_MEMBER = 21\n}\n\n/**\n * Transfer fee configuration for Token 2022\n */\nexport interface TransferFeeConfig {\n /** Transfer fee basis points (0-10000, where 10000 = 100%) */\n transferFeeBasisPoints: number\n /** Maximum transfer fee in token base units */\n maximumFee: bigint\n /** Authority that can modify transfer fee config */\n transferFeeConfigAuthority: Address | null\n /** Authority that can withdraw collected fees */\n withdrawWithheldAuthority: Address | null\n /** Amount of fees currently withheld */\n withheldAmount: bigint\n /** Older transfer fee configuration */\n olderTransferFee: {\n epoch: bigint\n transferFeeBasisPoints: number\n maximumFee: bigint\n }\n /** Newer transfer fee configuration */\n newerTransferFee: {\n epoch: bigint\n transferFeeBasisPoints: number\n maximumFee: bigint\n }\n}\n\n/**\n * Confidential transfer configuration for Token 2022\n */\nexport interface ConfidentialTransferConfig {\n /** Authority that can configure confidential transfers */\n authority: Address | null\n /** Automatically approve new accounts for confidential transfers */\n autoApproveNewAccounts: boolean\n /** Public key for auditing confidential transfers */\n auditorElgamalPubkey: Uint8Array | null\n}\n\n/**\n * Interest-bearing token configuration for Token 2022\n */\nexport interface InterestBearingConfig {\n /** Authority that can update the interest rate */\n rateAuthority: Address | null\n /** Current interest rate (basis points per year) */\n currentRate: number\n /** Timestamp when interest bearing was initialized */\n initializationTimestamp: bigint\n /** Timestamp of last rate update */\n lastUpdateTimestamp: bigint\n /** Pre-computed interest rate */\n preUpdateAverageRate: number\n}\n\n// =====================================================\n// CORE ATA DERIVATION FUNCTIONS\n// =====================================================\n\n/**\n * Derive Associated Token Account address for any token program\n * \n * This is the core ATA derivation function that works with both\n * SPL Token and Token 2022 programs. The derivation follows the\n * standard pattern: ['owner', 'token_program', 'mint']\n * \n * @param owner - The wallet/owner address\n * @param mint - The token mint address\n * @param tokenProgram - The token program address (SPL Token or Token 2022)\n * @returns Promise<Address> - The derived ATA address\n */\nexport async function deriveAssociatedTokenAddress(\n owner: Address,\n mint: Address,\n tokenProgram: Address = TOKEN_PROGRAM_ADDRESS\n): Promise<Address> {\n const [address] = await getProgramDerivedAddress({\n programAddress: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,\n seeds: [\n getAddressEncoder().encode(owner),\n getAddressEncoder().encode(tokenProgram),\n getAddressEncoder().encode(mint)\n ]\n })\n return address\n}\n\n/**\n * Derive Associated Token Account for SPL Token (legacy)\n * \n * @param owner - The wallet/owner address\n * @param mint - The token mint address\n * @returns Promise<Address> - The derived ATA address\n */\nexport async function deriveSplTokenAssociatedTokenAddress(\n owner: Address,\n mint: Address\n): Promise<Address> {\n return deriveAssociatedTokenAddress(owner, mint, TOKEN_PROGRAM_ADDRESS)\n}\n\n/**\n * Derive Associated Token Account for Token 2022\n * \n * @param owner - The wallet/owner address\n * @param mint - The token mint address\n * @returns Promise<Address> - The derived ATA address\n */\nexport async function deriveToken2022AssociatedTokenAddress(\n owner: Address,\n mint: Address\n): Promise<Address> {\n return deriveAssociatedTokenAddress(owner, mint, TOKEN_2022_PROGRAM_ADDRESS)\n}\n\n/**\n * Get complete ATA information including program detection\n * \n * @param owner - The wallet/owner address\n * @param mint - The token mint address\n * @param tokenProgram - Optional: specify token program, auto-detect if not provided\n * @returns Promise<AssociatedTokenAccount> - Complete ATA information\n */\nexport async function getAssociatedTokenAccount(\n owner: Address,\n mint: Address,\n tokenProgram?: Address\n): Promise<AssociatedTokenAccount> {\n // If token program not specified, default to SPL Token\n // In practice, you might want to detect this from the mint account\n const program = tokenProgram ?? TOKEN_PROGRAM_ADDRESS\n const isToken2022 = program === TOKEN_2022_PROGRAM_ADDRESS\n \n const address = await deriveAssociatedTokenAddress(owner, mint, program)\n \n return {\n address,\n owner,\n mint,\n tokenProgram: program,\n isToken2022\n }\n}\n\n// =====================================================\n// TOKEN PROGRAM DETECTION\n// =====================================================\n\n/**\n * Detect which token program owns a given mint\n * Note: This requires RPC calls to fetch mint account data\n * \n * @param mint - The token mint address\n * @returns Promise<Address> - The token program address\n */\nexport async function detectTokenProgram(\n mint: Address, \n rpcEndpoint = 'https://api.devnet.solana.com'\n): Promise<Address> {\n try {\n // Import RPC utilities for account fetching\n const { createSolanaRpc } = await import('@solana/kit')\n const rpc = createSolanaRpc(rpcEndpoint)\n \n // Fetch mint account info with safe base64 encoding\n const accountInfo = await rpc.getAccountInfo(mint, {\n encoding: 'base64',\n commitment: 'confirmed'\n }).send()\n \n if (!accountInfo.value) {\n throw new Error(`Mint account ${mint} not found`)\n }\n \n // Check the owner program - this determines which token program owns the mint\n const ownerProgram = accountInfo.value.owner\n \n // Compare against known token program addresses\n if (ownerProgram === TOKEN_PROGRAM_ADDRESS) {\n return TOKEN_PROGRAM_ADDRESS\n } else if (ownerProgram === TOKEN_2022_PROGRAM_ADDRESS) {\n return TOKEN_2022_PROGRAM_ADDRESS \n } else {\n // Unknown program - default to SPL Token for safety\n console.warn(`Unknown token program owner: ${ownerProgram}, defaulting to SPL Token`)\n return TOKEN_PROGRAM_ADDRESS\n }\n } catch (error) {\n console.error(`Failed to detect token program for mint ${mint}:`, error)\n // Default to SPL Token on error\n return TOKEN_PROGRAM_ADDRESS\n }\n}\n\n/**\n * Check if a mint is a Token 2022 mint\n * \n * @param mint - The token mint address\n * @returns Promise<boolean> - True if Token 2022, false if SPL Token\n */\nexport async function isToken2022Mint(mint: Address): Promise<boolean> {\n const program = await detectTokenProgram(mint)\n return program === TOKEN_2022_PROGRAM_ADDRESS\n}\n\n/**\n * Get the appropriate token program for a given mint\n * \n * @param mint - The token mint address\n * @returns Promise<TokenProgram> - The token program enum\n */\nexport async function getTokenProgramType(mint: Address): Promise<TokenProgram> {\n const isToken2022 = await isToken2022Mint(mint)\n return isToken2022 ? TokenProgram.TOKEN_2022 : TokenProgram.SPL_TOKEN\n}\n\n// =====================================================\n// TOKEN 2022 EXTENSION UTILITIES\n// =====================================================\n\n\n/**\n * Check if a mint has specific Token 2022 extensions\n * Note: This requires RPC calls to fetch and parse mint account data\n * \n * @param mint - The token mint address\n * @param extensions - Array of extensions to check for\n * @returns Promise<Record<TokenExtension, boolean>> - Extension presence map\n */\nexport async function checkToken2022Extensions(\n mint: Address,\n extensions: TokenExtension[],\n _rpcEndpoint = 'https://api.devnet.solana.com'\n): Promise<Record<TokenExtension, boolean>> {\n // Token-2022 extension checking removed - not aligned with VC/Reputation pivot\n console.warn(`Token-2022 extension checking is deprecated: mint ${mint}`)\n const result = {} as Record<TokenExtension, boolean>\n for (const extension of extensions) {\n result[extension] = false\n }\n return result\n}\n\n/**\n * Check if a mint has the transfer fee extension\n * \n * @param mint - The token mint address\n * @param rpcEndpoint - Optional RPC endpoint\n * @returns Promise<boolean> - True if mint has transfer fee extension\n */\nexport async function hasTransferFeeExtension(\n mint: Address,\n rpcEndpoint = 'https://api.devnet.solana.com'\n): Promise<boolean> {\n const result = await checkToken2022Extensions(\n mint,\n [TokenExtension.TRANSFER_FEE_CONFIG],\n rpcEndpoint\n )\n return result[TokenExtension.TRANSFER_FEE_CONFIG]\n}\n\n/**\n * Check if a mint has the confidential transfer extension\n * \n * @param mint - The token mint address\n * @param rpcEndpoint - Optional RPC endpoint\n * @returns Promise<boolean> - True if mint has confidential transfer extension\n */\nexport async function hasConfidentialTransferExtension(\n mint: Address,\n rpcEndpoint = 'https://api.devnet.solana.com'\n): Promise<boolean> {\n const result = await checkToken2022Extensions(\n mint,\n [TokenExtension.CONFIDENTIAL_TRANSFER_MINT],\n rpcEndpoint\n )\n return result[TokenExtension.CONFIDENTIAL_TRANSFER_MINT]\n}\n\n/**\n * Check if a mint has the interest-bearing extension\n * \n * @param mint - The token mint address\n * @param rpcEndpoint - Optional RPC endpoint\n * @returns Promise<boolean> - True if mint has interest-bearing extension\n */\nexport async function hasInterestBearingExtension(\n mint: Address,\n rpcEndpoint = 'https://api.devnet.solana.com'\n): Promise<boolean> {\n const result = await checkToken2022Extensions(\n mint,\n [TokenExtension.INTEREST_BEARING_MINT],\n rpcEndpoint\n )\n return result[TokenExtension.INTEREST_BEARING_MINT]\n}\n\n/**\n * Get transfer fee configuration for a Token 2022 mint\n * \n * @param mint - The Token 2022 mint address\n * @returns Promise<TransferFeeConfig | null> - Transfer fee config or null if not configured\n */\nexport async function getTransferFeeConfig(\n mint: Address,\n _rpcEndpoint = 'https://api.devnet.solana.com'\n): Promise<TransferFeeConfig | null> {\n // Token-2022 extension functions removed - not aligned with VC/Reputation pivot\n console.warn(`Token-2022 getTransferFeeConfig is deprecated: mint ${mint}`)\n return null\n}\n\n/**\n * Get confidential transfer configuration for a Token 2022 mint\n * \n * @param mint - The Token 2022 mint address \n * @returns Promise<ConfidentialTransferConfig | null> - Confidential transfer config or null\n */\nexport async function getConfidentialTransferConfig(\n mint: Address,\n _rpcEndpoint = 'https://api.devnet.solana.com'\n): Promise<ConfidentialTransferConfig | null> {\n // Token-2022 extension functions removed - not aligned with VC/Reputation pivot\n console.warn(`Token-2022 getConfidentialTransferConfig is deprecated: mint ${mint}`)\n return null\n}\n\n/**\n * Get interest-bearing configuration for a Token 2022 mint\n * \n * @param mint - The Token 2022 mint address\n * @returns Promise<InterestBearingConfig | null> - Interest-bearing config or null\n */\nexport async function getInterestBearingConfig(\n mint: Address,\n _rpcEndpoint = 'https://api.devnet.solana.com'\n): Promise<InterestBearingConfig | null> {\n // Token-2022 extension functions removed - not aligned with VC/Reputation pivot\n console.warn(`Token-2022 getInterestBearingConfig is deprecated: mint ${mint}`)\n return null\n}\n\n// =====================================================\n// TOKEN ACCOUNT UTILITIES \n// =====================================================\n\n/**\n * Calculate rent-exempt minimum for a token account with extensions\n * \n * @param extensions - Array of extensions the account will have\n * @returns bigint - Minimum lamports required for rent exemption\n */\nexport function calculateTokenAccountRent(extensions: TokenExtension[] = []): bigint {\n // Base token account size: 165 bytes\n let accountSize = 165\n \n // Add space for each extension (simplified calculation)\n for (const extension of extensions) {\n switch (extension) {\n case TokenExtension.TRANSFER_FEE_AMOUNT:\n accountSize += 8 + 8 // u64 + u64 for withheld amounts\n break\n case TokenExtension.CONFIDENTIAL_TRANSFER_ACCOUNT:\n accountSize += 286 // Complex confidential transfer data\n break\n case TokenExtension.IMMUTABLE_OWNER:\n accountSize += 0 // No additional space needed\n break\n case TokenExtension.MEMO_TRANSFER:\n accountSize += 1 // u8 flag\n break\n case TokenExtension.NON_TRANSFERABLE_ACCOUNT:\n accountSize += 0 // No additional space needed\n break\n case TokenExtension.CPI_GUARD:\n accountSize += 1 // u8 flag\n break\n case TokenExtension.TRANSFER_HOOK_ACCOUNT:\n accountSize += 1 // u8 flag\n break\n default:\n accountSize += 8 // Default additional space for unknown extensions\n }\n }\n \n // Rough calculation: ~6,960 lamports per 128 bytes (current Solana rates)\n // This is a simplified calculation - actual implementation should use RPC\n const lamportsPerByte = BigInt(54) // Approximate current rate\n return BigInt(accountSize) * lamportsPerByte\n}\n\n/**\n * Get all possible ATA addresses for a wallet/mint pair\n * Returns both SPL Token and Token 2022 ATAs\n * \n * @param owner - The wallet/owner address\n * @param mint - The token mint address \n * @returns Promise<{ splToken: Address, token2022: Address }> - Both ATA addresses\n */\nexport async function getAllAssociatedTokenAddresses(\n owner: Address,\n mint: Address\n): Promise<{ splToken: Address, token2022: Address }> {\n const [splToken, token2022] = await Promise.all([\n deriveSplTokenAssociatedTokenAddress(owner, mint),\n deriveToken2022AssociatedTokenAddress(owner, mint)\n ])\n \n return { splToken, token2022 }\n}\n\n/**\n * Validate if an address could be a valid ATA\n * \n * @param address - The address to validate\n * @param owner - The expected owner\n * @param mint - The expected mint \n * @returns Promise<{ isValid: boolean, program?: Address }> - Validation result\n */\nexport async function validateAssociatedTokenAddress(\n address: Address,\n owner: Address,\n mint: Address\n): Promise<{ isValid: boolean, program?: Address }> {\n const addresses = await getAllAssociatedTokenAddresses(owner, mint)\n \n if (address === addresses.splToken) {\n return { isValid: true, program: TOKEN_PROGRAM_ADDRESS }\n }\n \n if (address === addresses.token2022) {\n return { isValid: true, program: TOKEN_2022_PROGRAM_ADDRESS }\n }\n \n return { isValid: false }\n}\n\n// =====================================================\n// HELPER FUNCTIONS\n// =====================================================\n\n/**\n * Convert TokenProgram enum to program address\n * \n * @param program - The token program enum\n * @returns Address - The program address\n */\nexport function getTokenProgramAddress(program: TokenProgram): Address {\n switch (program) {\n case TokenProgram.SPL_TOKEN:\n return TOKEN_PROGRAM_ADDRESS\n case TokenProgram.TOKEN_2022:\n return TOKEN_2022_PROGRAM_ADDRESS\n default:\n throw new Error(`Unknown token program: ${program}`)\n }\n}\n\n/**\n * Convert program address to TokenProgram enum\n * \n * @param address - The program address\n * @returns TokenProgram - The token program enum\n */\nexport function getTokenProgramFromAddress(address: Address): TokenProgram {\n if (address === TOKEN_PROGRAM_ADDRESS) {\n return TokenProgram.SPL_TOKEN\n }\n if (address === TOKEN_2022_PROGRAM_ADDRESS) {\n return TokenProgram.TOKEN_2022\n }\n throw new Error(`Unknown token program address: ${address}`)\n}\n\n/**\n * Format token amount with proper decimals\n * \n * @param amount - Raw token amount (in base units)\n * @param decimals - Number of decimal places for the token\n * @returns string - Formatted amount\n */\nexport function formatTokenAmount(amount: bigint, decimals: number): string {\n const divisor = BigInt(10 ** decimals)\n const quotient = amount / divisor\n const remainder = amount % divisor\n \n if (remainder === BigInt(0)) {\n return quotient.toString()\n }\n \n const remainderStr = remainder.toString().padStart(decimals, '0')\n const trimmedRemainder = remainderStr.replace(/0+$/, '')\n \n return `${quotient}.${trimmedRemainder}`\n}\n\n/**\n * Parse formatted token amount to raw base units\n * \n * @param formatted - Formatted token amount string\n * @param decimals - Number of decimal places for the token\n * @returns bigint - Raw token amount\n */\nexport function parseTokenAmount(formatted: string, decimals: number): bigint {\n const [whole, fraction = ''] = formatted.split('.')\n const paddedFraction = fraction.padEnd(decimals, '0').slice(0, decimals)\n const rawAmount = whole + paddedFraction\n return BigInt(rawAmount)\n}\n\n/**\n * Get token extension data from mint account\n * \n * @param mintData - The mint account data from getMintWithExtensions\n * @param extensionType - The extension type to get\n * @returns Extension data or null if not found\n */\nexport function getTokenExtensionData(\n mintData: { extensions?: Record<string, unknown> } | null,\n extensionType: TokenExtension\n): Buffer | null {\n if (!mintData?.extensions) {\n return null\n }\n\n // Map extension type enum to string keys used in the parsed extensions\n const extensionKeys: Record<TokenExtension, string> = {\n [TokenExtension.UNINITIALIZED]: 'uninitialized',\n [TokenExtension.TRANSFER_FEE_CONFIG]: 'transferFeeConfig',\n [TokenExtension.TRANSFER_FEE_AMOUNT]: 'transferFeeAmount',\n [TokenExtension.MINT_CLOSE_AUTHORITY]: 'mintCloseAuthority',\n [TokenExtension.CONFIDENTIAL_TRANSFER_MINT]: 'confidentialTransferMint',\n [TokenExtension.CONFIDENTIAL_TRANSFER_ACCOUNT]: 'confidentialTransferAccount',\n [TokenExtension.DEFAULT_ACCOUNT_STATE]: 'defaultAccountState',\n [TokenExtension.IMMUTABLE_OWNER]: 'immutableOwner',\n [TokenExtension.MEMO_TRANSFER]: 'memoTransfer',\n [TokenExtension.NON_TRANSFERABLE]: 'nonTransferable',\n [TokenExtension.INTEREST_BEARING_MINT]: 'interestBearingConfig',\n [TokenExtension.CPI_GUARD]: 'cpiGuard',\n [TokenExtension.PERMANENT_DELEGATE]: 'permanentDelegate',\n [TokenExtension.NON_TRANSFERABLE_ACCOUNT]: 'nonTransferableAccount',\n [TokenExtension.TRANSFER_HOOK]: 'transferHook',\n [TokenExtension.TRANSFER_HOOK_ACCOUNT]: 'transferHookAccount',\n [TokenExtension.METADATA_POINTER]: 'metadataPointer',\n [TokenExtension.TOKEN_METADATA]: 'tokenMetadata',\n [TokenExtension.GROUP_POINTER]: 'groupPointer',\n [TokenExtension.TOKEN_GROUP]: 'tokenGroup',\n [TokenExtension.GROUP_MEMBER_POINTER]: 'groupMemberPointer',\n [TokenExtension.TOKEN_GROUP_MEMBER]: 'tokenGroupMember'\n }\n\n const extensionKey = extensionKeys[extensionType]\n const extensionData = mintData.extensions[extensionKey]\n\n if (!extensionData) {\n return null\n }\n\n // Convert extension data to Buffer for backward compatibility\n // In the future, we might want to return the parsed data directly\n try {\n return Buffer.from(JSON.stringify(extensionData))\n } catch {\n return null\n }\n}\n\n/**\n * Parse transfer fee configuration from extension data\n * \n * @param extensionData - The raw extension data or parsed extension object\n * @returns TransferFeeConfig - Parsed transfer fee configuration\n */\nexport function parseTransferFeeConfig(\n extensionData: Buffer | unknown\n): TransferFeeConfig {\n try {\n let parsedData: unknown\n\n // Handle both Buffer (from getTokenExtensionData) and direct parsed data\n if (Buffer.isBuffer(extensionData)) {\n const dataStr = extensionData.toString()\n parsedData = JSON.parse(dataStr)\n } else {\n parsedData = extensionData\n }\n\n // Type guard and validation for transfer fee config structure\n if (parsedData && typeof parsedData === 'object') {\n const config = parsedData as {\n transferFeeBasisPoints?: number\n maximumFee?: bigint | string | number\n transferFeeConfigAuthority?: Address | null | string\n withdrawWithheldAuthority?: Address | null | string\n }\n\n return {\n transferFeeBasisPoints: config.transferFeeBasisPoints ?? 0,\n maximumFee: typeof config.maximumFee === 'bigint' \n ? config.maximumFee \n : BigInt(config.maximumFee ?? 0),\n transferFeeConfigAuthority: config.transferFeeConfigAuthority as Address | null ?? null,\n withdrawWithheldAuthority: config.withdrawWithheldAuthority as Address | null ?? null,\n withheldAmount: BigInt(0),\n olderTransferFee: {\n epoch: BigInt(0),\n transferFeeBasisPoints: 0,\n maximumFee: BigInt(0)\n },\n newerTransferFee: {\n epoch: BigInt(1),\n transferFeeBasisPoints: config.transferFeeBasisPoints ?? 0,\n maximumFee: typeof config.maximumFee === 'bigint' \n ? config.maximumFee \n : BigInt(config.maximumFee ?? 0)\n }\n }\n }\n } catch (error) {\n console.warn('Failed to parse transfer fee config:', error)\n }\n\n // Return default config if parsing fails\n return {\n transferFeeBasisPoints: 0,\n maximumFee: BigInt(0),\n transferFeeConfigAuthority: null,\n withdrawWithheldAuthority: null,\n withheldAmount: BigInt(0),\n olderTransferFee: {\n epoch: BigInt(0),\n transferFeeBasisPoints: 0,\n maximumFee: BigInt(0)\n },\n newerTransferFee: {\n epoch: BigInt(1),\n transferFeeBasisPoints: 0,\n maximumFee: BigInt(0)\n }\n }\n}\n\n/**\n * Fetch transfer fee configuration for a Token-2022 mint via RPC\n * \n * @deprecated Token-2022 extension functions removed - not aligned with VC/Reputation pivot\n * @param _rpc - RPC client for making requests\n * @param mint - The mint address to query\n * @returns Promise<TransferFeeConfig | null> - Always returns null (deprecated)\n */\nexport async function fetchTransferFeeConfig(\n _rpc: unknown,\n mint: Address\n): Promise<TransferFeeConfig | null> {\n console.warn(`Token-2022 fetchTransferFeeConfig is deprecated: mint ${mint}`)\n return null\n}\n\n/**\n * Check if a mint has transfer fees enabled\n * \n * @deprecated Token-2022 extension functions removed - not aligned with VC/Reputation pivot\n * @param _rpc - RPC client for making requests \n * @param mint - The mint address to check\n * @returns Promise<boolean> - Always returns false (deprecated)\n */\nexport async function hasTransferFees(\n _rpc: unknown,\n mint: Address\n): Promise<boolean> {\n console.warn(`Token-2022 hasTransferFees is deprecated: mint ${mint}`)\n return false\n}","/**\n * Governance Helper Utilities\n * \n * Comprehensive utilities for RBAC management, multi-signature wallets,\n * proposal lifecycle, and voting mechanisms.\n */\n\nimport type { Address } from '@solana/kit'\nimport { getAddressEncoder, getProgramDerivedAddress, getBytesEncoder } from '@solana/kit'\nimport {\n ProposalStatus,\n VoteChoice,\n // type Multisig, // TODO: Re-enable after multisig account is regenerated\n type GovernanceProposal,\n // type RbacConfig, // TODO: Re-enable after rbacConfig account is regenerated\n // type Role, // TODO: Re-enable after role type is regenerated\n type VotingResults,\n type QuorumRequirements\n} from '../generated/index.js'\n\n// =====================================================\n// PDA DERIVATION\n// =====================================================\n\n/**\n * Derive multisig account PDA\n */\nexport async function deriveMultisigPda(\n programId: Address,\n authority: Address,\n multisigId: bigint\n): Promise<Address> {\n const [pda] = await getProgramDerivedAddress({\n programAddress: programId,\n seeds: [\n getBytesEncoder().encode(new Uint8Array([109, 117, 108, 116, 105, 115, 105, 103])), // 'multisig'\n getAddressEncoder().encode(authority),\n new Uint8Array(new BigUint64Array([multisigId]).buffer)\n ]\n })\n return pda\n}\n\n/**\n * Derive proposal account PDA\n */\nexport async function deriveProposalPda(\n programId: Address,\n multisig: Address,\n proposalId: bigint\n): Promise<Address> {\n const [pda] = await getProgramDerivedAddress({\n programAddress: programId,\n seeds: [\n getBytesEncoder().encode(new Uint8Array([112, 114, 111, 112, 111, 115, 97, 108])), // 'proposal'\n getAddressEncoder().encode(multisig),\n new Uint8Array(new BigUint64Array([proposalId]).buffer)\n ]\n })\n return pda\n}\n\n/**\n * Derive RBAC account PDA\n */\nexport async function deriveRbacPda(\n programId: Address,\n admin: Address\n): Promise<Address> {\n const [pda] = await getProgramDerivedAddress({\n programAddress: programId,\n seeds: [\n getBytesEncoder().encode(new Uint8Array([114, 98, 97, 99])), // 'rbac'\n getAddressEncoder().encode(admin)\n ]\n })\n return pda\n}\n\n// =====================================================\n// MULTISIG UTILITIES\n// =====================================================\n// TODO: Re-enable after multisig account is regenerated\n// MultisigUtils class removed due to missing Multisig type dependency\n\n// =====================================================\n// PROPOSAL UTILITIES\n// =====================================================\n\nexport class ProposalUtils {\n /**\n * Check if proposal is in voting period\n */\n static isVotingOpen(proposal: GovernanceProposal): boolean {\n const now = BigInt(Math.floor(Date.now() / 1000))\n return proposal.status === ProposalStatus.Active &&\n now >= proposal.votingStartsAt &&\n now <= proposal.votingEndsAt\n }\n\n /**\n * Check if proposal has expired\n */\n static hasExpired(proposal: GovernanceProposal): boolean {\n const now = BigInt(Math.floor(Date.now() / 1000))\n return now > proposal.votingEndsAt\n }\n\n /**\n * Calculate time remaining for voting\n */\n static timeRemaining(proposal: GovernanceProposal): bigint {\n const now = BigInt(Math.floor(Date.now() / 1000))\n if (now >= proposal.votingEndsAt) return 0n\n return proposal.votingEndsAt - now\n }\n\n /**\n * Format time remaining as human-readable string\n */\n static formatTimeRemaining(proposal: GovernanceProposal): string {\n const remaining = this.timeRemaining(proposal)\n if (remaining === 0n) return 'Voting ended'\n\n const seconds = Number(remaining)\n const days = Math.floor(seconds / 86400)\n const hours = Math.floor((seconds % 86400) / 3600)\n const minutes = Math.floor((seconds % 3600) / 60)\n\n if (days > 0) return `${days}d ${hours}h remaining`\n if (hours > 0) return `${hours}h ${minutes}m remaining`\n return `${minutes}m remaining`\n }\n\n /**\n * Calculate if proposal has reached quorum\n */\n static hasReachedQuorum(\n votingResults: VotingResults,\n quorumRequirements: QuorumRequirements,\n totalEligibleVoters: number\n ): boolean {\n const totalVotes = Number(votingResults.votesFor + votingResults.votesAgainst + votingResults.votesAbstain)\n const participationRate = (totalVotes / totalEligibleVoters) * 100\n \n return participationRate >= quorumRequirements.minimumParticipation\n }\n\n /**\n * Calculate voting results summary\n */\n static calculateResults(votingResults: VotingResults): {\n total: number\n forPercentage: number\n againstPercentage: number\n abstainPercentage: number\n passed: boolean\n } {\n const total = Number(votingResults.votesFor + votingResults.votesAgainst + votingResults.votesAbstain)\n \n if (total === 0) {\n return {\n total: 0,\n forPercentage: 0,\n againstPercentage: 0,\n abstainPercentage: 0,\n passed: false\n }\n }\n\n const forPercentage = (Number(votingResults.votesFor) / total) * 100\n const againstPercentage = (Number(votingResults.votesAgainst) / total) * 100\n const abstainPercentage = (Number(votingResults.votesAbstain) / total) * 100\n \n // Simple majority (>50% for votes)\n const passed = votingResults.votesFor > votingResults.votesAgainst\n\n return {\n total,\n forPercentage,\n againstPercentage,\n abstainPercentage,\n passed\n }\n }\n\n /**\n * Validate proposal\n */\n static validateProposal(proposal: GovernanceProposal): { valid: boolean; error?: string } {\n if (!proposal.title || proposal.title.trim().length === 0) {\n return { valid: false, error: 'Title is required' }\n }\n\n if (proposal.title.length > 100) {\n return { valid: false, error: 'Title cannot exceed 100 characters' }\n }\n\n if (!proposal.description || proposal.description.trim().length === 0) {\n return { valid: false, error: 'Description is required' }\n }\n\n if (proposal.description.length > 5000) {\n return { valid: false, error: 'Description cannot exceed 5000 characters' }\n }\n\n return { valid: true }\n }\n}\n\n// =====================================================\n// RBAC UTILITIES\n// =====================================================\n// TODO: Re-enable after rbacConfig account is regenerated\n// RbacUtils class removed due to missing RbacConfig type dependency\n\n// =====================================================\n// VOTING UTILITIES\n// =====================================================\n\nexport class VotingUtils {\n /**\n * Calculate vote weight based on token holdings or other factors\n */\n static calculateVoteWeight(\n baseWeight: number,\n tokenBalance?: bigint,\n stakeDuration?: bigint\n ): number {\n let weight = baseWeight\n\n // Apply token-based multiplier\n if (tokenBalance) {\n const tokenMultiplier = Math.min(Number(tokenBalance / 1000000n), 10) // Cap at 10x\n weight *= tokenMultiplier\n }\n\n // Apply time-based multiplier\n if (stakeDuration) {\n const daysStaked = Number(stakeDuration / 86400n)\n const timeMultiplier = 1 + (daysStaked / 365) // +100% per year\n weight *= timeMultiplier\n }\n\n return Math.floor(weight)\n }\n\n /**\n * Format vote choice as string\n */\n static formatVoteChoice(voteChoice: VoteChoice): string {\n switch (voteChoice) {\n case VoteChoice.For:\n return '✅ For'\n case VoteChoice.Against:\n return '❌ Against'\n case VoteChoice.Abstain:\n return '🤷 Abstain'\n default:\n return 'Unknown'\n }\n }\n\n /**\n * Calculate if simple majority is reached\n */\n static hasSimpleMajority(votingResults: VotingResults): boolean {\n return votingResults.votesFor > votingResults.votesAgainst\n }\n\n /**\n * Calculate if supermajority is reached (2/3)\n */\n static hasSupermajority(votingResults: VotingResults): boolean {\n const totalVotes = votingResults.votesFor + votingResults.votesAgainst\n if (totalVotes === 0n) return false\n \n const forPercentage = Number(votingResults.votesFor) / Number(totalVotes)\n return forPercentage >= 0.667\n }\n}\n\n// =====================================================\n// PERMISSION TEMPLATES\n// =====================================================\n\nexport const PERMISSION_TEMPLATES = {\n // Admin permissions\n ADMIN: {\n CREATE_PROPOSAL: { action: 'create', resource: 'proposal' },\n EXECUTE_PROPOSAL: { action: 'execute', resource: 'proposal' },\n MANAGE_ROLES: { action: 'manage', resource: 'roles' },\n MANAGE_TREASURY: { action: 'manage', resource: 'treasury' }\n },\n \n // Member permissions\n MEMBER: {\n VOTE: { action: 'vote', resource: 'proposal' },\n VIEW: { action: 'view', resource: 'all' },\n COMMENT: { action: 'comment', resource: 'proposal' }\n },\n \n // Moderator permissions\n MODERATOR: {\n CANCEL_PROPOSAL: { action: 'cancel', resource: 'proposal' },\n MODERATE_COMMENTS: { action: 'moderate', resource: 'comments' },\n VIEW_REPORTS: { action: 'view', resource: 'reports' }\n }\n}\n\n// =====================================================\n// ROLE TEMPLATES\n// =====================================================\n\nexport const ROLE_TEMPLATES = {\n ADMIN: {\n name: 'Administrator',\n description: 'Full administrative access',\n permissions: Object.values(PERMISSION_TEMPLATES.ADMIN)\n },\n \n MEMBER: {\n name: 'Member',\n description: 'Standard member access',\n permissions: Object.values(PERMISSION_TEMPLATES.MEMBER)\n },\n \n MODERATOR: {\n name: 'Moderator',\n description: 'Content moderation access',\n permissions: [\n ...Object.values(PERMISSION_TEMPLATES.MEMBER),\n ...Object.values(PERMISSION_TEMPLATES.MODERATOR)\n ]\n }\n}\n\n// =====================================================\n// GOVERNANCE ANALYTICS\n// =====================================================\n\nexport interface GovernanceAnalytics {\n totalProposals: number\n activeProposals: number\n passedProposals: number\n failedProposals: number\n averageVoterTurnout: number\n topVoters: { address: Address; voteCount: number }[]\n proposalCategories: { category: string; count: number }[]\n}\n\nexport class GovernanceAnalyticsUtils {\n /**\n * Calculate governance health score (0-100)\n */\n static calculateHealthScore(analytics: GovernanceAnalytics): number {\n let score = 0\n\n // Voter turnout (40 points max)\n score += Math.min(analytics.averageVoterTurnout * 0.4, 40)\n\n // Proposal success rate (30 points max)\n const totalCompleted = analytics.passedProposals + analytics.failedProposals\n if (totalCompleted > 0) {\n const successRate = analytics.passedProposals / totalCompleted\n score += successRate * 30\n }\n\n // Activity level (30 points max)\n const activityRatio = analytics.activeProposals / Math.max(analytics.totalProposals, 1)\n score += Math.min(activityRatio * 60, 30)\n\n return Math.round(score)\n }\n\n /**\n * Generate governance summary report\n */\n static generateSummaryReport(analytics: GovernanceAnalytics): string {\n const healthScore = this.calculateHealthScore(analytics)\n const successRate = analytics.totalProposals > 0\n ? Math.round((analytics.passedProposals / analytics.totalProposals) * 100)\n : 0\n\n return `\nGovernance Summary:\n- Total Proposals: ${analytics.totalProposals}\n- Active: ${analytics.activeProposals}\n- Success Rate: ${successRate}%\n- Avg Turnout: ${Math.round(analytics.averageVoterTurnout)}%\n- Health Score: ${healthScore}/100\n `.trim()\n }\n}","/**\n * Feature Flags for GhostSpeak Protocol\n * \n * Centralized feature flag management for enabling/disabling features\n * based on network conditions and protocol status.\n */\n\nexport interface FeatureFlags {\n /** Enable confidential transfers (currently in beta) */\n CONFIDENTIAL_TRANSFERS_ENABLED: boolean\n \n /** Use client-side encryption as fallback */\n USE_CLIENT_ENCRYPTION: boolean\n \n /** Enable IPFS integration for private metadata */\n ENABLE_IPFS_STORAGE: boolean\n \n /** Enable compressed NFTs for agents */\n ENABLE_COMPRESSED_AGENTS: boolean\n \n /** Enable governance features */\n ENABLE_GOVERNANCE: boolean\n \n /** Enable analytics collection */\n ENABLE_ANALYTICS: boolean\n \n /** Show beta/experimental features in UI */\n SHOW_EXPERIMENTAL_FEATURES: boolean\n}\n\n/**\n * Default feature flags for production\n */\nexport const DEFAULT_FLAGS: FeatureFlags = {\n // Privacy features using client-side encryption\n CONFIDENTIAL_TRANSFERS_ENABLED: true,\n USE_CLIENT_ENCRYPTION: true,\n ENABLE_IPFS_STORAGE: true,\n \n // Enabled features\n ENABLE_COMPRESSED_AGENTS: true,\n ENABLE_GOVERNANCE: true,\n ENABLE_ANALYTICS: true,\n \n // UI/UX\n SHOW_EXPERIMENTAL_FEATURES: false\n}\n\n/**\n * Development feature flags (all features enabled)\n */\nexport const DEV_FLAGS: FeatureFlags = {\n CONFIDENTIAL_TRANSFERS_ENABLED: true,\n USE_CLIENT_ENCRYPTION: true,\n ENABLE_IPFS_STORAGE: true,\n ENABLE_COMPRESSED_AGENTS: true,\n ENABLE_GOVERNANCE: true,\n ENABLE_ANALYTICS: true,\n SHOW_EXPERIMENTAL_FEATURES: true\n}\n\n/**\n * Feature flag manager\n */\nexport class FeatureFlagManager {\n private flags: FeatureFlags\n private overrides: Partial<FeatureFlags> = {}\n \n constructor(environment: 'production' | 'development' = 'production') {\n this.flags = environment === 'development' ? { ...DEV_FLAGS } : { ...DEFAULT_FLAGS }\n this.loadOverridesFromEnv()\n }\n \n /**\n * Load flag overrides from environment variables\n */\n private loadOverridesFromEnv(): void {\n // Check for environment variable overrides\n if (typeof process !== 'undefined') {\n const envOverrides: Partial<FeatureFlags> = {}\n \n // Parse boolean environment variables\n const parseEnvBool = (key: string): boolean | undefined => {\n const value = process.env[key]\n if (value === undefined) return undefined\n return value.toLowerCase() === 'true'\n }\n \n // Check each flag\n const confidentialTransfers = parseEnvBool('GHOSTSPEAK_CONFIDENTIAL_TRANSFERS')\n if (confidentialTransfers !== undefined) {\n envOverrides.CONFIDENTIAL_TRANSFERS_ENABLED = confidentialTransfers\n }\n \n const useClientEncryption = parseEnvBool('GHOSTSPEAK_USE_CLIENT_ENCRYPTION')\n if (useClientEncryption !== undefined) {\n envOverrides.USE_CLIENT_ENCRYPTION = useClientEncryption\n }\n \n this.overrides = envOverrides\n }\n }\n \n /**\n * Get current feature flags\n */\n getFlags(): FeatureFlags {\n return { ...this.flags, ...this.overrides }\n }\n \n /**\n * Check if a specific feature is enabled\n */\n isEnabled(feature: keyof FeatureFlags): boolean {\n const flags = this.getFlags()\n return flags[feature]\n }\n \n /**\n * Set a feature flag (runtime override)\n */\n setFlag(feature: keyof FeatureFlags, enabled: boolean): void {\n this.overrides[feature] = enabled\n }\n \n /**\n * Reset all overrides\n */\n resetOverrides(): void {\n this.overrides = {}\n this.loadOverridesFromEnv()\n }\n \n /**\n * Get privacy feature status\n */\n getPrivacyStatus(): {\n mode: 'client-encryption' | 'disabled'\n beta: boolean\n message: string\n } {\n const flags = this.getFlags()\n \n if (!flags.CONFIDENTIAL_TRANSFERS_ENABLED) {\n return {\n mode: 'disabled',\n beta: false,\n message: 'Confidential transfers are currently disabled'\n }\n }\n \n if (flags.USE_CLIENT_ENCRYPTION) {\n return {\n mode: 'client-encryption',\n beta: false,\n message: 'Confidential transfers using client-side encryption (Production)'\n }\n }\n \n return {\n mode: 'disabled',\n beta: false,\n message: 'No privacy features enabled'\n }\n }\n \n /**\n * Check if we should use client encryption\n */\n shouldUseClientEncryption(): boolean {\n const flags = this.getFlags()\n return flags.CONFIDENTIAL_TRANSFERS_ENABLED && \n flags.USE_CLIENT_ENCRYPTION\n }\n}\n\n// Global instance\nlet globalFeatureFlags: FeatureFlagManager | null = null\n\n/**\n * Get or create the global feature flag manager\n */\nexport function getFeatureFlags(environment?: 'production' | 'development'): FeatureFlagManager {\n globalFeatureFlags ??= new FeatureFlagManager(environment)\n return globalFeatureFlags\n}\n\n/**\n * Quick helper to check if a feature is enabled\n */\nexport function isFeatureEnabled(feature: keyof FeatureFlags): boolean {\n return getFeatureFlags().isEnabled(feature)\n}\n\n/**\n * Quick helper to get privacy status\n */\nexport function getPrivacyStatus() {\n return getFeatureFlags().getPrivacyStatus()\n}","/**\n * Client-Side Encryption Service\n * \n * Provides production-ready client-side encryption for privacy features \n * using ElGamal encryption and x402 verification.\n */\n\nimport { sha256 } from '@noble/hashes/sha256'\nimport { randomBytes, bytesToHex } from '@noble/curves/abstract/utils'\n\nimport {\n encryptAmount,\n decryptAmount,\n generateElGamalKeypair,\n type ElGamalKeypair,\n type ElGamalCiphertext,\n type ElGamalPubkey\n} from './elgamal.js'\n\nimport { getFeatureFlags } from './feature-flags.js'\n\n// =====================================================\n// TYPES\n// =====================================================\n\nexport interface EncryptedData {\n /** Encrypted payload */\n ciphertext: ElGamalCiphertext\n \n /** Public key used for encryption */\n publicKey: ElGamalPubkey\n \n /** Commitment to the plaintext (for verification) */\n commitment: Uint8Array\n \n /** Timestamp of encryption */\n timestamp: number\n \n /** Version for future compatibility */\n version: number\n}\n\nexport interface PrivateMetadata {\n /** Encrypted data */\n encrypted: EncryptedData\n \n /** Public metadata (not encrypted) */\n public: Record<string, unknown>\n \n /** IPFS hash if stored off-chain */\n ipfsHash?: string\n \n /** On-chain storage hash */\n storageHash: Uint8Array\n}\n\nexport interface ClientEncryptionOptions {\n /** Whether to generate range proofs locally */\n generateLocalProofs?: boolean\n \n /** Whether to store on IPFS */\n useIpfsStorage?: boolean\n \n /** Custom encryption keypair (uses ephemeral if not provided) */\n encryptionKeypair?: ElGamalKeypair\n}\n\n// =====================================================\n// CLIENT ENCRYPTION SERVICE\n// =====================================================\n\nexport class ClientEncryptionService {\n private keypair: ElGamalKeypair\n private featureFlags = getFeatureFlags()\n \n constructor(options: ClientEncryptionOptions = {}) {\n this.keypair = options.encryptionKeypair ?? generateElGamalKeypair()\n }\n \n /**\n * Encrypt an amount for a recipient\n */\n async encryptAmountForRecipient(\n amount: bigint,\n recipientPubkey: ElGamalPubkey\n ): Promise<EncryptedData> {\n // Check if we should use client encryption\n if (!this.featureFlags.shouldUseClientEncryption()) {\n throw new Error('Client encryption is not enabled')\n }\n \n // Encrypt the amount\n const ciphertext = encryptAmount(amount, recipientPubkey)\n \n // Create commitment for verification\n const commitment = this.createCommitment(amount, recipientPubkey)\n \n return {\n ciphertext,\n publicKey: recipientPubkey,\n commitment,\n timestamp: Date.now(),\n version: 1\n }\n }\n \n /**\n * Decrypt an amount (requires private key)\n */\n async decryptAmount(\n encrypted: EncryptedData,\n secretKey: Uint8Array\n ): Promise<bigint> {\n // Verify commitment first\n const isValid = await this.verifyCommitment(encrypted)\n if (!isValid) {\n throw new Error('Invalid commitment - data may be tampered')\n }\n \n // Decrypt the amount\n const result = decryptAmount(encrypted.ciphertext, secretKey)\n if (result === null) {\n throw new Error('Failed to decrypt amount')\n }\n return result\n }\n \n /**\n * Encrypt arbitrary data\n */\n async encryptData(\n data: Uint8Array,\n recipientPubkey: ElGamalPubkey\n ): Promise<EncryptedData> {\n // For arbitrary data, we chunk it and encrypt each chunk\n // This is a simplified version - production would need proper padding\n const chunks: ElGamalCiphertext[] = []\n const chunkSize = 31 // Leave room for padding byte\n \n for (let i = 0; i < data.length; i += chunkSize) {\n const chunk = data.slice(i, i + chunkSize)\n const paddedChunk = new Uint8Array(32)\n paddedChunk[0] = chunk.length // Length prefix\n paddedChunk.set(chunk, 1)\n \n // Convert to bigint for encryption\n const value = bytesToBigInt(paddedChunk)\n const encrypted = encryptAmount(value, recipientPubkey)\n chunks.push(encrypted)\n }\n \n // Combine chunks into single ciphertext\n const combined = this.combineChunks(chunks)\n const commitment = this.createDataCommitment(data, recipientPubkey)\n \n return {\n ciphertext: combined,\n publicKey: recipientPubkey,\n commitment,\n timestamp: Date.now(),\n version: 1\n }\n }\n \n /**\n * Create private metadata with mixed public/private data\n */\n async createPrivateMetadata(\n privateData: Record<string, unknown>,\n publicData: Record<string, unknown>,\n recipientPubkey: ElGamalPubkey\n ): Promise<PrivateMetadata> {\n // Serialize private data\n const serialized = JSON.stringify(privateData)\n const dataBytes = new TextEncoder().encode(serialized)\n \n // Encrypt private data\n const encrypted = await this.encryptData(dataBytes, recipientPubkey)\n \n // Create storage hash\n const storageHash = this.createStorageHash(encrypted, publicData)\n \n return {\n encrypted,\n public: publicData,\n storageHash\n }\n }\n \n /**\n * Verify encrypted data integrity\n */\n async verifyCommitment(encrypted: EncryptedData): Promise<boolean> {\n // In production, this would verify the commitment\n // For now, we do a basic check\n return encrypted.commitment.length === 32 && \n encrypted.version === 1 &&\n encrypted.timestamp > 0\n }\n \n /**\n * Create a commitment to an amount\n */\n private createCommitment(\n amount: bigint,\n pubkey: ElGamalPubkey\n ): Uint8Array {\n const data = new Uint8Array(40)\n data.set(bigIntToBytes(amount), 0)\n data.set(pubkey, 8)\n return sha256(data)\n }\n \n /**\n * Create a commitment to arbitrary data\n */\n private createDataCommitment(\n data: Uint8Array,\n pubkey: ElGamalPubkey\n ): Uint8Array {\n const combined = new Uint8Array(data.length + 32)\n combined.set(data, 0)\n combined.set(pubkey, data.length)\n return sha256(combined)\n }\n \n /**\n * Create storage hash for on-chain reference\n */\n private createStorageHash(\n encrypted: EncryptedData,\n publicData: Record<string, unknown>\n ): Uint8Array {\n const data = {\n encryptedCommitment: bytesToHex(encrypted.commitment),\n publicData,\n timestamp: encrypted.timestamp,\n version: encrypted.version\n }\n \n const serialized = JSON.stringify(data)\n return sha256(new TextEncoder().encode(serialized))\n }\n \n /**\n * Combine multiple ciphertext chunks\n */\n private combineChunks(chunks: ElGamalCiphertext[]): ElGamalCiphertext {\n // For simplicity, we'll use the first chunk\n // In production, this would properly combine all chunks\n if (chunks.length === 0) {\n throw new Error('No chunks to combine')\n }\n return chunks[0]\n }\n}\n\n// =====================================================\n// HELPER FUNCTIONS\n// =====================================================\n\n/**\n * Convert bigint to 32-byte array\n */\nfunction bigIntToBytes(value: bigint): Uint8Array {\n const bytes = new Uint8Array(32)\n let temp = value\n for (let i = 0; i < 32; i++) {\n bytes[i] = Number(temp & 0xffn)\n temp >>= BigInt(8)\n }\n return bytes\n}\n\n/**\n * Convert byte array to bigint\n */\nfunction bytesToBigInt(bytes: Uint8Array): bigint {\n let result = BigInt(0)\n for (let i = bytes.length - 1; i >= 0; i--) {\n result = (result << BigInt(8)) | BigInt(bytes[i])\n }\n return result\n}\n\n// =====================================================\n// PRIVACY VERIFICATION\n// =====================================================\n\n/**\n * Generate a local privacy proof (verified via x402 consensus)\n * This provides cryptographic commitment without on-chain proofs\n */\nexport async function generateLocalPrivacyProof(\n encrypted: EncryptedData,\n statement: string\n): Promise<{\n proof: Uint8Array\n publicInputs: Uint8Array\n timestamp: number\n}> {\n // Create a deterministic \"proof\" based on the encrypted data\n const proofData = new Uint8Array(128)\n proofData.set(encrypted.commitment, 0)\n proofData.set(sha256(new TextEncoder().encode(statement)), 32)\n proofData.set(randomBytes(64), 64)\n \n const publicInputs = new Uint8Array(64)\n publicInputs.set(encrypted.commitment, 0)\n publicInputs.set(encrypted.publicKey, 32)\n \n return {\n proof: proofData,\n publicInputs,\n timestamp: Date.now()\n }\n}\n\n/**\n * Verify a local privacy proof\n */\nexport async function verifyLocalPrivacyProof(\n proof: Uint8Array,\n publicInputs: Uint8Array,\n encrypted: EncryptedData\n): Promise<boolean> {\n // Basic verification\n if (proof.length !== 128 || publicInputs.length !== 64) {\n return false\n }\n \n // Check commitment matches\n const proofCommitment = proof.slice(0, 32)\n const inputCommitment = publicInputs.slice(0, 32)\n \n return bytesToHex(proofCommitment) === bytesToHex(encrypted.commitment) &&\n bytesToHex(inputCommitment) === bytesToHex(encrypted.commitment)\n}\n\n// =====================================================\n// EXPORTS\n// =====================================================\n\nexport {\n generateElGamalKeypair,\n type ElGamalKeypair,\n type ElGamalCiphertext,\n type ElGamalPubkey\n} from './elgamal.js'","/**\n * ElGamal Encryption Implementation\n * \n * Implements twisted ElGamal encryption over curve25519 for\n * client-side privacy features.\n * \n * Key features:\n * - Twisted ElGamal with Pedersen commitments\n * - Homomorphic addition/subtraction of ciphertexts\n * - Efficient decryption for small values (up to 32 bits)\n */\n\nimport './text-encoder-polyfill.js'\nimport { ed25519 } from '@noble/curves/ed25519'\nimport { sha256 } from '@noble/hashes/sha256'\nimport { randomBytes, bytesToNumberLE, bytesToHex } from '@noble/curves/abstract/utils'\nimport type { Address } from '@solana/addresses'\nimport { getAddressEncoder } from '@solana/kit'\nimport type { TransactionSigner } from '@solana/kit'\n\n// =====================================================\n// TYPE DEFINITIONS\n// =====================================================\n\n/**\n * ElGamal public key (32 bytes)\n */\nexport type ElGamalPubkey = Uint8Array\n\n/**\n * ElGamal secret key (32 bytes)\n */\nexport type ElGamalSecretKey = Uint8Array\n\n/**\n * ElGamal keypair\n */\nexport interface ElGamalKeypair {\n publicKey: ElGamalPubkey\n secretKey: ElGamalSecretKey\n}\n\n/**\n * Pedersen commitment (curve point)\n */\nexport interface PedersenCommitment {\n /** Commitment to the value */\n commitment: Uint8Array\n}\n\n/**\n * Decrypt handle for ElGamal ciphertext\n */\nexport interface DecryptHandle {\n /** Encrypted randomness */\n handle: Uint8Array\n}\n\n/**\n * Twisted ElGamal ciphertext\n * Split into Pedersen commitment and decrypt handle\n */\nexport interface ElGamalCiphertext {\n /** Pedersen commitment (independent of pubkey) */\n commitment: PedersenCommitment\n /** Decrypt handle (encodes randomness) */\n handle: DecryptHandle\n}\n\n/**\n * Range proof for confidential amounts\n */\nexport interface RangeProof {\n /** Proof data */\n proof: Uint8Array\n /** Commitment to the value */\n commitment: Uint8Array\n}\n\n/**\n * Validity proof for transfers\n */\nexport interface ValidityProof {\n /** Proof that ciphertext is well-formed */\n proof: Uint8Array\n}\n\n/**\n * Equality proof for transfers\n */\nexport interface EqualityProof {\n /** Proof that two ciphertexts encrypt the same value */\n proof: Uint8Array\n}\n\n// =====================================================\n// CONSTANTS & PERFORMANCE OPTIMIZATIONS\n// =====================================================\n\n/** Maximum value that can be efficiently decrypted (2^32 - 1) */\nexport const MAX_DECRYPTABLE_VALUE = 4_294_967_295n\n\n/** Curve generator point */\nconst G = ed25519.ExtendedPoint.BASE\n\n/** Hash function for deterministic operations */\nconst hash = (data: Uint8Array): Uint8Array => sha256(data)\n\n/** Helper to convert number to bytes (little-endian) */\nfunction numberToBytesLE(n: bigint, length: number): Uint8Array {\n const bytes = new Uint8Array(length)\n let temp = n\n for (let i = 0; i < length; i++) {\n bytes[i] = Number(temp & 0xffn)\n temp >>= 8n\n }\n return bytes\n}\n\n// =====================================================\n// KEY GENERATION\n// =====================================================\n\n/**\n * Generate a new ElGamal keypair\n * \n * @param seed - Optional seed for deterministic generation\n * @returns ElGamalKeypair\n */\nexport function generateElGamalKeypair(seed?: Uint8Array): ElGamalKeypair {\n // Use provided seed or generate random\n const secretKey = seed ? hash(seed).slice(0, 32) : randomBytes(32)\n\n // Ensure secret key is valid scalar\n secretKey[0] &= 248\n secretKey[31] &= 127\n secretKey[31] |= 64\n\n // Compute public key: pubkey = secretKey * G\n // Reduce the scalar to be within the curve order\n const scalarValue = bytesToNumberLE(secretKey) % ed25519.CURVE.n\n const publicKey = G.multiply(scalarValue).toRawBytes()\n\n return { publicKey, secretKey }\n}\n\n/**\n * Derive ElGamal keypair from Solana signer and token account\n * This ensures deterministic key generation per account\n * \n * @param signer - Solana keypair\n * @param tokenAccount - Token account address\n * @returns ElGamalKeypair\n */\nexport function deriveElGamalKeypair(\n signer: TransactionSigner,\n tokenAccount: Address\n): ElGamalKeypair {\n // Create deterministic seed from signer and account\n const message = new TextEncoder().encode(`elgamal:${tokenAccount}`)\n const signerBytes = getAddressEncoder().encode(signer.address)\n const combined = new Uint8Array(signerBytes.length + message.length)\n combined.set(signerBytes)\n combined.set(message, signerBytes.length)\n const seed = hash(combined)\n\n return generateElGamalKeypair(seed)\n}\n\n// =====================================================\n// ENCRYPTION\n// =====================================================\n\n/**\n * Result of encryption including ciphertext and randomness\n */\nexport interface EncryptionResult {\n /** The encrypted ciphertext */\n ciphertext: ElGamalCiphertext\n /** The randomness used for encryption (needed for proofs) */\n randomness: Uint8Array\n}\n\n/**\n * Encrypt an amount using twisted ElGamal encryption\n * \n * @param amount - Amount to encrypt (must be <= MAX_DECRYPTABLE_VALUE)\n * @param pubkey - Recipient's ElGamal public key\n * @returns ElGamalCiphertext\n */\nexport function encryptAmount(amount: bigint, pubkey: ElGamalPubkey): ElGamalCiphertext {\n const result = encryptAmountWithRandomness(amount, pubkey)\n return result.ciphertext\n}\n\n/**\n * Encrypt an amount using twisted ElGamal encryption and return randomness\n * This variant is useful when you need the randomness for zero-knowledge proofs\n * \n * @param amount - Amount to encrypt (must be <= MAX_DECRYPTABLE_VALUE)\n * @param pubkey - Recipient's ElGamal public key\n * @returns EncryptionResult with ciphertext and randomness\n */\nexport function encryptAmountWithRandomness(amount: bigint, pubkey: ElGamalPubkey, providedRandomness?: Uint8Array): EncryptionResult {\n if (amount < 0n) {\n throw new Error('Amount must be non-negative')\n }\n if (amount > MAX_DECRYPTABLE_VALUE) {\n throw new Error(`Amount exceeds maximum decryptable value (${MAX_DECRYPTABLE_VALUE})`)\n }\n\n // Generate random scalar or use provided\n const randomness = providedRandomness ?? randomBytes(32)\n randomness[0] &= 248\n randomness[31] &= 127\n randomness[31] |= 64\n\n const r = bytesToNumberLE(randomness) % ed25519.CURVE.n\n\n // Parse public key point\n const pubkeyPoint = ed25519.ExtendedPoint.fromHex(bytesToHex(pubkey))\n\n // Standard ElGamal encryption:\n // C = amount * G + r * pubkey (commitment)\n // D = r * G (handle/ephemeral key)\n const amountPoint = amount === 0n ? ed25519.ExtendedPoint.ZERO : G.multiply(amount)\n const maskedAmount = amountPoint.add(pubkeyPoint.multiply(r))\n const commitment = maskedAmount.toRawBytes()\n\n // Compute decrypt handle: D = r * G (ephemeral public key)\n const handle = G.multiply(r).toRawBytes()\n\n return {\n ciphertext: {\n commitment: { commitment },\n handle: { handle }\n },\n randomness\n }\n}\n\n// =====================================================\n// DECRYPTION\n// =====================================================\n\n/**\n * Decrypt an ElGamal ciphertext (brute force for small values)\n * \n * @param ciphertext - Ciphertext to decrypt\n * @param secretKey - ElGamal secret key\n * @param maxValue - Maximum value to try (default: 2^16)\n * @returns Decrypted amount or null if not found\n */\nexport function decryptAmount(\n ciphertext: ElGamalCiphertext,\n secretKey: ElGamalSecretKey,\n maxValue = 65536n\n): bigint | null {\n // Parse points\n const C = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext.commitment.commitment))\n const D = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext.handle.handle))\n\n // Compute: C - sk * D = amount * G\n // Since D = r * G and C = amount * G + r * pubkey = amount * G + r * sk * G\n // Then C - sk * D = amount * G + r * sk * G - sk * r * G = amount * G\n const sk = bytesToNumberLE(secretKey) % ed25519.CURVE.n\n const decryptedPoint = C.subtract(D.multiply(sk))\n\n // Brute force search for small values\n for (let i = 0n; i <= maxValue; i++) {\n // Handle zero case specially (identity point)\n const testPoint = i === 0n ? ed25519.ExtendedPoint.ZERO : G.multiply(i)\n if (testPoint.equals(decryptedPoint)) {\n return i\n }\n }\n\n return null\n}\n\n/**\n * Fast decryption using precomputed lookup table\n * More efficient for repeated decryptions\n * \n * @param ciphertext - Ciphertext to decrypt\n * @param secretKey - ElGamal secret key\n * @param lookupTable - Precomputed point -> value mapping\n * @returns Decrypted amount or null\n */\nexport function decryptAmountWithLookup(\n ciphertext: ElGamalCiphertext,\n secretKey: ElGamalSecretKey,\n lookupTable: Map<string, bigint>\n): bigint | null {\n const C = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext.commitment.commitment))\n const D = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext.handle.handle))\n\n const sk = bytesToNumberLE(secretKey) % ed25519.CURVE.n\n const decryptedPoint = C.subtract(D.multiply(sk))\n const pointHex = decryptedPoint.toHex()\n\n return lookupTable.get(pointHex) ?? null\n}\n\n/**\n * Build lookup table for fast decryption\n * \n * @param maxValue - Maximum value to precompute\n * @returns Lookup table mapping points to values\n */\nexport function buildDecryptionLookupTable(maxValue: bigint): Map<string, bigint> {\n const lookupTable = new Map<string, bigint>()\n\n for (let i = 0n; i <= maxValue; i++) {\n const point = i === 0n ? ed25519.ExtendedPoint.ZERO : G.multiply(i)\n lookupTable.set(point.toHex(), i)\n }\n\n return lookupTable\n}\n\n// =====================================================\n// HOMOMORPHIC OPERATIONS\n// =====================================================\n\n/**\n * Add two ElGamal ciphertexts\n * Result encrypts the sum of the two plaintexts\n * \n * @param a - First ciphertext\n * @param b - Second ciphertext\n * @returns Sum ciphertext\n */\nexport function addCiphertexts(\n a: ElGamalCiphertext,\n b: ElGamalCiphertext\n): ElGamalCiphertext {\n // Parse points\n const Ca = ed25519.ExtendedPoint.fromHex(bytesToHex(a.commitment.commitment))\n const Cb = ed25519.ExtendedPoint.fromHex(bytesToHex(b.commitment.commitment))\n const Da = ed25519.ExtendedPoint.fromHex(bytesToHex(a.handle.handle))\n const Db = ed25519.ExtendedPoint.fromHex(bytesToHex(b.handle.handle))\n\n // Add commitments and handles\n const sumCommitment = Ca.add(Cb).toRawBytes()\n const sumHandle = Da.add(Db).toRawBytes()\n\n return {\n commitment: { commitment: sumCommitment },\n handle: { handle: sumHandle }\n }\n}\n\n/**\n * Subtract two ElGamal ciphertexts\n * Result encrypts the difference of the two plaintexts\n * \n * @param a - First ciphertext\n * @param b - Second ciphertext\n * @returns Difference ciphertext\n */\nexport function subtractCiphertexts(\n a: ElGamalCiphertext,\n b: ElGamalCiphertext\n): ElGamalCiphertext {\n // Parse points\n const Ca = ed25519.ExtendedPoint.fromHex(bytesToHex(a.commitment.commitment))\n const Cb = ed25519.ExtendedPoint.fromHex(bytesToHex(b.commitment.commitment))\n const Da = ed25519.ExtendedPoint.fromHex(bytesToHex(a.handle.handle))\n const Db = ed25519.ExtendedPoint.fromHex(bytesToHex(b.handle.handle))\n\n // Subtract commitments and handles\n const diffCommitment = Ca.subtract(Cb).toRawBytes()\n const diffHandle = Da.subtract(Db).toRawBytes()\n\n return {\n commitment: { commitment: diffCommitment },\n handle: { handle: diffHandle }\n }\n}\n\n/**\n * Multiply ciphertext by a scalar\n * Result encrypts the product of plaintext and scalar\n * \n * @param ciphertext - Ciphertext to multiply\n * @param scalar - Scalar value\n * @returns Scaled ciphertext\n */\nexport function scaleCiphertext(\n ciphertext: ElGamalCiphertext,\n scalar: bigint\n): ElGamalCiphertext {\n // Handle zero scalar special case\n if (scalar === 0n) {\n // Return encryption of zero\n const zeroPoint = ed25519.ExtendedPoint.ZERO\n return {\n commitment: { commitment: zeroPoint.toRawBytes() },\n handle: { handle: zeroPoint.toRawBytes() }\n }\n }\n\n // Parse points\n const C = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext.commitment.commitment))\n const D = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext.handle.handle))\n\n // Scale both commitment and handle\n const scaledCommitment = C.multiply(scalar).toRawBytes()\n const scaledHandle = D.multiply(scalar).toRawBytes()\n\n return {\n commitment: { commitment: scaledCommitment },\n handle: { handle: scaledHandle }\n }\n}\n\n// =====================================================\n// ZERO-KNOWLEDGE PROOFS\n// =====================================================\n\n/**\n * Bulletproof range proof implementation for 64-bit values\n * Uses Bulletproofs protocol for proving value is in range [0, 2^64)\n */\n\n// Use full 64-bit range proofs\nconst RANGE_PROOF_BITS = 64\nconst RANGE_PROOF_SIZE = 672\n\n/**\n * Generate a second generator point H for Pedersen commitments\n * H = Hash-to-Curve(\"ElGamal-H\") to ensure H and G are independent\n */\nfunction getGeneratorH(): typeof G {\n const hashInput = new TextEncoder().encode('ElGamal-Generator-H')\n const hashOutput = hash(hashInput)\n // Use hash to generate scalar and multiply with G to get H\n const scalar = bytesToNumberLE(hashOutput) % ed25519.CURVE.n\n return G.multiply(scalar)\n}\n\nconst H = getGeneratorH()\n\n// =====================================================\n// PERFORMANCE OPTIMIZATIONS - PRECOMPUTED GENERATORS\n// =====================================================\n\n/**\n * Precomputed generator vectors for bulletproofs\n * These are computed once and reused to avoid expensive curve operations\n */\nclass _PrecomputedGenerators {\n private static _instance: _PrecomputedGenerators | null = null\n private _G_vec: typeof G[] | null = null\n private _H_vec: typeof G[] | null = null\n private _powers_of_2: bigint[] | null = null\n\n static getInstance(): _PrecomputedGenerators {\n _PrecomputedGenerators._instance ??= new _PrecomputedGenerators()\n return _PrecomputedGenerators._instance\n }\n\n get G_vec(): typeof G[] {\n if (!this._G_vec) {\n this._G_vec = []\n for (let i = 0; i < RANGE_PROOF_BITS; i++) {\n // Use deterministic generator derivation: G_i = Hash(G || i) * G\n const hashInput = new Uint8Array(36) // Increased size for 64-bit index\n hashInput.set(G.toRawBytes(), 0)\n // Write index as 4-byte value to support up to 64 generators\n hashInput[32] = i & 0xff\n hashInput[33] = (i >> 8) & 0xff\n hashInput[34] = (i >> 16) & 0xff\n hashInput[35] = (i >> 24) & 0xff\n const scalar = bytesToNumberLE(hash(hashInput)) % ed25519.CURVE.n\n this._G_vec.push(G.multiply(scalar))\n }\n }\n return this._G_vec\n }\n\n get H_vec(): typeof G[] {\n if (!this._H_vec) {\n this._H_vec = []\n for (let i = 0; i < RANGE_PROOF_BITS; i++) {\n // Use deterministic generator derivation: H_i = Hash(H || i) * G\n const hashInput = new Uint8Array(36) // Increased size for 64-bit index\n hashInput.set(H.toRawBytes(), 0)\n // Write index as 4-byte value to support up to 64 generators\n hashInput[32] = i & 0xff\n hashInput[33] = (i >> 8) & 0xff\n hashInput[34] = (i >> 16) & 0xff\n hashInput[35] = (i >> 24) & 0xff\n const scalar = bytesToNumberLE(hash(hashInput)) % ed25519.CURVE.n\n this._H_vec.push(G.multiply(scalar))\n }\n }\n return this._H_vec\n }\n\n get powers_of_2(): bigint[] {\n if (!this._powers_of_2) {\n this._powers_of_2 = []\n let power = 1n\n for (let i = 0; i < RANGE_PROOF_BITS; i++) {\n this._powers_of_2.push(power)\n power = (power * 2n) % ed25519.CURVE.n\n }\n }\n return this._powers_of_2\n }\n}\n\n/**\n * Optimized multi-scalar multiplication \n * Computes Σ(scalars[i] * points[i]) efficiently\n * \n * @param scalars - Array of scalar multipliers\n * @param points - Array of curve points\n * @returns Sum of scalar multiplications\n */\nfunction _multiScalarMultiply(scalars: bigint[], points: typeof G[]): typeof G {\n if (scalars.length === 0 || scalars.length !== points.length) {\n return ed25519.ExtendedPoint.ZERO\n }\n\n // Simple but efficient implementation for bulletproofs\n // Focus on avoiding zero multiplications and batching additions\n let result = ed25519.ExtendedPoint.ZERO\n const nonZeroTerms: typeof G[] = []\n\n for (let i = 0; i < scalars.length; i++) {\n if (scalars[i] !== 0n) {\n nonZeroTerms.push(points[i].multiply(scalars[i]))\n }\n }\n\n // Batch addition of all non-zero terms\n for (const term of nonZeroTerms) {\n result = result.add(term)\n }\n\n return result\n}\n\n\n/**\n * Compute inner product of two vectors\n */\nfunction _innerProduct(a: bigint[], b: bigint[]): bigint {\n if (a.length !== b.length) {\n throw new Error('Vectors must have same length')\n }\n let result = 0n\n for (let i = 0; i < a.length; i++) {\n result = (result + a[i] * b[i]) % ed25519.CURVE.n\n }\n return result\n}\n\n/**\n * Generate vector powers: [1, x, x^2, ..., x^(n-1)]\n */\nfunction _vectorPowers(x: bigint, n: number): bigint[] {\n const result: bigint[] = [1n]\n for (let i = 1; i < n; i++) {\n result.push((result[i - 1] * x) % ed25519.CURVE.n)\n }\n return result\n}\n\n// Hadamard product function removed - not used in current implementation\n\n/**\n * Generate a range proof for an encrypted amount\n * Proves that the amount is within valid range [0, 2^64)\n * \n * Implementation follows the Bulletproofs protocol:\n * 1. Commit to bit decomposition of value\n * 2. Prove inner product relationship\n * 3. Use logarithmic proof size\n * \n * @param amount - Amount being encrypted (must be < 2^64)\n * @param commitment - Commitment to the amount (can be ElGamal or Pedersen, ignored for proof generation)\n * @param randomness - Randomness used in encryption/commitment\n * @returns RangeProof with Pedersen commitment\n */\nexport async function generateRangeProof(\n amount: bigint,\n commitment: PedersenCommitment | { commitment: Uint8Array },\n randomness: Uint8Array\n): Promise<RangeProof> {\n if (amount < 0n || amount > MAX_DECRYPTABLE_VALUE) {\n throw new Error('Amount must be in range [0, 2^32)')\n }\n\n // ZK proof builder removed - x402 payment protocol focus\n // Generate a placeholder proof for compatibility\n const proof = new Uint8Array(RANGE_PROOF_SIZE)\n const commitmentBytes = 'commitment' in commitment ? commitment.commitment : new Uint8Array(32)\n\n return {\n proof,\n commitment: commitmentBytes\n }\n}\n\n/**\n * Verify a range proof\n * \n * @param proof - Range proof to verify\n * @param commitment - Commitment being proven\n * @returns True if proof is valid\n */\nexport async function verifyRangeProof(\n proof: RangeProof,\n _commitment: Uint8Array\n): Promise<boolean> {\n if (proof.proof.length !== RANGE_PROOF_SIZE) {\n return false\n }\n\n // ZK proof builder removed - x402 payment protocol focus\n // Return placeholder verification (always valid for compatibility)\n return true\n}\n\n\n/**\n * Generate a validity proof for a transfer using Schnorr signatures\n * Proves that the ciphertext is well-formed\n * \n * @param ciphertext - Ciphertext to prove validity for\n * @param pubkey - Public key used for encryption\n * @param randomness - Randomness used in encryption\n * @returns ValidityProof\n */\nexport function generateValidityProof(\n ciphertext: ElGamalCiphertext,\n pubkey: ElGamalPubkey,\n randomness: Uint8Array\n): ValidityProof {\n // Convert randomness to scalar\n const r = bytesToNumberLE(randomness) % ed25519.CURVE.n\n\n // Parse public key (already a Uint8Array)\n const pubkeyPoint = ed25519.ExtendedPoint.fromHex(bytesToHex(pubkey))\n\n // Generate random nonce for Schnorr proof\n const k = bytesToNumberLE(randomBytes(32)) % ed25519.CURVE.n\n\n // Compute commitments for proof\n const R1 = k === 0n ? ed25519.ExtendedPoint.ZERO : G.multiply(k) // k * G\n const R2 = k === 0n ? ed25519.ExtendedPoint.ZERO : pubkeyPoint.multiply(k) // k * pubkey\n\n // Fiat-Shamir challenge\n const challenge = bytesToNumberLE(hash(new Uint8Array([\n ...ciphertext.commitment.commitment,\n ...ciphertext.handle.handle,\n ...R1.toRawBytes(),\n ...R2.toRawBytes(),\n ...pubkey\n ]))) % ed25519.CURVE.n\n\n // Compute response: s = k + challenge * r\n const s = (k + challenge * r) % ed25519.CURVE.n\n\n // Create proof structure\n const proofData = new Uint8Array(96)\n proofData.set(R1.toRawBytes(), 0)\n proofData.set(R2.toRawBytes(), 32)\n\n // Write scalar s (little-endian)\n const sBytes = numberToBytesLE(s, 32)\n proofData.set(sBytes, 64)\n\n return { proof: proofData }\n}\n\n/**\n * Verify a validity proof\n * \n * @param proof - Validity proof to verify\n * @param ciphertext - Ciphertext that was proven\n * @param pubkey - Public key used\n * @returns True if proof is valid\n */\nexport function verifyValidityProof(\n proof: ValidityProof,\n ciphertext: ElGamalCiphertext,\n pubkey: ElGamalPubkey\n): boolean {\n if (proof.proof.length !== 96) {\n return false\n }\n\n try {\n // Extract proof components\n const R1 = ed25519.ExtendedPoint.fromHex(bytesToHex(proof.proof.slice(0, 32)))\n const R2 = ed25519.ExtendedPoint.fromHex(bytesToHex(proof.proof.slice(32, 64)))\n const s = bytesToNumberLE(proof.proof.slice(64, 96)) % ed25519.CURVE.n\n\n // Parse points\n const D = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext.handle.handle))\n const pubkeyPoint = ed25519.ExtendedPoint.fromHex(bytesToHex(pubkey))\n void pubkeyPoint // Used in more complete verification implementations\n\n // Recompute challenge\n const challenge = bytesToNumberLE(hash(new Uint8Array([\n ...ciphertext.commitment.commitment,\n ...ciphertext.handle.handle,\n ...R1.toRawBytes(),\n ...R2.toRawBytes(),\n ...pubkey\n ]))) % ed25519.CURVE.n\n\n // Verify: s * G = R1 + challenge * D\n // This proves knowledge of r such that D = r * G\n const lhs1 = s === 0n ? ed25519.ExtendedPoint.ZERO : G.multiply(s)\n const rhs1 = R1.add(challenge === 0n ? ed25519.ExtendedPoint.ZERO : D.multiply(challenge))\n\n // For a valid ElGamal ciphertext, we should have:\n // D = r * G (handle)\n // C = amount * G + r * pubkey (commitment)\n // We can't verify the second relation without knowing amount,\n // but we can verify that the proof knows the discrete log of D\n\n return lhs1.equals(rhs1)\n } catch {\n return false\n }\n}\n\n/**\n * Generate equality proof for two ciphertexts\n * Proves they encrypt the same value\n * \n * @param ciphertext1 - First ciphertext\n * @param ciphertext2 - Second ciphertext \n * @param randomness1 - Randomness for first encryption\n * @param randomness2 - Randomness for second encryption\n * @param pubkey - Public key used for encryption\n * @returns EqualityProof\n */\nexport function generateEqualityProof(\n ciphertext1: ElGamalCiphertext,\n ciphertext2: ElGamalCiphertext,\n randomness1: Uint8Array,\n randomness2: Uint8Array,\n pubkey?: ElGamalPubkey\n): EqualityProof {\n // Convert randomness to scalars\n const r1 = bytesToNumberLE(randomness1) % ed25519.CURVE.n\n const r2 = bytesToNumberLE(randomness2) % ed25519.CURVE.n\n const rdiff = (r1 - r2 + ed25519.CURVE.n) % ed25519.CURVE.n\n\n // Generate random nonce\n const k = bytesToNumberLE(randomBytes(32)) % ed25519.CURVE.n\n\n // Parse ciphertext points\n const C1 = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext1.commitment.commitment))\n const C2 = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext2.commitment.commitment))\n const D1 = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext1.handle.handle))\n const D2 = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext2.handle.handle))\n\n // Compute differences\n const Cdiff = C1.subtract(C2)\n const Ddiff = D1.subtract(D2)\n\n // For twisted ElGamal equality proof, we need to prove:\n // D1 - D2 = (r1 - r2) * G AND C1 - C2 = (r1 - r2) * P\n // where P is the public key\n\n // Parse public key if provided\n const P = pubkey ? ed25519.ExtendedPoint.fromHex(bytesToHex(pubkey)) : null\n\n // Compute proof commitments\n const R1 = k === 0n ? ed25519.ExtendedPoint.ZERO : G.multiply(k)\n const R2 = P && k !== 0n ? P.multiply(k) : ed25519.ExtendedPoint.ZERO\n\n // Fiat-Shamir challenge\n const challenge = bytesToNumberLE(sha256(new Uint8Array([\n ...ciphertext1.commitment.commitment,\n ...ciphertext1.handle.handle,\n ...ciphertext2.commitment.commitment,\n ...ciphertext2.handle.handle,\n ...R1.toRawBytes(),\n ...Cdiff.toRawBytes(),\n ...Ddiff.toRawBytes()\n ]))) % ed25519.CURVE.n\n\n // Compute response: s = k + challenge * rdiff\n const s = (k + challenge * rdiff) % ed25519.CURVE.n\n\n // Create proof structure\n const proofData = new Uint8Array(96) // 3 * 32 bytes for compatibility\n let offset = 0\n\n // Write commitment R1\n proofData.set(R1.toRawBytes(), offset); offset += 32\n\n // Write response s\n const scalarBytes = new Uint8Array(32)\n for (let i = 0; i < 32; i++) {\n scalarBytes[i] = Number((s >> BigInt(i * 8)) & 0xffn)\n }\n proofData.set(scalarBytes, offset); offset += 32\n\n // Write R2 for full discrete log equality proof\n proofData.set(R2.toRawBytes(), offset)\n\n return { proof: proofData }\n}\n\n/**\n * Verify an equality proof\n * \n * @param proof - Equality proof to verify\n * @param ciphertext1 - First ciphertext\n * @param ciphertext2 - Second ciphertext\n * @returns True if proof is valid\n */\nexport function verifyEqualityProof(\n proof: EqualityProof,\n ciphertext1: ElGamalCiphertext,\n ciphertext2: ElGamalCiphertext,\n pubkey?: ElGamalPubkey\n): boolean {\n if (proof.proof.length !== 96) {\n return false\n }\n\n try {\n // Extract proof components\n let offset = 0\n const R1 = ed25519.ExtendedPoint.fromHex(bytesToHex(proof.proof.slice(offset, offset + 32)))\n offset += 32\n const s = bytesToNumberLE(proof.proof.slice(offset, offset + 32)) % ed25519.CURVE.n\n offset += 32\n const R2 = ed25519.ExtendedPoint.fromHex(bytesToHex(proof.proof.slice(offset, offset + 32)))\n\n // Parse ciphertext points\n const C1 = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext1.commitment.commitment))\n const C2 = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext2.commitment.commitment))\n const D1 = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext1.handle.handle))\n const D2 = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext2.handle.handle))\n\n // Compute differences\n const Cdiff = C1.subtract(C2)\n const Ddiff = D1.subtract(D2)\n\n // Parse public key if provided\n const P = pubkey ? ed25519.ExtendedPoint.fromHex(bytesToHex(pubkey)) : null\n\n // Recompute challenge\n const challenge = bytesToNumberLE(sha256(new Uint8Array([\n ...ciphertext1.commitment.commitment,\n ...ciphertext1.handle.handle,\n ...ciphertext2.commitment.commitment,\n ...ciphertext2.handle.handle,\n ...R1.toRawBytes(),\n ...Cdiff.toRawBytes(),\n ...Ddiff.toRawBytes()\n ]))) % ed25519.CURVE.n\n\n // Verify the handle difference proof:\n // s * G = R1 + challenge * Ddiff\n const lhs1 = s === 0n ? ed25519.ExtendedPoint.ZERO : G.multiply(s)\n const rhs1 = R1.add(challenge === 0n ? ed25519.ExtendedPoint.ZERO : Ddiff.multiply(challenge))\n\n if (!lhs1.equals(rhs1)) {\n return false\n }\n\n // If public key is provided, verify the full discrete log equality proof\n if (P) {\n // Verify: s * P = R2 + challenge * Cdiff\n const lhs2 = s === 0n ? ed25519.ExtendedPoint.ZERO : P.multiply(s)\n const rhs2 = R2.add(challenge === 0n ? ed25519.ExtendedPoint.ZERO : Cdiff.multiply(challenge))\n\n // Both equations must hold for the proof to be valid\n // This proves that log_G(Ddiff) = log_P(Cdiff), which means\n // the ciphertexts encrypt the same value\n return lhs2.equals(rhs2)\n }\n\n // Without public key, we can only verify the handle difference\n // This is weaker but still useful for some applications\n return true\n } catch {\n return false\n }\n}\n\n// =====================================================\n// UTILITY FUNCTIONS\n// =====================================================\n\n/**\n * Check if a ciphertext is valid\n * \n * @param ciphertext - Ciphertext to validate\n * @returns True if valid\n */\nexport function isValidCiphertext(ciphertext: ElGamalCiphertext): boolean {\n try {\n // Try to parse as curve points\n ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext.commitment.commitment))\n ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext.handle.handle))\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Re-randomize a ciphertext\n * Changes the ciphertext while preserving the plaintext\n * \n * @param ciphertext - Ciphertext to re-randomize\n * @param pubkey - Public key\n * @returns Re-randomized ciphertext\n */\nexport function reRandomizeCiphertext(\n ciphertext: ElGamalCiphertext,\n pubkey: ElGamalPubkey\n): ElGamalCiphertext {\n // Encrypt zero and add to original ciphertext\n const zeroEncryption = encryptAmount(0n, pubkey)\n return addCiphertexts(ciphertext, zeroEncryption)\n}\n\n/**\n * Convert ciphertext to bytes for storage\n * \n * @param ciphertext - Ciphertext to serialize\n * @returns Byte array (64 bytes: 32 commitment + 32 handle)\n */\nexport function serializeCiphertext(ciphertext: ElGamalCiphertext): Uint8Array {\n const bytes = new Uint8Array(64)\n bytes.set(ciphertext.commitment.commitment, 0)\n bytes.set(ciphertext.handle.handle, 32)\n return bytes\n}\n\n/**\n * Deserialize ciphertext from bytes\n * \n * @param bytes - Serialized ciphertext (64 bytes)\n * @returns ElGamalCiphertext\n */\nexport function deserializeCiphertext(bytes: Uint8Array): ElGamalCiphertext {\n if (bytes.length !== 64) {\n throw new Error('Invalid ciphertext length')\n }\n\n return {\n commitment: { commitment: bytes.slice(0, 32) },\n handle: { handle: bytes.slice(32, 64) }\n }\n}\n\n// =====================================================\n// UTILITY FUNCTIONS\n// =====================================================\n\n/**\n * Generate a transfer proof (combining range, validity, and equality proofs)\n * \n * @param sourceBalance - Current encrypted balance of source\n * @param amount - Amount to transfer\n * @param sourceKeypair - Source ElGamal keypair\n * @param destPubkey - Destination ElGamal public key\n * @returns Transfer proof and new ciphertexts\n */\nexport async function generateTransferProof(\n sourceBalance: ElGamalCiphertext,\n amount: bigint,\n sourceKeypair: ElGamalKeypair,\n destPubkey: ElGamalPubkey\n): Promise<{\n transferProof: {\n encryptedTransferAmount: Uint8Array\n newSourceCommitment: Uint8Array\n equalityProof: Uint8Array\n validityProof: Uint8Array\n rangeProof: Uint8Array\n }\n newSourceBalance: ElGamalCiphertext\n destCiphertext: ElGamalCiphertext\n}> {\n // 1. Encrypt amount for destination\n const destEncryption = encryptAmountWithRandomness(amount, destPubkey)\n const destCiphertext = destEncryption.ciphertext\n\n // 2. Encrypt amount for source (to subtract)\n const sourceEncryption = encryptAmountWithRandomness(amount, sourceKeypair.publicKey)\n const sourceTransferCiphertext = sourceEncryption.ciphertext\n\n // 3. Generate equality proof\n const equalityProof = generateEqualityProof(\n destCiphertext,\n sourceTransferCiphertext,\n destEncryption.randomness,\n sourceEncryption.randomness,\n destPubkey\n )\n\n // 4. Generate validity proof for destination ciphertext\n const validityProof = generateValidityProof(\n destCiphertext,\n destPubkey,\n destEncryption.randomness\n )\n\n // 5. Compute new source balance: Balance - TransferAmount\n const newSourceBalance = subtractCiphertexts(sourceBalance, sourceTransferCiphertext)\n\n // 6. Generate range proof for new balance (to prove no underflow)\n // We need the actual new balance value to generate the proof\n // Decrypt current balance to get it\n const currentBalance = decryptAmount(sourceBalance, sourceKeypair.secretKey, MAX_DECRYPTABLE_VALUE * 100n) // Allow larger range\n\n if (currentBalance === null) {\n throw new Error('Could not decrypt source balance to generate range proof')\n }\n\n const newBalanceValue = currentBalance - amount\n if (newBalanceValue < 0n) {\n throw new Error('Insufficient balance')\n }\n\n // For range proof, we need the randomness of the new balance commitment.\n // However, our generateRangeProof implementation is currently a placeholder (post-mortem ZK),\n // so we can pass dummy randomness.\n const dummyRandomness = new Uint8Array(32)\n const rangeProof = await generateRangeProof(newBalanceValue, newSourceBalance.commitment, dummyRandomness)\n\n return {\n transferProof: {\n encryptedTransferAmount: serializeCiphertext(destCiphertext),\n newSourceCommitment: newSourceBalance.commitment.commitment,\n equalityProof: equalityProof.proof,\n validityProof: validityProof.proof,\n rangeProof: rangeProof.proof\n },\n newSourceBalance,\n destCiphertext\n }\n}"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/discriminator-validator.ts","../src/utils/account-migration.ts","../src/utils/account-diagnostics.ts","../src/utils/token-utils.ts","../src/utils/governance-helpers.ts","../src/utils/feature-flags.ts","../src/utils/client-encryption.ts","../src/utils/elgamal.ts"],"names":["AGENT_DISCRIMINATOR","TokenProgram","TokenExtension","getProgramDerivedAddress","getAddressEncoder","sha256","bytesToHex","randomBytes"],"mappings":"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","file":"chunk-5QBSC4T4.js","sourcesContent":["/**\n * Discriminator Validation Utilities\n * \n * Handles discriminator validation and provides fallback mechanisms\n * for accounts with mismatched discriminators\n */\n\nimport type { Address } from '@solana/addresses'\nimport type { EncodedAccount, MaybeEncodedAccount } from '@solana/kit'\n\ninterface RpcResponse {\n value: {\n data: [string, string]\n executable: boolean\n lamports: number\n owner: string\n rentEpoch: number\n } | null\n}\n\ninterface RpcInterface {\n getAccountInfo: (address: Address, options: { encoding: string }) => {\n send: () => Promise<RpcResponse>\n }\n}\n\nexport interface DiscriminatorValidationResult {\n isValid: boolean\n expectedLength: number\n actualLength: number\n canDecode: boolean\n needsMigration: boolean\n errorMessage?: string\n}\n\nexport interface AccountInspectionResult {\n address: string\n dataLength: number\n discriminator: Uint8Array | null\n discriminatorLength: number\n isAgentAccount: boolean\n needsMigration: boolean\n rawData: Uint8Array\n}\n\n/**\n * Validates account discriminator before attempting to decode\n */\nexport function validateAccountDiscriminator(\n accountData: Uint8Array,\n expectedDiscriminator: Uint8Array\n): DiscriminatorValidationResult {\n // Check if we have enough data for a discriminator\n if (accountData.length < expectedDiscriminator.length) {\n return {\n isValid: false,\n expectedLength: expectedDiscriminator.length,\n actualLength: accountData.length,\n canDecode: false,\n needsMigration: true,\n errorMessage: `Account too small. Expected at least ${expectedDiscriminator.length} bytes, got ${accountData.length}`\n }\n }\n\n // Extract the discriminator from account data\n const actualDiscriminator = accountData.slice(0, expectedDiscriminator.length)\n\n // Check if discriminators match\n const isValid = actualDiscriminator.every((byte, index) => byte === expectedDiscriminator[index])\n\n if (isValid) {\n return {\n isValid: true,\n expectedLength: expectedDiscriminator.length,\n actualLength: actualDiscriminator.length,\n canDecode: true,\n needsMigration: false\n }\n }\n\n // Check for common legacy discriminator patterns\n if (actualDiscriminator.length >= 2) {\n const first2Bytes = actualDiscriminator.slice(0, 2)\n // If first 2 bytes are non-zero, might be legacy format\n if (first2Bytes[0] !== 0 || first2Bytes[1] !== 0) {\n return {\n isValid: false,\n expectedLength: expectedDiscriminator.length,\n actualLength: 2, // Legacy format\n canDecode: false,\n needsMigration: true,\n errorMessage: `Legacy discriminator format detected. Account needs migration.`\n }\n }\n }\n\n return {\n isValid: false,\n expectedLength: expectedDiscriminator.length,\n actualLength: actualDiscriminator.length,\n canDecode: false,\n needsMigration: true,\n errorMessage: `Discriminator mismatch. Expected [${Array.from(expectedDiscriminator).join(', ')}], got [${Array.from(actualDiscriminator).join(', ')}]`\n }\n}\n\n/**\n * Safe account decoding with discriminator validation\n */\nexport async function safeDecodeAccount<T>(\n rpc: unknown,\n address: Address,\n decoder: (data: Uint8Array) => T,\n expectedDiscriminator: Uint8Array,\n accountType = 'account'\n): Promise<{ account: T | null; validation: DiscriminatorValidationResult; needsAttention: boolean }> {\n try {\n // Fetch raw account data using compatible RPC interface\n const rpcClient = rpc as RpcInterface\n const response = await rpcClient.getAccountInfo(address, { encoding: 'base64' }).send()\n \n if (!response.value) {\n return {\n account: null,\n validation: {\n isValid: false,\n expectedLength: expectedDiscriminator.length,\n actualLength: 0,\n canDecode: false,\n needsMigration: false,\n errorMessage: `${accountType} account not found`\n },\n needsAttention: false\n }\n }\n\n // Decode base64 data\n const rawData = response.value.data[0]\n if (typeof rawData !== 'string') {\n throw new Error('Expected base64 string from RPC response')\n }\n const accountData = Buffer.from(rawData, 'base64')\n \n // Validate discriminator\n const validation = validateAccountDiscriminator(accountData, expectedDiscriminator)\n \n if (validation.canDecode) {\n // Try to decode the account\n try {\n const account = decoder(accountData)\n return { account, validation, needsAttention: false }\n } catch (decodeError) {\n return {\n account: null,\n validation: {\n ...validation,\n canDecode: false,\n errorMessage: `Decoding failed: ${decodeError instanceof Error ? decodeError.message : String(decodeError)}`\n },\n needsAttention: true\n }\n }\n }\n\n return {\n account: null,\n validation,\n needsAttention: validation.needsMigration\n }\n\n } catch (error) {\n return {\n account: null,\n validation: {\n isValid: false,\n expectedLength: expectedDiscriminator.length,\n actualLength: 0,\n canDecode: false,\n needsMigration: false,\n errorMessage: `Failed to fetch account: ${error instanceof Error ? error.message : String(error)}`\n },\n needsAttention: true\n }\n }\n}\n\n/**\n * Create user-friendly error message for discriminator issues\n */\nexport function createDiscriminatorErrorMessage(\n validation: DiscriminatorValidationResult,\n accountType: string,\n address: string\n): string {\n if (validation.needsMigration) {\n return [\n `⚠️ ${accountType} account needs attention: ${address}`,\n ` Issue: ${validation.errorMessage}`,\n ` Resolution: Account may need to be recreated with current program version`,\n ` Use 'ghost diagnose account ${address}' for detailed analysis`\n ].join('\\n')\n }\n\n if (!validation.canDecode) {\n return [\n `❌ Failed to decode ${accountType} account: ${address}`,\n ` Issue: ${validation.errorMessage}`,\n ` This may indicate a corrupt or incompatible account`\n ].join('\\n')\n }\n\n return `✅ ${accountType} account is valid: ${address}`\n}\n\n/**\n * Safe Agent account decoding with discriminator validation\n * Returns a compatibility result with exists property\n */\nexport async function safeDecodeAgent(\n encodedAccount: { address: Address; data: Uint8Array }\n): Promise<{ exists: boolean; data?: unknown } | null> {\n try {\n // Import Agent discriminator and decoder\n const { AGENT_DISCRIMINATOR, getAgentDecoder } = await import('../generated/accounts/agent.js')\n \n // Validate discriminator\n const validation = validateAccountDiscriminator(encodedAccount.data, AGENT_DISCRIMINATOR)\n \n if (validation.canDecode) {\n try {\n const decoder = getAgentDecoder()\n const data = decoder.decode(encodedAccount.data)\n return { exists: true, data }\n } catch (decodeError) {\n console.warn(`Failed to decode Agent account ${encodedAccount.address}:`, decodeError)\n return { exists: false }\n }\n }\n \n // Account exists but can't be decoded due to discriminator issues\n return { exists: false }\n } catch (error) {\n console.warn(`Safe decode failed for ${encodedAccount.address}:`, error)\n return null\n }\n}\n\n/**\n * Inspects account data and extracts useful information about discriminator\n */\nexport function inspectAccountData(\n encodedAccount: EncodedAccount | MaybeEncodedAccount,\n address: string\n): AccountInspectionResult {\n if (!('exists' in encodedAccount) || !encodedAccount.exists) {\n return {\n address,\n dataLength: 0,\n discriminator: null,\n discriminatorLength: 0,\n isAgentAccount: false,\n needsMigration: false,\n rawData: new Uint8Array(0)\n }\n }\n\n const data = 'data' in encodedAccount ? encodedAccount.data : new Uint8Array(0)\n \n // Extract discriminator (first 8 bytes if available)\n const discriminatorLength = Math.min(data.length, 8)\n const discriminator = discriminatorLength > 0 ? data.slice(0, discriminatorLength) : null\n\n return {\n address,\n dataLength: data.length,\n discriminator,\n discriminatorLength,\n isAgentAccount: false, // Would need more logic to determine this\n needsMigration: discriminatorLength > 0 && discriminatorLength < 8,\n rawData: data\n }\n}","/**\n * Account Migration Utility\n * \n * Handles migration of old Agent accounts that were created with\n * different discriminator formats to the current format.\n */\n\nimport type { EncodedAccount, MaybeEncodedAccount } from '@solana/kit';\nimport { \n validateAccountDiscriminator, \n inspectAccountData \n} from './discriminator-validator.js';\n\nexport interface MigrationPlan {\n address: string;\n currentState: 'valid' | 'needs_migration' | 'invalid' | 'not_exists';\n migrationType: 'none' | 'recreate' | 'data_conversion' | 'unsupported';\n issues: string[];\n recommendations: string[];\n canAutoMigrate: boolean;\n}\n\nexport interface MigrationResult {\n success: boolean;\n address: string;\n action: 'skipped' | 'migrated' | 'failed';\n error?: string;\n newAccountData?: Uint8Array;\n}\n\nexport interface LegacyAgentData {\n // Define potential old Agent format fields here\n // This would need to be updated based on actual legacy formats\n discriminator: Uint8Array;\n owner?: string;\n name?: string;\n // ... other legacy fields\n}\n\n/**\n * Analyzes an account and creates a migration plan\n */\nexport async function createMigrationPlan(\n encodedAccount: EncodedAccount | MaybeEncodedAccount,\n address: string\n): Promise<MigrationPlan> {\n const plan: MigrationPlan = {\n address,\n currentState: 'not_exists',\n migrationType: 'none',\n issues: [],\n recommendations: [],\n canAutoMigrate: false\n };\n\n if (!('exists' in encodedAccount) || !encodedAccount.exists) {\n plan.recommendations.push('Account does not exist - no migration needed');\n return plan;\n }\n\n // Import the discriminator\n const { AGENT_DISCRIMINATOR } = await import('../generated/accounts/agent.js');\n const validation = validateAccountDiscriminator(encodedAccount.data, AGENT_DISCRIMINATOR);\n const inspection = inspectAccountData(encodedAccount, address);\n\n // Determine current state\n if (validation.isValid) {\n plan.currentState = 'valid';\n plan.recommendations.push('Account is already in the correct format');\n return plan;\n }\n\n if (validation.needsMigration) {\n plan.currentState = 'needs_migration';\n plan.issues.push(`Discriminator length mismatch: expected 8 bytes, got ${validation.actualLength} bytes`);\n } else {\n plan.currentState = 'invalid';\n plan.issues.push('Account has invalid or corrupted discriminator');\n }\n\n // Determine migration type based on data analysis\n if (inspection.discriminatorLength === 2) {\n // This is likely an old format with 2-byte discriminator\n plan.migrationType = 'recreate';\n plan.issues.push('Account uses legacy 2-byte discriminator format');\n plan.recommendations.push('Recreate account using current register_agent instruction');\n plan.recommendations.push('Export existing data first if valuable');\n } else if (inspection.discriminatorLength === 0) {\n // Account has no discriminator\n plan.migrationType = 'unsupported';\n plan.issues.push('Account has no discriminator - may not be an Agent account');\n plan.recommendations.push('Verify this is actually an Agent account');\n } else if (inspection.discriminatorLength < 8) {\n // Partial discriminator\n plan.migrationType = 'unsupported';\n plan.issues.push(`Partial discriminator detected (${inspection.discriminatorLength} bytes)`);\n plan.recommendations.push('Account data may be corrupted - consider recreation');\n } else {\n // Full 8-byte discriminator but wrong values\n plan.migrationType = 'data_conversion';\n plan.issues.push('Discriminator has correct length but wrong values');\n plan.recommendations.push('May be from a different program version');\n plan.recommendations.push('Check if this account belongs to the correct program');\n }\n\n // Determine if auto-migration is possible\n plan.canAutoMigrate = plan.migrationType === 'recreate' && inspection.dataLength > 8;\n\n return plan;\n}\n\n/**\n * Attempts to extract meaningful data from a legacy account\n */\nexport function extractLegacyData(\n encodedAccount: EncodedAccount | MaybeEncodedAccount\n): LegacyAgentData | null {\n if (!('exists' in encodedAccount) || !encodedAccount.exists || !('data' in encodedAccount) || encodedAccount.data.length < 2) {\n return null;\n }\n\n const data = ('data' in encodedAccount) ? encodedAccount.data : new Uint8Array(0);\n \n try {\n // For accounts with 2-byte discriminator, try to extract what we can\n if (data.length >= 2) {\n return {\n discriminator: data.slice(0, 2),\n // Add more extraction logic here based on known legacy formats\n // This would need to be customized based on actual legacy account structures\n };\n }\n } catch (error) {\n console.warn('Failed to extract legacy data:', error);\n }\n\n return null;\n}\n\n/**\n * Creates a detailed migration report for multiple accounts\n */\nexport async function createMigrationReport(\n accounts: { address: string; encodedAccount: EncodedAccount | MaybeEncodedAccount }[]\n): Promise<{\n summary: {\n total: number;\n valid: number;\n needsMigration: number;\n invalid: number;\n canAutoMigrate: number;\n };\n plans: MigrationPlan[];\n recommendations: string[];\n}> {\n const plans = await Promise.all(accounts.map(({ address, encodedAccount }) => \n createMigrationPlan(encodedAccount, address)\n ));\n\n const summary = {\n total: plans.length,\n valid: plans.filter(p => p.currentState === 'valid').length,\n needsMigration: plans.filter(p => p.currentState === 'needs_migration').length,\n invalid: plans.filter(p => p.currentState === 'invalid').length,\n canAutoMigrate: plans.filter(p => p.canAutoMigrate).length\n };\n\n const recommendations: string[] = [];\n\n if (summary.needsMigration > 0) {\n recommendations.push(`${summary.needsMigration} accounts need migration`);\n }\n\n if (summary.canAutoMigrate > 0) {\n recommendations.push(`${summary.canAutoMigrate} accounts can be auto-migrated`);\n }\n\n if (summary.invalid > 0) {\n recommendations.push(`${summary.invalid} accounts have invalid data and should be investigated`);\n }\n\n if (summary.needsMigration === 0 && summary.invalid === 0) {\n recommendations.push('All accounts are in the correct format');\n } else {\n recommendations.push('Consider running migration utilities to fix account format issues');\n recommendations.push('Backup important account data before migration');\n }\n\n return {\n summary,\n plans,\n recommendations\n };\n}\n\n/**\n * Simulates migration without actually performing it\n */\nexport async function simulateMigration(\n encodedAccount: EncodedAccount | MaybeEncodedAccount,\n address: string\n): Promise<{\n plan: MigrationPlan;\n simulation: {\n wouldSucceed: boolean;\n estimatedSteps: string[];\n warnings: string[];\n requiredActions: string[];\n };\n}> {\n const plan = await createMigrationPlan(encodedAccount, address);\n \n const simulation = {\n wouldSucceed: false,\n estimatedSteps: [] as string[],\n warnings: [] as string[],\n requiredActions: [] as string[]\n };\n\n if (plan.currentState === 'valid') {\n simulation.wouldSucceed = true;\n simulation.estimatedSteps.push('No migration needed - account is already valid');\n return { plan, simulation };\n }\n\n switch (plan.migrationType) {\n case 'recreate':\n simulation.estimatedSteps.push('1. Extract existing account data');\n simulation.estimatedSteps.push('2. Create new account with correct format');\n simulation.estimatedSteps.push('3. Transfer any salvageable data');\n simulation.estimatedSteps.push('4. Close old account');\n simulation.requiredActions.push('User must re-register the agent');\n simulation.warnings.push('Some data may be lost during recreation');\n simulation.wouldSucceed = plan.canAutoMigrate;\n break;\n\n case 'data_conversion':\n simulation.estimatedSteps.push('1. Analyze existing data format');\n simulation.estimatedSteps.push('2. Convert to new format');\n simulation.estimatedSteps.push('3. Update discriminator');\n simulation.warnings.push('Data conversion is experimental');\n simulation.requiredActions.push('Manual verification required');\n simulation.wouldSucceed = false;\n break;\n\n case 'unsupported':\n simulation.estimatedSteps.push('1. Manual investigation required');\n simulation.estimatedSteps.push('2. Determine if account is recoverable');\n simulation.warnings.push('Account may not be recoverable');\n simulation.requiredActions.push('Manual inspection and possible recreation');\n simulation.wouldSucceed = false;\n break;\n\n default:\n simulation.estimatedSteps.push('No migration strategy available');\n simulation.wouldSucceed = false;\n }\n\n return { plan, simulation };\n}\n\n/**\n * Provides user-friendly migration instructions\n */\nexport function getMigrationInstructions(plan: MigrationPlan): string[] {\n const instructions: string[] = [];\n\n switch (plan.migrationType) {\n case 'none':\n instructions.push('✅ No migration needed - your account is up to date');\n break;\n\n case 'recreate':\n instructions.push('🔄 Account Recreation Required:');\n instructions.push('1. Use the CLI command: `ghost agent register` to create a new account');\n instructions.push('2. Configure your agent with the same settings as before');\n instructions.push('3. The old account will be automatically replaced');\n instructions.push('⚠️ Note: You may need to re-verify your agent after recreation');\n break;\n\n case 'data_conversion':\n instructions.push('🔧 Data Conversion Required:');\n instructions.push('1. Contact support for assistance with account conversion');\n instructions.push('2. Manual intervention may be required');\n instructions.push('3. Backup your account data before proceeding');\n break;\n\n case 'unsupported':\n instructions.push('❌ Migration Not Supported:');\n instructions.push('1. This account cannot be automatically migrated');\n instructions.push('2. Consider creating a new account');\n instructions.push('3. Contact support if this account contains important data');\n break;\n }\n\n return instructions;\n}","/**\n * Account Diagnostics Utility\n * \n * Comprehensive diagnostic tools for inspecting and debugging\n * account discriminator issues and data format problems.\n */\n\nimport type { \n Address, \n EncodedAccount, \n MaybeEncodedAccount\n} from '@solana/kit';\n\nimport { \n fetchEncodedAccount\n} from '@solana/kit';\nimport { \n validateAccountDiscriminator, \n inspectAccountData, \n type AccountInspectionResult \n} from './discriminator-validator.js';\nimport { \n createMigrationPlan, \n simulateMigration,\n getMigrationInstructions \n} from './account-migration.js';\nimport { AGENT_DISCRIMINATOR } from '../generated/accounts/agent.js';\n\nexport interface DiagnosticReport {\n address: string;\n timestamp: string;\n accountExists: boolean;\n discriminatorValidation: ReturnType<typeof validateAccountDiscriminator>;\n inspection: AccountInspectionResult;\n migrationPlan: Awaited<ReturnType<typeof createMigrationPlan>>;\n migrationSimulation: Awaited<ReturnType<typeof simulateMigration>>;\n recommendations: string[];\n debugInfo: {\n expectedDiscriminator: number[];\n actualDiscriminator: number[] | null;\n dataPreview: number[];\n programId?: string;\n };\n}\n\nexport interface BatchDiagnosticReport {\n summary: {\n total: number;\n valid: number;\n invalid: number;\n needsMigration: number;\n notExists: number;\n };\n reports: DiagnosticReport[];\n globalRecommendations: string[];\n timestamp: string;\n}\n\n/**\n * Runs comprehensive diagnostics on a single account\n */\nexport async function runAccountDiagnostics(\n encodedAccount: EncodedAccount | MaybeEncodedAccount,\n address: string\n): Promise<DiagnosticReport> {\n const timestamp = new Date().toISOString();\n const accountExists = ('exists' in encodedAccount) && encodedAccount.exists;\n \n let discriminatorValidation, inspection, migrationPlan, migrationSimulation;\n \n if (accountExists) {\n // Import the discriminator\n const { AGENT_DISCRIMINATOR } = await import('../generated/accounts/agent.js');\n discriminatorValidation = validateAccountDiscriminator(encodedAccount.data, AGENT_DISCRIMINATOR);\n inspection = inspectAccountData(encodedAccount, address);\n migrationPlan = await createMigrationPlan(encodedAccount, address);\n migrationSimulation = await simulateMigration(encodedAccount, address);\n } else {\n // Default values for non-existent accounts\n discriminatorValidation = {\n isValid: false,\n actualLength: 0,\n expectedLength: 8,\n canDecode: false,\n needsMigration: false,\n errorMessage: 'Account does not exist'\n };\n inspection = {\n address,\n dataLength: 0,\n discriminator: null,\n discriminatorLength: 0,\n isAgentAccount: false,\n needsMigration: false,\n rawData: new Uint8Array(0)\n };\n migrationPlan = {\n address,\n currentState: 'not_exists' as const,\n migrationType: 'none' as const,\n issues: ['Account does not exist'],\n recommendations: ['Create account using register_agent instruction'],\n canAutoMigrate: false\n };\n migrationSimulation = {\n plan: migrationPlan,\n simulation: {\n wouldSucceed: false,\n estimatedSteps: ['Account must be created first'],\n warnings: [],\n requiredActions: ['Use register_agent instruction']\n }\n };\n }\n\n // Generate recommendations\n const recommendations: string[] = [];\n \n if (!accountExists) {\n recommendations.push('Account does not exist - create using register_agent');\n } else if (discriminatorValidation.isValid) {\n recommendations.push('Account is valid - no action needed');\n } else {\n recommendations.push(...getMigrationInstructions(migrationPlan));\n }\n\n // Create debug info\n const debugInfo = {\n expectedDiscriminator: Array.from(AGENT_DISCRIMINATOR),\n actualDiscriminator: inspection.discriminator ? Array.from(inspection.discriminator) : null,\n dataPreview: Array.from(inspection.rawData.slice(0, 32)),\n programId: (accountExists && ('owner' in encodedAccount) ? encodedAccount.owner : undefined) as string | undefined\n };\n\n return {\n address,\n timestamp,\n accountExists,\n discriminatorValidation,\n inspection,\n migrationPlan,\n migrationSimulation,\n recommendations,\n debugInfo\n };\n}\n\n/**\n * Runs diagnostics on multiple accounts\n */\nexport async function runBatchDiagnostics(\n accounts: { address: string; encodedAccount: EncodedAccount | MaybeEncodedAccount }[]\n): Promise<BatchDiagnosticReport> {\n const timestamp = new Date().toISOString();\n const reports = await Promise.all(accounts.map(({ address, encodedAccount }) => \n runAccountDiagnostics(encodedAccount, address)\n ));\n\n const summary = {\n total: reports.length,\n valid: reports.filter(r => r.accountExists && r.discriminatorValidation.isValid).length,\n invalid: reports.filter(r => r.accountExists && !r.discriminatorValidation.isValid).length,\n needsMigration: reports.filter(r => r.migrationPlan.currentState === 'needs_migration').length,\n notExists: reports.filter(r => !r.accountExists).length\n };\n\n const globalRecommendations: string[] = [];\n \n if (summary.notExists > 0) {\n globalRecommendations.push(`${summary.notExists} accounts need to be created`);\n }\n if (summary.needsMigration > 0) {\n globalRecommendations.push(`${summary.needsMigration} accounts need migration`);\n }\n if (summary.invalid > 0) {\n globalRecommendations.push(`${summary.invalid} accounts have data issues`);\n }\n if (summary.valid === summary.total) {\n globalRecommendations.push('All accounts are healthy');\n }\n\n return {\n summary,\n reports,\n globalRecommendations,\n timestamp\n };\n}\n\n/**\n * Fetches and diagnoses an account directly from the blockchain\n */\nexport async function diagnoseAccountFromChain(\n rpc: Parameters<typeof fetchEncodedAccount>[0],\n address: Address,\n options?: { logToConsole?: boolean }\n): Promise<DiagnosticReport> {\n try {\n const encodedAccount = await fetchEncodedAccount(rpc, address);\n const report = await runAccountDiagnostics(encodedAccount, address);\n \n if (options?.logToConsole) {\n console.group(`🔍 Account Diagnostics: ${address}`);\n console.log('Exists:', report.accountExists);\n console.log('Valid:', report.discriminatorValidation.isValid);\n console.log('Needs Migration:', report.migrationPlan.currentState === 'needs_migration');\n console.log('Recommendations:');\n report.recommendations.forEach(rec => console.log(` - ${rec}`));\n \n if (!report.discriminatorValidation.isValid) {\n console.log('Issues:');\n if (Array.isArray(report.migrationPlan.issues)) {\n report.migrationPlan.issues.forEach((issue: string) => console.log(` - ${issue}`));\n }\n }\n \n console.groupEnd();\n }\n \n return report;\n } catch (err) {\n console.error(`Failed to diagnose account ${address}:`, err);\n \n // Return a diagnostic report for the error case\n return {\n address,\n timestamp: new Date().toISOString(),\n accountExists: false,\n discriminatorValidation: {\n isValid: false,\n actualLength: 0,\n expectedLength: 8,\n canDecode: false,\n needsMigration: false,\n errorMessage: `Failed to fetch account: ${err instanceof Error ? err.message : String(err)}`\n },\n inspection: {\n address,\n dataLength: 0,\n discriminator: null,\n discriminatorLength: 0,\n isAgentAccount: false,\n needsMigration: false,\n rawData: new Uint8Array(0)\n },\n migrationPlan: {\n address,\n currentState: 'invalid',\n migrationType: 'unsupported',\n issues: [`Failed to fetch account: ${err instanceof Error ? err.message : String(err)}`],\n recommendations: ['Check network connection and account address'],\n canAutoMigrate: false\n },\n migrationSimulation: {\n plan: {\n address,\n currentState: 'invalid',\n migrationType: 'unsupported',\n issues: [`Failed to fetch account: ${err instanceof Error ? err.message : String(err)}`],\n recommendations: ['Check network connection and account address'],\n canAutoMigrate: false\n },\n simulation: {\n wouldSucceed: false,\n estimatedSteps: ['Fix network connectivity issues'],\n warnings: ['Account could not be fetched'],\n requiredActions: ['Verify account address and network connection']\n }\n },\n recommendations: ['Check network connection and account address'],\n debugInfo: {\n expectedDiscriminator: Array.from(AGENT_DISCRIMINATOR),\n actualDiscriminator: null,\n dataPreview: [],\n programId: undefined\n }\n };\n }\n}\n\n/**\n * Fetches and diagnoses multiple accounts from the blockchain\n */\nexport async function diagnoseBatchFromChain(\n rpc: Parameters<typeof fetchEncodedAccount>[0],\n addresses: Address[],\n options?: { \n logToConsole?: boolean;\n maxConcurrent?: number;\n }\n): Promise<BatchDiagnosticReport> {\n const maxConcurrent = options?.maxConcurrent ?? 10;\n const reports: DiagnosticReport[] = [];\n \n // Process accounts in batches to avoid overwhelming the RPC\n for (let i = 0; i < addresses.length; i += maxConcurrent) {\n const batch = addresses.slice(i, i + maxConcurrent);\n const batchPromises = batch.map(address => \n diagnoseAccountFromChain(rpc, address, { logToConsole: false })\n );\n \n const batchReports = await Promise.allSettled(batchPromises);\n \n for (const result of batchReports) {\n if (result.status === 'fulfilled') {\n reports.push(result.value);\n } else {\n console.error('Failed to diagnose account:', result.reason);\n // Add a fallback report for failed fetches\n reports.push({\n address: 'unknown',\n timestamp: new Date().toISOString(),\n accountExists: false,\n discriminatorValidation: {\n isValid: false,\n actualLength: 0,\n expectedLength: 8,\n canDecode: false,\n needsMigration: false,\n errorMessage: 'Failed to fetch account'\n },\n inspection: {\n address: 'unknown',\n dataLength: 0,\n discriminator: null,\n discriminatorLength: 0,\n isAgentAccount: false,\n needsMigration: false,\n rawData: new Uint8Array(0)\n },\n migrationPlan: {\n address: 'unknown',\n currentState: 'invalid',\n migrationType: 'unsupported',\n issues: ['Failed to fetch account'],\n recommendations: ['Check network connection'],\n canAutoMigrate: false\n },\n migrationSimulation: {\n plan: {\n address: 'unknown',\n currentState: 'invalid' as const,\n migrationType: 'unsupported' as const,\n issues: ['Failed to fetch account'],\n recommendations: ['Check network connection'],\n canAutoMigrate: false\n },\n simulation: {\n wouldSucceed: false,\n estimatedSteps: ['Fix fetch issues'],\n warnings: ['Account could not be fetched'],\n requiredActions: ['Check network']\n }\n },\n recommendations: ['Check network connection'],\n debugInfo: {\n expectedDiscriminator: Array.from(AGENT_DISCRIMINATOR),\n actualDiscriminator: null,\n dataPreview: [],\n programId: undefined\n }\n });\n }\n }\n }\n\n const batchReport = await runBatchDiagnostics(\n reports.map(report => ({\n address: report.address,\n encodedAccount: {\n exists: report.accountExists,\n data: report.inspection.rawData,\n address: report.address,\n owner: report.debugInfo.programId ?? '',\n executable: false,\n lamports: 0n,\n programAddress: report.debugInfo.programId ?? '',\n space: report.inspection.rawData.length\n } as unknown as EncodedAccount\n }))\n );\n\n if (options?.logToConsole) {\n console.group('🔍 Batch Diagnostics Summary');\n console.log('Total accounts:', batchReport.summary.total);\n console.log('Valid accounts:', batchReport.summary.valid);\n console.log('Invalid accounts:', batchReport.summary.invalid);\n console.log('Need migration:', batchReport.summary.needsMigration);\n console.log('Do not exist:', batchReport.summary.notExists);\n console.log('Global recommendations:');\n batchReport.globalRecommendations.forEach(rec => console.log(` - ${rec}`));\n console.groupEnd();\n }\n\n return batchReport;\n}\n\n/**\n * Exports a diagnostic report as JSON\n */\nexport function exportDiagnosticReport(\n report: DiagnosticReport | BatchDiagnosticReport,\n filename?: string\n): string {\n const json = JSON.stringify(report, null, 2);\n \n if (filename) {\n // In a browser environment, you might want to trigger a download\n // In Node.js, you might want to write to file\n console.log(`Diagnostic report would be saved as: ${filename}`);\n console.log('Report data:', json);\n }\n \n return json;\n}","/**\n * Token Utilities for SPL Token and Token 2022 (Token Extensions)\n * \n * Provides comprehensive token handling utilities including:\n * - Associated Token Account (ATA) derivation for both SPL Token and Token 2022\n * - Token 2022 specific features (transfer fees, confidential transfers, etc.)\n * - Token program detection and validation\n * - Account creation and management utilities\n * \n * Based on the latest SPL Token 2022 specification and @solana/kit v2.3.0\n */\n\nimport type { Address } from '@solana/addresses'\nimport { \n getProgramDerivedAddress,\n getAddressEncoder\n} from '@solana/kit'\nimport { \n TOKEN_PROGRAM_ADDRESS,\n TOKEN_2022_PROGRAM_ADDRESS,\n ASSOCIATED_TOKEN_PROGRAM_ADDRESS \n} from '../constants/system-addresses.js'\n\n// =====================================================\n// TYPES AND INTERFACES\n// =====================================================\n\n/**\n * Token program variants supported by GhostSpeak\n */\nexport enum TokenProgram {\n /** Original SPL Token Program */\n SPL_TOKEN = 'spl-token',\n /** SPL Token 2022 (Token Extensions) Program */\n TOKEN_2022 = 'token-2022'\n}\n\n/**\n * Associated Token Account information\n */\nexport interface AssociatedTokenAccount {\n /** The derived ATA address */\n address: Address\n /** The wallet/owner address */\n owner: Address\n /** The token mint address */\n mint: Address\n /** The token program used (SPL Token or Token 2022) */\n tokenProgram: Address\n /** Whether this is a Token 2022 ATA */\n isToken2022: boolean\n}\n\n/**\n * Token 2022 Extension Types\n * Based on the latest Token Extensions specification\n */\nexport enum TokenExtension {\n /** Uninitialized account */\n UNINITIALIZED = 0,\n /** Transfer fee extension */\n TRANSFER_FEE_CONFIG = 1,\n /** Transfer fee amount */\n TRANSFER_FEE_AMOUNT = 2,\n /** Mint close authority */\n MINT_CLOSE_AUTHORITY = 3,\n /** Confidential transfer mint */\n CONFIDENTIAL_TRANSFER_MINT = 4,\n /** Confidential transfer account */\n CONFIDENTIAL_TRANSFER_ACCOUNT = 5,\n /** Default account state */\n DEFAULT_ACCOUNT_STATE = 6,\n /** Immutable owner */\n IMMUTABLE_OWNER = 7,\n /** Memo transfer */\n MEMO_TRANSFER = 8,\n /** Non-transferable */\n NON_TRANSFERABLE = 9,\n /** Interest bearing mint */\n INTEREST_BEARING_MINT = 10,\n /** CPI guard */\n CPI_GUARD = 11,\n /** Permanent delegate */\n PERMANENT_DELEGATE = 12,\n /** Non-transferable account */\n NON_TRANSFERABLE_ACCOUNT = 13,\n /** Transfer hook */\n TRANSFER_HOOK = 14,\n /** Transfer hook account */\n TRANSFER_HOOK_ACCOUNT = 15,\n /** Metadata pointer */\n METADATA_POINTER = 16,\n /** Token metadata */\n TOKEN_METADATA = 17,\n /** Group pointer */\n GROUP_POINTER = 18,\n /** Token group */\n TOKEN_GROUP = 19,\n /** Group member pointer */\n GROUP_MEMBER_POINTER = 20,\n /** Token group member */\n TOKEN_GROUP_MEMBER = 21\n}\n\n/**\n * Transfer fee configuration for Token 2022\n */\nexport interface TransferFeeConfig {\n /** Transfer fee basis points (0-10000, where 10000 = 100%) */\n transferFeeBasisPoints: number\n /** Maximum transfer fee in token base units */\n maximumFee: bigint\n /** Authority that can modify transfer fee config */\n transferFeeConfigAuthority: Address | null\n /** Authority that can withdraw collected fees */\n withdrawWithheldAuthority: Address | null\n /** Amount of fees currently withheld */\n withheldAmount: bigint\n /** Older transfer fee configuration */\n olderTransferFee: {\n epoch: bigint\n transferFeeBasisPoints: number\n maximumFee: bigint\n }\n /** Newer transfer fee configuration */\n newerTransferFee: {\n epoch: bigint\n transferFeeBasisPoints: number\n maximumFee: bigint\n }\n}\n\n/**\n * Confidential transfer configuration for Token 2022\n */\nexport interface ConfidentialTransferConfig {\n /** Authority that can configure confidential transfers */\n authority: Address | null\n /** Automatically approve new accounts for confidential transfers */\n autoApproveNewAccounts: boolean\n /** Public key for auditing confidential transfers */\n auditorElgamalPubkey: Uint8Array | null\n}\n\n/**\n * Interest-bearing token configuration for Token 2022\n */\nexport interface InterestBearingConfig {\n /** Authority that can update the interest rate */\n rateAuthority: Address | null\n /** Current interest rate (basis points per year) */\n currentRate: number\n /** Timestamp when interest bearing was initialized */\n initializationTimestamp: bigint\n /** Timestamp of last rate update */\n lastUpdateTimestamp: bigint\n /** Pre-computed interest rate */\n preUpdateAverageRate: number\n}\n\n// =====================================================\n// CORE ATA DERIVATION FUNCTIONS\n// =====================================================\n\n/**\n * Derive Associated Token Account address for any token program\n * \n * This is the core ATA derivation function that works with both\n * SPL Token and Token 2022 programs. The derivation follows the\n * standard pattern: ['owner', 'token_program', 'mint']\n * \n * @param owner - The wallet/owner address\n * @param mint - The token mint address\n * @param tokenProgram - The token program address (SPL Token or Token 2022)\n * @returns Promise<Address> - The derived ATA address\n */\nexport async function deriveAssociatedTokenAddress(\n owner: Address,\n mint: Address,\n tokenProgram: Address = TOKEN_PROGRAM_ADDRESS\n): Promise<Address> {\n const [address] = await getProgramDerivedAddress({\n programAddress: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,\n seeds: [\n getAddressEncoder().encode(owner),\n getAddressEncoder().encode(tokenProgram),\n getAddressEncoder().encode(mint)\n ]\n })\n return address\n}\n\n/**\n * Derive Associated Token Account for SPL Token (legacy)\n * \n * @param owner - The wallet/owner address\n * @param mint - The token mint address\n * @returns Promise<Address> - The derived ATA address\n */\nexport async function deriveSplTokenAssociatedTokenAddress(\n owner: Address,\n mint: Address\n): Promise<Address> {\n return deriveAssociatedTokenAddress(owner, mint, TOKEN_PROGRAM_ADDRESS)\n}\n\n/**\n * Derive Associated Token Account for Token 2022\n * \n * @param owner - The wallet/owner address\n * @param mint - The token mint address\n * @returns Promise<Address> - The derived ATA address\n */\nexport async function deriveToken2022AssociatedTokenAddress(\n owner: Address,\n mint: Address\n): Promise<Address> {\n return deriveAssociatedTokenAddress(owner, mint, TOKEN_2022_PROGRAM_ADDRESS)\n}\n\n/**\n * Get complete ATA information including program detection\n * \n * @param owner - The wallet/owner address\n * @param mint - The token mint address\n * @param tokenProgram - Optional: specify token program, auto-detect if not provided\n * @returns Promise<AssociatedTokenAccount> - Complete ATA information\n */\nexport async function getAssociatedTokenAccount(\n owner: Address,\n mint: Address,\n tokenProgram?: Address\n): Promise<AssociatedTokenAccount> {\n // If token program not specified, default to SPL Token\n // In practice, you might want to detect this from the mint account\n const program = tokenProgram ?? TOKEN_PROGRAM_ADDRESS\n const isToken2022 = program === TOKEN_2022_PROGRAM_ADDRESS\n \n const address = await deriveAssociatedTokenAddress(owner, mint, program)\n \n return {\n address,\n owner,\n mint,\n tokenProgram: program,\n isToken2022\n }\n}\n\n// =====================================================\n// TOKEN PROGRAM DETECTION\n// =====================================================\n\n/**\n * Detect which token program owns a given mint\n * Note: This requires RPC calls to fetch mint account data\n * \n * @param mint - The token mint address\n * @returns Promise<Address> - The token program address\n */\nexport async function detectTokenProgram(\n mint: Address, \n rpcEndpoint = 'https://api.devnet.solana.com'\n): Promise<Address> {\n try {\n // Import RPC utilities for account fetching\n const { createSolanaRpc } = await import('@solana/kit')\n const rpc = createSolanaRpc(rpcEndpoint)\n \n // Fetch mint account info with safe base64 encoding\n const accountInfo = await rpc.getAccountInfo(mint, {\n encoding: 'base64',\n commitment: 'confirmed'\n }).send()\n \n if (!accountInfo.value) {\n throw new Error(`Mint account ${mint} not found`)\n }\n \n // Check the owner program - this determines which token program owns the mint\n const ownerProgram = accountInfo.value.owner\n \n // Compare against known token program addresses\n if (ownerProgram === TOKEN_PROGRAM_ADDRESS) {\n return TOKEN_PROGRAM_ADDRESS\n } else if (ownerProgram === TOKEN_2022_PROGRAM_ADDRESS) {\n return TOKEN_2022_PROGRAM_ADDRESS \n } else {\n // Unknown program - default to SPL Token for safety\n console.warn(`Unknown token program owner: ${ownerProgram}, defaulting to SPL Token`)\n return TOKEN_PROGRAM_ADDRESS\n }\n } catch (error) {\n console.error(`Failed to detect token program for mint ${mint}:`, error)\n // Default to SPL Token on error\n return TOKEN_PROGRAM_ADDRESS\n }\n}\n\n/**\n * Check if a mint is a Token 2022 mint\n * \n * @param mint - The token mint address\n * @returns Promise<boolean> - True if Token 2022, false if SPL Token\n */\nexport async function isToken2022Mint(mint: Address): Promise<boolean> {\n const program = await detectTokenProgram(mint)\n return program === TOKEN_2022_PROGRAM_ADDRESS\n}\n\n/**\n * Get the appropriate token program for a given mint\n * \n * @param mint - The token mint address\n * @returns Promise<TokenProgram> - The token program enum\n */\nexport async function getTokenProgramType(mint: Address): Promise<TokenProgram> {\n const isToken2022 = await isToken2022Mint(mint)\n return isToken2022 ? TokenProgram.TOKEN_2022 : TokenProgram.SPL_TOKEN\n}\n\n// =====================================================\n// TOKEN 2022 EXTENSION UTILITIES\n// =====================================================\n\n\n/**\n * Check if a mint has specific Token 2022 extensions\n * Note: This requires RPC calls to fetch and parse mint account data\n * \n * @param mint - The token mint address\n * @param extensions - Array of extensions to check for\n * @returns Promise<Record<TokenExtension, boolean>> - Extension presence map\n */\nexport async function checkToken2022Extensions(\n mint: Address,\n extensions: TokenExtension[],\n _rpcEndpoint = 'https://api.devnet.solana.com'\n): Promise<Record<TokenExtension, boolean>> {\n // Token-2022 extension checking removed - not aligned with VC/Reputation pivot\n console.warn(`Token-2022 extension checking is deprecated: mint ${mint}`)\n const result = {} as Record<TokenExtension, boolean>\n for (const extension of extensions) {\n result[extension] = false\n }\n return result\n}\n\n/**\n * Check if a mint has the transfer fee extension\n * \n * @param mint - The token mint address\n * @param rpcEndpoint - Optional RPC endpoint\n * @returns Promise<boolean> - True if mint has transfer fee extension\n */\nexport async function hasTransferFeeExtension(\n mint: Address,\n rpcEndpoint = 'https://api.devnet.solana.com'\n): Promise<boolean> {\n const result = await checkToken2022Extensions(\n mint,\n [TokenExtension.TRANSFER_FEE_CONFIG],\n rpcEndpoint\n )\n return result[TokenExtension.TRANSFER_FEE_CONFIG]\n}\n\n/**\n * Check if a mint has the confidential transfer extension\n * \n * @param mint - The token mint address\n * @param rpcEndpoint - Optional RPC endpoint\n * @returns Promise<boolean> - True if mint has confidential transfer extension\n */\nexport async function hasConfidentialTransferExtension(\n mint: Address,\n rpcEndpoint = 'https://api.devnet.solana.com'\n): Promise<boolean> {\n const result = await checkToken2022Extensions(\n mint,\n [TokenExtension.CONFIDENTIAL_TRANSFER_MINT],\n rpcEndpoint\n )\n return result[TokenExtension.CONFIDENTIAL_TRANSFER_MINT]\n}\n\n/**\n * Check if a mint has the interest-bearing extension\n * \n * @param mint - The token mint address\n * @param rpcEndpoint - Optional RPC endpoint\n * @returns Promise<boolean> - True if mint has interest-bearing extension\n */\nexport async function hasInterestBearingExtension(\n mint: Address,\n rpcEndpoint = 'https://api.devnet.solana.com'\n): Promise<boolean> {\n const result = await checkToken2022Extensions(\n mint,\n [TokenExtension.INTEREST_BEARING_MINT],\n rpcEndpoint\n )\n return result[TokenExtension.INTEREST_BEARING_MINT]\n}\n\n/**\n * Get transfer fee configuration for a Token 2022 mint\n * \n * @param mint - The Token 2022 mint address\n * @returns Promise<TransferFeeConfig | null> - Transfer fee config or null if not configured\n */\nexport async function getTransferFeeConfig(\n mint: Address,\n _rpcEndpoint = 'https://api.devnet.solana.com'\n): Promise<TransferFeeConfig | null> {\n // Token-2022 extension functions removed - not aligned with VC/Reputation pivot\n console.warn(`Token-2022 getTransferFeeConfig is deprecated: mint ${mint}`)\n return null\n}\n\n/**\n * Get confidential transfer configuration for a Token 2022 mint\n * \n * @param mint - The Token 2022 mint address \n * @returns Promise<ConfidentialTransferConfig | null> - Confidential transfer config or null\n */\nexport async function getConfidentialTransferConfig(\n mint: Address,\n _rpcEndpoint = 'https://api.devnet.solana.com'\n): Promise<ConfidentialTransferConfig | null> {\n // Token-2022 extension functions removed - not aligned with VC/Reputation pivot\n console.warn(`Token-2022 getConfidentialTransferConfig is deprecated: mint ${mint}`)\n return null\n}\n\n/**\n * Get interest-bearing configuration for a Token 2022 mint\n * \n * @param mint - The Token 2022 mint address\n * @returns Promise<InterestBearingConfig | null> - Interest-bearing config or null\n */\nexport async function getInterestBearingConfig(\n mint: Address,\n _rpcEndpoint = 'https://api.devnet.solana.com'\n): Promise<InterestBearingConfig | null> {\n // Token-2022 extension functions removed - not aligned with VC/Reputation pivot\n console.warn(`Token-2022 getInterestBearingConfig is deprecated: mint ${mint}`)\n return null\n}\n\n// =====================================================\n// TOKEN ACCOUNT UTILITIES \n// =====================================================\n\n/**\n * Calculate rent-exempt minimum for a token account with extensions\n * \n * @param extensions - Array of extensions the account will have\n * @returns bigint - Minimum lamports required for rent exemption\n */\nexport function calculateTokenAccountRent(extensions: TokenExtension[] = []): bigint {\n // Base token account size: 165 bytes\n let accountSize = 165\n \n // Add space for each extension (simplified calculation)\n for (const extension of extensions) {\n switch (extension) {\n case TokenExtension.TRANSFER_FEE_AMOUNT:\n accountSize += 8 + 8 // u64 + u64 for withheld amounts\n break\n case TokenExtension.CONFIDENTIAL_TRANSFER_ACCOUNT:\n accountSize += 286 // Complex confidential transfer data\n break\n case TokenExtension.IMMUTABLE_OWNER:\n accountSize += 0 // No additional space needed\n break\n case TokenExtension.MEMO_TRANSFER:\n accountSize += 1 // u8 flag\n break\n case TokenExtension.NON_TRANSFERABLE_ACCOUNT:\n accountSize += 0 // No additional space needed\n break\n case TokenExtension.CPI_GUARD:\n accountSize += 1 // u8 flag\n break\n case TokenExtension.TRANSFER_HOOK_ACCOUNT:\n accountSize += 1 // u8 flag\n break\n default:\n accountSize += 8 // Default additional space for unknown extensions\n }\n }\n \n // Rough calculation: ~6,960 lamports per 128 bytes (current Solana rates)\n // This is a simplified calculation - actual implementation should use RPC\n const lamportsPerByte = BigInt(54) // Approximate current rate\n return BigInt(accountSize) * lamportsPerByte\n}\n\n/**\n * Get all possible ATA addresses for a wallet/mint pair\n * Returns both SPL Token and Token 2022 ATAs\n * \n * @param owner - The wallet/owner address\n * @param mint - The token mint address \n * @returns Promise<{ splToken: Address, token2022: Address }> - Both ATA addresses\n */\nexport async function getAllAssociatedTokenAddresses(\n owner: Address,\n mint: Address\n): Promise<{ splToken: Address, token2022: Address }> {\n const [splToken, token2022] = await Promise.all([\n deriveSplTokenAssociatedTokenAddress(owner, mint),\n deriveToken2022AssociatedTokenAddress(owner, mint)\n ])\n \n return { splToken, token2022 }\n}\n\n/**\n * Validate if an address could be a valid ATA\n * \n * @param address - The address to validate\n * @param owner - The expected owner\n * @param mint - The expected mint \n * @returns Promise<{ isValid: boolean, program?: Address }> - Validation result\n */\nexport async function validateAssociatedTokenAddress(\n address: Address,\n owner: Address,\n mint: Address\n): Promise<{ isValid: boolean, program?: Address }> {\n const addresses = await getAllAssociatedTokenAddresses(owner, mint)\n \n if (address === addresses.splToken) {\n return { isValid: true, program: TOKEN_PROGRAM_ADDRESS }\n }\n \n if (address === addresses.token2022) {\n return { isValid: true, program: TOKEN_2022_PROGRAM_ADDRESS }\n }\n \n return { isValid: false }\n}\n\n// =====================================================\n// HELPER FUNCTIONS\n// =====================================================\n\n/**\n * Convert TokenProgram enum to program address\n * \n * @param program - The token program enum\n * @returns Address - The program address\n */\nexport function getTokenProgramAddress(program: TokenProgram): Address {\n switch (program) {\n case TokenProgram.SPL_TOKEN:\n return TOKEN_PROGRAM_ADDRESS\n case TokenProgram.TOKEN_2022:\n return TOKEN_2022_PROGRAM_ADDRESS\n default:\n throw new Error(`Unknown token program: ${program}`)\n }\n}\n\n/**\n * Convert program address to TokenProgram enum\n * \n * @param address - The program address\n * @returns TokenProgram - The token program enum\n */\nexport function getTokenProgramFromAddress(address: Address): TokenProgram {\n if (address === TOKEN_PROGRAM_ADDRESS) {\n return TokenProgram.SPL_TOKEN\n }\n if (address === TOKEN_2022_PROGRAM_ADDRESS) {\n return TokenProgram.TOKEN_2022\n }\n throw new Error(`Unknown token program address: ${address}`)\n}\n\n/**\n * Format token amount with proper decimals\n * \n * @param amount - Raw token amount (in base units)\n * @param decimals - Number of decimal places for the token\n * @returns string - Formatted amount\n */\nexport function formatTokenAmount(amount: bigint, decimals: number): string {\n const divisor = BigInt(10 ** decimals)\n const quotient = amount / divisor\n const remainder = amount % divisor\n \n if (remainder === BigInt(0)) {\n return quotient.toString()\n }\n \n const remainderStr = remainder.toString().padStart(decimals, '0')\n const trimmedRemainder = remainderStr.replace(/0+$/, '')\n \n return `${quotient}.${trimmedRemainder}`\n}\n\n/**\n * Parse formatted token amount to raw base units\n * \n * @param formatted - Formatted token amount string\n * @param decimals - Number of decimal places for the token\n * @returns bigint - Raw token amount\n */\nexport function parseTokenAmount(formatted: string, decimals: number): bigint {\n const [whole, fraction = ''] = formatted.split('.')\n const paddedFraction = fraction.padEnd(decimals, '0').slice(0, decimals)\n const rawAmount = whole + paddedFraction\n return BigInt(rawAmount)\n}\n\n/**\n * Get token extension data from mint account\n * \n * @param mintData - The mint account data from getMintWithExtensions\n * @param extensionType - The extension type to get\n * @returns Extension data or null if not found\n */\nexport function getTokenExtensionData(\n mintData: { extensions?: Record<string, unknown> } | null,\n extensionType: TokenExtension\n): Buffer | null {\n if (!mintData?.extensions) {\n return null\n }\n\n // Map extension type enum to string keys used in the parsed extensions\n const extensionKeys: Record<TokenExtension, string> = {\n [TokenExtension.UNINITIALIZED]: 'uninitialized',\n [TokenExtension.TRANSFER_FEE_CONFIG]: 'transferFeeConfig',\n [TokenExtension.TRANSFER_FEE_AMOUNT]: 'transferFeeAmount',\n [TokenExtension.MINT_CLOSE_AUTHORITY]: 'mintCloseAuthority',\n [TokenExtension.CONFIDENTIAL_TRANSFER_MINT]: 'confidentialTransferMint',\n [TokenExtension.CONFIDENTIAL_TRANSFER_ACCOUNT]: 'confidentialTransferAccount',\n [TokenExtension.DEFAULT_ACCOUNT_STATE]: 'defaultAccountState',\n [TokenExtension.IMMUTABLE_OWNER]: 'immutableOwner',\n [TokenExtension.MEMO_TRANSFER]: 'memoTransfer',\n [TokenExtension.NON_TRANSFERABLE]: 'nonTransferable',\n [TokenExtension.INTEREST_BEARING_MINT]: 'interestBearingConfig',\n [TokenExtension.CPI_GUARD]: 'cpiGuard',\n [TokenExtension.PERMANENT_DELEGATE]: 'permanentDelegate',\n [TokenExtension.NON_TRANSFERABLE_ACCOUNT]: 'nonTransferableAccount',\n [TokenExtension.TRANSFER_HOOK]: 'transferHook',\n [TokenExtension.TRANSFER_HOOK_ACCOUNT]: 'transferHookAccount',\n [TokenExtension.METADATA_POINTER]: 'metadataPointer',\n [TokenExtension.TOKEN_METADATA]: 'tokenMetadata',\n [TokenExtension.GROUP_POINTER]: 'groupPointer',\n [TokenExtension.TOKEN_GROUP]: 'tokenGroup',\n [TokenExtension.GROUP_MEMBER_POINTER]: 'groupMemberPointer',\n [TokenExtension.TOKEN_GROUP_MEMBER]: 'tokenGroupMember'\n }\n\n const extensionKey = extensionKeys[extensionType]\n const extensionData = mintData.extensions[extensionKey]\n\n if (!extensionData) {\n return null\n }\n\n // Convert extension data to Buffer for backward compatibility\n // In the future, we might want to return the parsed data directly\n try {\n return Buffer.from(JSON.stringify(extensionData))\n } catch {\n return null\n }\n}\n\n/**\n * Parse transfer fee configuration from extension data\n * \n * @param extensionData - The raw extension data or parsed extension object\n * @returns TransferFeeConfig - Parsed transfer fee configuration\n */\nexport function parseTransferFeeConfig(\n extensionData: Buffer | unknown\n): TransferFeeConfig {\n try {\n let parsedData: unknown\n\n // Handle both Buffer (from getTokenExtensionData) and direct parsed data\n if (Buffer.isBuffer(extensionData)) {\n const dataStr = extensionData.toString()\n parsedData = JSON.parse(dataStr)\n } else {\n parsedData = extensionData\n }\n\n // Type guard and validation for transfer fee config structure\n if (parsedData && typeof parsedData === 'object') {\n const config = parsedData as {\n transferFeeBasisPoints?: number\n maximumFee?: bigint | string | number\n transferFeeConfigAuthority?: Address | null | string\n withdrawWithheldAuthority?: Address | null | string\n }\n\n return {\n transferFeeBasisPoints: config.transferFeeBasisPoints ?? 0,\n maximumFee: typeof config.maximumFee === 'bigint' \n ? config.maximumFee \n : BigInt(config.maximumFee ?? 0),\n transferFeeConfigAuthority: config.transferFeeConfigAuthority as Address | null ?? null,\n withdrawWithheldAuthority: config.withdrawWithheldAuthority as Address | null ?? null,\n withheldAmount: BigInt(0),\n olderTransferFee: {\n epoch: BigInt(0),\n transferFeeBasisPoints: 0,\n maximumFee: BigInt(0)\n },\n newerTransferFee: {\n epoch: BigInt(1),\n transferFeeBasisPoints: config.transferFeeBasisPoints ?? 0,\n maximumFee: typeof config.maximumFee === 'bigint' \n ? config.maximumFee \n : BigInt(config.maximumFee ?? 0)\n }\n }\n }\n } catch (error) {\n console.warn('Failed to parse transfer fee config:', error)\n }\n\n // Return default config if parsing fails\n return {\n transferFeeBasisPoints: 0,\n maximumFee: BigInt(0),\n transferFeeConfigAuthority: null,\n withdrawWithheldAuthority: null,\n withheldAmount: BigInt(0),\n olderTransferFee: {\n epoch: BigInt(0),\n transferFeeBasisPoints: 0,\n maximumFee: BigInt(0)\n },\n newerTransferFee: {\n epoch: BigInt(1),\n transferFeeBasisPoints: 0,\n maximumFee: BigInt(0)\n }\n }\n}\n\n/**\n * Fetch transfer fee configuration for a Token-2022 mint via RPC\n * \n * @deprecated Token-2022 extension functions removed - not aligned with VC/Reputation pivot\n * @param _rpc - RPC client for making requests\n * @param mint - The mint address to query\n * @returns Promise<TransferFeeConfig | null> - Always returns null (deprecated)\n */\nexport async function fetchTransferFeeConfig(\n _rpc: unknown,\n mint: Address\n): Promise<TransferFeeConfig | null> {\n console.warn(`Token-2022 fetchTransferFeeConfig is deprecated: mint ${mint}`)\n return null\n}\n\n/**\n * Check if a mint has transfer fees enabled\n * \n * @deprecated Token-2022 extension functions removed - not aligned with VC/Reputation pivot\n * @param _rpc - RPC client for making requests \n * @param mint - The mint address to check\n * @returns Promise<boolean> - Always returns false (deprecated)\n */\nexport async function hasTransferFees(\n _rpc: unknown,\n mint: Address\n): Promise<boolean> {\n console.warn(`Token-2022 hasTransferFees is deprecated: mint ${mint}`)\n return false\n}","/**\n * Governance Helper Utilities\n * \n * Comprehensive utilities for RBAC management, multi-signature wallets,\n * proposal lifecycle, and voting mechanisms.\n */\n\nimport type { Address } from '@solana/kit'\nimport { getAddressEncoder, getProgramDerivedAddress, getBytesEncoder } from '@solana/kit'\nimport {\n ProposalStatus,\n VoteChoice,\n // type Multisig, // TODO: Re-enable after multisig account is regenerated\n type GovernanceProposal,\n // type RbacConfig, // TODO: Re-enable after rbacConfig account is regenerated\n // type Role, // TODO: Re-enable after role type is regenerated\n type VotingResults,\n type QuorumRequirements\n} from '../generated/index.js'\n\n// =====================================================\n// PDA DERIVATION\n// =====================================================\n\n/**\n * Derive multisig account PDA\n */\nexport async function deriveMultisigPda(\n programId: Address,\n authority: Address,\n multisigId: bigint\n): Promise<Address> {\n const [pda] = await getProgramDerivedAddress({\n programAddress: programId,\n seeds: [\n getBytesEncoder().encode(new Uint8Array([109, 117, 108, 116, 105, 115, 105, 103])), // 'multisig'\n getAddressEncoder().encode(authority),\n new Uint8Array(new BigUint64Array([multisigId]).buffer)\n ]\n })\n return pda\n}\n\n/**\n * Derive proposal account PDA\n */\nexport async function deriveProposalPda(\n programId: Address,\n multisig: Address,\n proposalId: bigint\n): Promise<Address> {\n const [pda] = await getProgramDerivedAddress({\n programAddress: programId,\n seeds: [\n getBytesEncoder().encode(new Uint8Array([112, 114, 111, 112, 111, 115, 97, 108])), // 'proposal'\n getAddressEncoder().encode(multisig),\n new Uint8Array(new BigUint64Array([proposalId]).buffer)\n ]\n })\n return pda\n}\n\n/**\n * Derive RBAC account PDA\n */\nexport async function deriveRbacPda(\n programId: Address,\n admin: Address\n): Promise<Address> {\n const [pda] = await getProgramDerivedAddress({\n programAddress: programId,\n seeds: [\n getBytesEncoder().encode(new Uint8Array([114, 98, 97, 99])), // 'rbac'\n getAddressEncoder().encode(admin)\n ]\n })\n return pda\n}\n\n// =====================================================\n// MULTISIG UTILITIES\n// =====================================================\n// TODO: Re-enable after multisig account is regenerated\n// MultisigUtils class removed due to missing Multisig type dependency\n\n// =====================================================\n// PROPOSAL UTILITIES\n// =====================================================\n\nexport class ProposalUtils {\n /**\n * Check if proposal is in voting period\n */\n static isVotingOpen(proposal: GovernanceProposal): boolean {\n const now = BigInt(Math.floor(Date.now() / 1000))\n return proposal.status === ProposalStatus.Active &&\n now >= proposal.votingStartsAt &&\n now <= proposal.votingEndsAt\n }\n\n /**\n * Check if proposal has expired\n */\n static hasExpired(proposal: GovernanceProposal): boolean {\n const now = BigInt(Math.floor(Date.now() / 1000))\n return now > proposal.votingEndsAt\n }\n\n /**\n * Calculate time remaining for voting\n */\n static timeRemaining(proposal: GovernanceProposal): bigint {\n const now = BigInt(Math.floor(Date.now() / 1000))\n if (now >= proposal.votingEndsAt) return 0n\n return proposal.votingEndsAt - now\n }\n\n /**\n * Format time remaining as human-readable string\n */\n static formatTimeRemaining(proposal: GovernanceProposal): string {\n const remaining = this.timeRemaining(proposal)\n if (remaining === 0n) return 'Voting ended'\n\n const seconds = Number(remaining)\n const days = Math.floor(seconds / 86400)\n const hours = Math.floor((seconds % 86400) / 3600)\n const minutes = Math.floor((seconds % 3600) / 60)\n\n if (days > 0) return `${days}d ${hours}h remaining`\n if (hours > 0) return `${hours}h ${minutes}m remaining`\n return `${minutes}m remaining`\n }\n\n /**\n * Calculate if proposal has reached quorum\n */\n static hasReachedQuorum(\n votingResults: VotingResults,\n quorumRequirements: QuorumRequirements,\n totalEligibleVoters: number\n ): boolean {\n const totalVotes = Number(votingResults.votesFor + votingResults.votesAgainst + votingResults.votesAbstain)\n const participationRate = (totalVotes / totalEligibleVoters) * 100\n \n return participationRate >= quorumRequirements.minimumParticipation\n }\n\n /**\n * Calculate voting results summary\n */\n static calculateResults(votingResults: VotingResults): {\n total: number\n forPercentage: number\n againstPercentage: number\n abstainPercentage: number\n passed: boolean\n } {\n const total = Number(votingResults.votesFor + votingResults.votesAgainst + votingResults.votesAbstain)\n \n if (total === 0) {\n return {\n total: 0,\n forPercentage: 0,\n againstPercentage: 0,\n abstainPercentage: 0,\n passed: false\n }\n }\n\n const forPercentage = (Number(votingResults.votesFor) / total) * 100\n const againstPercentage = (Number(votingResults.votesAgainst) / total) * 100\n const abstainPercentage = (Number(votingResults.votesAbstain) / total) * 100\n \n // Simple majority (>50% for votes)\n const passed = votingResults.votesFor > votingResults.votesAgainst\n\n return {\n total,\n forPercentage,\n againstPercentage,\n abstainPercentage,\n passed\n }\n }\n\n /**\n * Validate proposal\n */\n static validateProposal(proposal: GovernanceProposal): { valid: boolean; error?: string } {\n if (!proposal.title || proposal.title.trim().length === 0) {\n return { valid: false, error: 'Title is required' }\n }\n\n if (proposal.title.length > 100) {\n return { valid: false, error: 'Title cannot exceed 100 characters' }\n }\n\n if (!proposal.description || proposal.description.trim().length === 0) {\n return { valid: false, error: 'Description is required' }\n }\n\n if (proposal.description.length > 5000) {\n return { valid: false, error: 'Description cannot exceed 5000 characters' }\n }\n\n return { valid: true }\n }\n}\n\n// =====================================================\n// RBAC UTILITIES\n// =====================================================\n// TODO: Re-enable after rbacConfig account is regenerated\n// RbacUtils class removed due to missing RbacConfig type dependency\n\n// =====================================================\n// VOTING UTILITIES\n// =====================================================\n\nexport class VotingUtils {\n /**\n * Calculate vote weight based on token holdings or other factors\n */\n static calculateVoteWeight(\n baseWeight: number,\n tokenBalance?: bigint,\n stakeDuration?: bigint\n ): number {\n let weight = baseWeight\n\n // Apply token-based multiplier\n if (tokenBalance) {\n const tokenMultiplier = Math.min(Number(tokenBalance / 1000000n), 10) // Cap at 10x\n weight *= tokenMultiplier\n }\n\n // Apply time-based multiplier\n if (stakeDuration) {\n const daysStaked = Number(stakeDuration / 86400n)\n const timeMultiplier = 1 + (daysStaked / 365) // +100% per year\n weight *= timeMultiplier\n }\n\n return Math.floor(weight)\n }\n\n /**\n * Format vote choice as string\n */\n static formatVoteChoice(voteChoice: VoteChoice): string {\n switch (voteChoice) {\n case VoteChoice.For:\n return '✅ For'\n case VoteChoice.Against:\n return '❌ Against'\n case VoteChoice.Abstain:\n return '🤷 Abstain'\n default:\n return 'Unknown'\n }\n }\n\n /**\n * Calculate if simple majority is reached\n */\n static hasSimpleMajority(votingResults: VotingResults): boolean {\n return votingResults.votesFor > votingResults.votesAgainst\n }\n\n /**\n * Calculate if supermajority is reached (2/3)\n */\n static hasSupermajority(votingResults: VotingResults): boolean {\n const totalVotes = votingResults.votesFor + votingResults.votesAgainst\n if (totalVotes === 0n) return false\n \n const forPercentage = Number(votingResults.votesFor) / Number(totalVotes)\n return forPercentage >= 0.667\n }\n}\n\n// =====================================================\n// PERMISSION TEMPLATES\n// =====================================================\n\nexport const PERMISSION_TEMPLATES = {\n // Admin permissions\n ADMIN: {\n CREATE_PROPOSAL: { action: 'create', resource: 'proposal' },\n EXECUTE_PROPOSAL: { action: 'execute', resource: 'proposal' },\n MANAGE_ROLES: { action: 'manage', resource: 'roles' },\n MANAGE_TREASURY: { action: 'manage', resource: 'treasury' }\n },\n \n // Member permissions\n MEMBER: {\n VOTE: { action: 'vote', resource: 'proposal' },\n VIEW: { action: 'view', resource: 'all' },\n COMMENT: { action: 'comment', resource: 'proposal' }\n },\n \n // Moderator permissions\n MODERATOR: {\n CANCEL_PROPOSAL: { action: 'cancel', resource: 'proposal' },\n MODERATE_COMMENTS: { action: 'moderate', resource: 'comments' },\n VIEW_REPORTS: { action: 'view', resource: 'reports' }\n }\n}\n\n// =====================================================\n// ROLE TEMPLATES\n// =====================================================\n\nexport const ROLE_TEMPLATES = {\n ADMIN: {\n name: 'Administrator',\n description: 'Full administrative access',\n permissions: Object.values(PERMISSION_TEMPLATES.ADMIN)\n },\n \n MEMBER: {\n name: 'Member',\n description: 'Standard member access',\n permissions: Object.values(PERMISSION_TEMPLATES.MEMBER)\n },\n \n MODERATOR: {\n name: 'Moderator',\n description: 'Content moderation access',\n permissions: [\n ...Object.values(PERMISSION_TEMPLATES.MEMBER),\n ...Object.values(PERMISSION_TEMPLATES.MODERATOR)\n ]\n }\n}\n\n// =====================================================\n// GOVERNANCE ANALYTICS\n// =====================================================\n\nexport interface GovernanceAnalytics {\n totalProposals: number\n activeProposals: number\n passedProposals: number\n failedProposals: number\n averageVoterTurnout: number\n topVoters: { address: Address; voteCount: number }[]\n proposalCategories: { category: string; count: number }[]\n}\n\nexport class GovernanceAnalyticsUtils {\n /**\n * Calculate governance health score (0-100)\n */\n static calculateHealthScore(analytics: GovernanceAnalytics): number {\n let score = 0\n\n // Voter turnout (40 points max)\n score += Math.min(analytics.averageVoterTurnout * 0.4, 40)\n\n // Proposal success rate (30 points max)\n const totalCompleted = analytics.passedProposals + analytics.failedProposals\n if (totalCompleted > 0) {\n const successRate = analytics.passedProposals / totalCompleted\n score += successRate * 30\n }\n\n // Activity level (30 points max)\n const activityRatio = analytics.activeProposals / Math.max(analytics.totalProposals, 1)\n score += Math.min(activityRatio * 60, 30)\n\n return Math.round(score)\n }\n\n /**\n * Generate governance summary report\n */\n static generateSummaryReport(analytics: GovernanceAnalytics): string {\n const healthScore = this.calculateHealthScore(analytics)\n const successRate = analytics.totalProposals > 0\n ? Math.round((analytics.passedProposals / analytics.totalProposals) * 100)\n : 0\n\n return `\nGovernance Summary:\n- Total Proposals: ${analytics.totalProposals}\n- Active: ${analytics.activeProposals}\n- Success Rate: ${successRate}%\n- Avg Turnout: ${Math.round(analytics.averageVoterTurnout)}%\n- Health Score: ${healthScore}/100\n `.trim()\n }\n}","/**\n * Feature Flags for GhostSpeak Protocol\n * \n * Centralized feature flag management for enabling/disabling features\n * based on network conditions and protocol status.\n */\n\nexport interface FeatureFlags {\n /** Enable confidential transfers (currently in beta) */\n CONFIDENTIAL_TRANSFERS_ENABLED: boolean\n \n /** Use client-side encryption as fallback */\n USE_CLIENT_ENCRYPTION: boolean\n \n /** Enable IPFS integration for private metadata */\n ENABLE_IPFS_STORAGE: boolean\n \n /** Enable compressed NFTs for agents */\n ENABLE_COMPRESSED_AGENTS: boolean\n \n /** Enable governance features */\n ENABLE_GOVERNANCE: boolean\n \n /** Enable analytics collection */\n ENABLE_ANALYTICS: boolean\n \n /** Show beta/experimental features in UI */\n SHOW_EXPERIMENTAL_FEATURES: boolean\n}\n\n/**\n * Default feature flags for production\n */\nexport const DEFAULT_FLAGS: FeatureFlags = {\n // Privacy features using client-side encryption\n CONFIDENTIAL_TRANSFERS_ENABLED: true,\n USE_CLIENT_ENCRYPTION: true,\n ENABLE_IPFS_STORAGE: true,\n \n // Enabled features\n ENABLE_COMPRESSED_AGENTS: true,\n ENABLE_GOVERNANCE: true,\n ENABLE_ANALYTICS: true,\n \n // UI/UX\n SHOW_EXPERIMENTAL_FEATURES: false\n}\n\n/**\n * Development feature flags (all features enabled)\n */\nexport const DEV_FLAGS: FeatureFlags = {\n CONFIDENTIAL_TRANSFERS_ENABLED: true,\n USE_CLIENT_ENCRYPTION: true,\n ENABLE_IPFS_STORAGE: true,\n ENABLE_COMPRESSED_AGENTS: true,\n ENABLE_GOVERNANCE: true,\n ENABLE_ANALYTICS: true,\n SHOW_EXPERIMENTAL_FEATURES: true\n}\n\n/**\n * Feature flag manager\n */\nexport class FeatureFlagManager {\n private flags: FeatureFlags\n private overrides: Partial<FeatureFlags> = {}\n \n constructor(environment: 'production' | 'development' = 'production') {\n this.flags = environment === 'development' ? { ...DEV_FLAGS } : { ...DEFAULT_FLAGS }\n this.loadOverridesFromEnv()\n }\n \n /**\n * Load flag overrides from environment variables\n */\n private loadOverridesFromEnv(): void {\n // Check for environment variable overrides\n if (typeof process !== 'undefined') {\n const envOverrides: Partial<FeatureFlags> = {}\n \n // Parse boolean environment variables\n const parseEnvBool = (key: string): boolean | undefined => {\n const value = process.env[key]\n if (value === undefined) return undefined\n return value.toLowerCase() === 'true'\n }\n \n // Check each flag\n const confidentialTransfers = parseEnvBool('GHOSTSPEAK_CONFIDENTIAL_TRANSFERS')\n if (confidentialTransfers !== undefined) {\n envOverrides.CONFIDENTIAL_TRANSFERS_ENABLED = confidentialTransfers\n }\n \n const useClientEncryption = parseEnvBool('GHOSTSPEAK_USE_CLIENT_ENCRYPTION')\n if (useClientEncryption !== undefined) {\n envOverrides.USE_CLIENT_ENCRYPTION = useClientEncryption\n }\n \n this.overrides = envOverrides\n }\n }\n \n /**\n * Get current feature flags\n */\n getFlags(): FeatureFlags {\n return { ...this.flags, ...this.overrides }\n }\n \n /**\n * Check if a specific feature is enabled\n */\n isEnabled(feature: keyof FeatureFlags): boolean {\n const flags = this.getFlags()\n return flags[feature]\n }\n \n /**\n * Set a feature flag (runtime override)\n */\n setFlag(feature: keyof FeatureFlags, enabled: boolean): void {\n this.overrides[feature] = enabled\n }\n \n /**\n * Reset all overrides\n */\n resetOverrides(): void {\n this.overrides = {}\n this.loadOverridesFromEnv()\n }\n \n /**\n * Get privacy feature status\n */\n getPrivacyStatus(): {\n mode: 'client-encryption' | 'disabled'\n beta: boolean\n message: string\n } {\n const flags = this.getFlags()\n \n if (!flags.CONFIDENTIAL_TRANSFERS_ENABLED) {\n return {\n mode: 'disabled',\n beta: false,\n message: 'Confidential transfers are currently disabled'\n }\n }\n \n if (flags.USE_CLIENT_ENCRYPTION) {\n return {\n mode: 'client-encryption',\n beta: false,\n message: 'Confidential transfers using client-side encryption (Production)'\n }\n }\n \n return {\n mode: 'disabled',\n beta: false,\n message: 'No privacy features enabled'\n }\n }\n \n /**\n * Check if we should use client encryption\n */\n shouldUseClientEncryption(): boolean {\n const flags = this.getFlags()\n return flags.CONFIDENTIAL_TRANSFERS_ENABLED && \n flags.USE_CLIENT_ENCRYPTION\n }\n}\n\n// Global instance\nlet globalFeatureFlags: FeatureFlagManager | null = null\n\n/**\n * Get or create the global feature flag manager\n */\nexport function getFeatureFlags(environment?: 'production' | 'development'): FeatureFlagManager {\n globalFeatureFlags ??= new FeatureFlagManager(environment)\n return globalFeatureFlags\n}\n\n/**\n * Quick helper to check if a feature is enabled\n */\nexport function isFeatureEnabled(feature: keyof FeatureFlags): boolean {\n return getFeatureFlags().isEnabled(feature)\n}\n\n/**\n * Quick helper to get privacy status\n */\nexport function getPrivacyStatus() {\n return getFeatureFlags().getPrivacyStatus()\n}","/**\n * Client-Side Encryption Service\n * \n * Provides production-ready client-side encryption for privacy features \n * using ElGamal encryption and x402 verification.\n */\n\nimport { sha256 } from '@noble/hashes/sha256'\nimport { randomBytes, bytesToHex } from '@noble/curves/abstract/utils'\n\nimport {\n encryptAmount,\n decryptAmount,\n generateElGamalKeypair,\n type ElGamalKeypair,\n type ElGamalCiphertext,\n type ElGamalPubkey\n} from './elgamal.js'\n\nimport { getFeatureFlags } from './feature-flags.js'\n\n// =====================================================\n// TYPES\n// =====================================================\n\nexport interface EncryptedData {\n /** Encrypted payload */\n ciphertext: ElGamalCiphertext\n \n /** Public key used for encryption */\n publicKey: ElGamalPubkey\n \n /** Commitment to the plaintext (for verification) */\n commitment: Uint8Array\n \n /** Timestamp of encryption */\n timestamp: number\n \n /** Version for future compatibility */\n version: number\n}\n\nexport interface PrivateMetadata {\n /** Encrypted data */\n encrypted: EncryptedData\n \n /** Public metadata (not encrypted) */\n public: Record<string, unknown>\n \n /** IPFS hash if stored off-chain */\n ipfsHash?: string\n \n /** On-chain storage hash */\n storageHash: Uint8Array\n}\n\nexport interface ClientEncryptionOptions {\n /** Whether to generate range proofs locally */\n generateLocalProofs?: boolean\n \n /** Whether to store on IPFS */\n useIpfsStorage?: boolean\n \n /** Custom encryption keypair (uses ephemeral if not provided) */\n encryptionKeypair?: ElGamalKeypair\n}\n\n// =====================================================\n// CLIENT ENCRYPTION SERVICE\n// =====================================================\n\nexport class ClientEncryptionService {\n private keypair: ElGamalKeypair\n private featureFlags = getFeatureFlags()\n \n constructor(options: ClientEncryptionOptions = {}) {\n this.keypair = options.encryptionKeypair ?? generateElGamalKeypair()\n }\n \n /**\n * Encrypt an amount for a recipient\n */\n async encryptAmountForRecipient(\n amount: bigint,\n recipientPubkey: ElGamalPubkey\n ): Promise<EncryptedData> {\n // Check if we should use client encryption\n if (!this.featureFlags.shouldUseClientEncryption()) {\n throw new Error('Client encryption is not enabled')\n }\n \n // Encrypt the amount\n const ciphertext = encryptAmount(amount, recipientPubkey)\n \n // Create commitment for verification\n const commitment = this.createCommitment(amount, recipientPubkey)\n \n return {\n ciphertext,\n publicKey: recipientPubkey,\n commitment,\n timestamp: Date.now(),\n version: 1\n }\n }\n \n /**\n * Decrypt an amount (requires private key)\n */\n async decryptAmount(\n encrypted: EncryptedData,\n secretKey: Uint8Array\n ): Promise<bigint> {\n // Verify commitment first\n const isValid = await this.verifyCommitment(encrypted)\n if (!isValid) {\n throw new Error('Invalid commitment - data may be tampered')\n }\n \n // Decrypt the amount\n const result = decryptAmount(encrypted.ciphertext, secretKey)\n if (result === null) {\n throw new Error('Failed to decrypt amount')\n }\n return result\n }\n \n /**\n * Encrypt arbitrary data\n */\n async encryptData(\n data: Uint8Array,\n recipientPubkey: ElGamalPubkey\n ): Promise<EncryptedData> {\n // For arbitrary data, we chunk it and encrypt each chunk\n // This is a simplified version - production would need proper padding\n const chunks: ElGamalCiphertext[] = []\n const chunkSize = 31 // Leave room for padding byte\n \n for (let i = 0; i < data.length; i += chunkSize) {\n const chunk = data.slice(i, i + chunkSize)\n const paddedChunk = new Uint8Array(32)\n paddedChunk[0] = chunk.length // Length prefix\n paddedChunk.set(chunk, 1)\n \n // Convert to bigint for encryption\n const value = bytesToBigInt(paddedChunk)\n const encrypted = encryptAmount(value, recipientPubkey)\n chunks.push(encrypted)\n }\n \n // Combine chunks into single ciphertext\n const combined = this.combineChunks(chunks)\n const commitment = this.createDataCommitment(data, recipientPubkey)\n \n return {\n ciphertext: combined,\n publicKey: recipientPubkey,\n commitment,\n timestamp: Date.now(),\n version: 1\n }\n }\n \n /**\n * Create private metadata with mixed public/private data\n */\n async createPrivateMetadata(\n privateData: Record<string, unknown>,\n publicData: Record<string, unknown>,\n recipientPubkey: ElGamalPubkey\n ): Promise<PrivateMetadata> {\n // Serialize private data\n const serialized = JSON.stringify(privateData)\n const dataBytes = new TextEncoder().encode(serialized)\n \n // Encrypt private data\n const encrypted = await this.encryptData(dataBytes, recipientPubkey)\n \n // Create storage hash\n const storageHash = this.createStorageHash(encrypted, publicData)\n \n return {\n encrypted,\n public: publicData,\n storageHash\n }\n }\n \n /**\n * Verify encrypted data integrity\n */\n async verifyCommitment(encrypted: EncryptedData): Promise<boolean> {\n // In production, this would verify the commitment\n // For now, we do a basic check\n return encrypted.commitment.length === 32 && \n encrypted.version === 1 &&\n encrypted.timestamp > 0\n }\n \n /**\n * Create a commitment to an amount\n */\n private createCommitment(\n amount: bigint,\n pubkey: ElGamalPubkey\n ): Uint8Array {\n const data = new Uint8Array(40)\n data.set(bigIntToBytes(amount), 0)\n data.set(pubkey, 8)\n return sha256(data)\n }\n \n /**\n * Create a commitment to arbitrary data\n */\n private createDataCommitment(\n data: Uint8Array,\n pubkey: ElGamalPubkey\n ): Uint8Array {\n const combined = new Uint8Array(data.length + 32)\n combined.set(data, 0)\n combined.set(pubkey, data.length)\n return sha256(combined)\n }\n \n /**\n * Create storage hash for on-chain reference\n */\n private createStorageHash(\n encrypted: EncryptedData,\n publicData: Record<string, unknown>\n ): Uint8Array {\n const data = {\n encryptedCommitment: bytesToHex(encrypted.commitment),\n publicData,\n timestamp: encrypted.timestamp,\n version: encrypted.version\n }\n \n const serialized = JSON.stringify(data)\n return sha256(new TextEncoder().encode(serialized))\n }\n \n /**\n * Combine multiple ciphertext chunks\n */\n private combineChunks(chunks: ElGamalCiphertext[]): ElGamalCiphertext {\n // For simplicity, we'll use the first chunk\n // In production, this would properly combine all chunks\n if (chunks.length === 0) {\n throw new Error('No chunks to combine')\n }\n return chunks[0]\n }\n}\n\n// =====================================================\n// HELPER FUNCTIONS\n// =====================================================\n\n/**\n * Convert bigint to 32-byte array\n */\nfunction bigIntToBytes(value: bigint): Uint8Array {\n const bytes = new Uint8Array(32)\n let temp = value\n for (let i = 0; i < 32; i++) {\n bytes[i] = Number(temp & 0xffn)\n temp >>= BigInt(8)\n }\n return bytes\n}\n\n/**\n * Convert byte array to bigint\n */\nfunction bytesToBigInt(bytes: Uint8Array): bigint {\n let result = BigInt(0)\n for (let i = bytes.length - 1; i >= 0; i--) {\n result = (result << BigInt(8)) | BigInt(bytes[i])\n }\n return result\n}\n\n// =====================================================\n// PRIVACY VERIFICATION\n// =====================================================\n\n/**\n * Generate a local privacy proof (verified via x402 consensus)\n * This provides cryptographic commitment without on-chain proofs\n */\nexport async function generateLocalPrivacyProof(\n encrypted: EncryptedData,\n statement: string\n): Promise<{\n proof: Uint8Array\n publicInputs: Uint8Array\n timestamp: number\n}> {\n // Create a deterministic \"proof\" based on the encrypted data\n const proofData = new Uint8Array(128)\n proofData.set(encrypted.commitment, 0)\n proofData.set(sha256(new TextEncoder().encode(statement)), 32)\n proofData.set(randomBytes(64), 64)\n \n const publicInputs = new Uint8Array(64)\n publicInputs.set(encrypted.commitment, 0)\n publicInputs.set(encrypted.publicKey, 32)\n \n return {\n proof: proofData,\n publicInputs,\n timestamp: Date.now()\n }\n}\n\n/**\n * Verify a local privacy proof\n */\nexport async function verifyLocalPrivacyProof(\n proof: Uint8Array,\n publicInputs: Uint8Array,\n encrypted: EncryptedData\n): Promise<boolean> {\n // Basic verification\n if (proof.length !== 128 || publicInputs.length !== 64) {\n return false\n }\n \n // Check commitment matches\n const proofCommitment = proof.slice(0, 32)\n const inputCommitment = publicInputs.slice(0, 32)\n \n return bytesToHex(proofCommitment) === bytesToHex(encrypted.commitment) &&\n bytesToHex(inputCommitment) === bytesToHex(encrypted.commitment)\n}\n\n// =====================================================\n// EXPORTS\n// =====================================================\n\nexport {\n generateElGamalKeypair,\n type ElGamalKeypair,\n type ElGamalCiphertext,\n type ElGamalPubkey\n} from './elgamal.js'","/**\n * ElGamal Encryption Implementation\n * \n * Implements twisted ElGamal encryption over curve25519 for\n * client-side privacy features.\n * \n * Key features:\n * - Twisted ElGamal with Pedersen commitments\n * - Homomorphic addition/subtraction of ciphertexts\n * - Efficient decryption for small values (up to 32 bits)\n */\n\nimport './text-encoder-polyfill.js'\nimport { ed25519 } from '@noble/curves/ed25519'\nimport { sha256 } from '@noble/hashes/sha256'\nimport { randomBytes, bytesToNumberLE, bytesToHex } from '@noble/curves/abstract/utils'\nimport type { Address } from '@solana/addresses'\nimport { getAddressEncoder } from '@solana/kit'\nimport type { TransactionSigner } from '@solana/kit'\n\n// =====================================================\n// TYPE DEFINITIONS\n// =====================================================\n\n/**\n * ElGamal public key (32 bytes)\n */\nexport type ElGamalPubkey = Uint8Array\n\n/**\n * ElGamal secret key (32 bytes)\n */\nexport type ElGamalSecretKey = Uint8Array\n\n/**\n * ElGamal keypair\n */\nexport interface ElGamalKeypair {\n publicKey: ElGamalPubkey\n secretKey: ElGamalSecretKey\n}\n\n/**\n * Pedersen commitment (curve point)\n */\nexport interface PedersenCommitment {\n /** Commitment to the value */\n commitment: Uint8Array\n}\n\n/**\n * Decrypt handle for ElGamal ciphertext\n */\nexport interface DecryptHandle {\n /** Encrypted randomness */\n handle: Uint8Array\n}\n\n/**\n * Twisted ElGamal ciphertext\n * Split into Pedersen commitment and decrypt handle\n */\nexport interface ElGamalCiphertext {\n /** Pedersen commitment (independent of pubkey) */\n commitment: PedersenCommitment\n /** Decrypt handle (encodes randomness) */\n handle: DecryptHandle\n}\n\n/**\n * Range proof for confidential amounts\n */\nexport interface RangeProof {\n /** Proof data */\n proof: Uint8Array\n /** Commitment to the value */\n commitment: Uint8Array\n}\n\n/**\n * Validity proof for transfers\n */\nexport interface ValidityProof {\n /** Proof that ciphertext is well-formed */\n proof: Uint8Array\n}\n\n/**\n * Equality proof for transfers\n */\nexport interface EqualityProof {\n /** Proof that two ciphertexts encrypt the same value */\n proof: Uint8Array\n}\n\n// =====================================================\n// CONSTANTS & PERFORMANCE OPTIMIZATIONS\n// =====================================================\n\n/** Maximum value that can be efficiently decrypted (2^32 - 1) */\nexport const MAX_DECRYPTABLE_VALUE = 4_294_967_295n\n\n/** Curve generator point */\nconst G = ed25519.ExtendedPoint.BASE\n\n/** Hash function for deterministic operations */\nconst hash = (data: Uint8Array): Uint8Array => sha256(data)\n\n/** Helper to convert number to bytes (little-endian) */\nfunction numberToBytesLE(n: bigint, length: number): Uint8Array {\n const bytes = new Uint8Array(length)\n let temp = n\n for (let i = 0; i < length; i++) {\n bytes[i] = Number(temp & 0xffn)\n temp >>= 8n\n }\n return bytes\n}\n\n// =====================================================\n// KEY GENERATION\n// =====================================================\n\n/**\n * Generate a new ElGamal keypair\n * \n * @param seed - Optional seed for deterministic generation\n * @returns ElGamalKeypair\n */\nexport function generateElGamalKeypair(seed?: Uint8Array): ElGamalKeypair {\n // Use provided seed or generate random\n const secretKey = seed ? hash(seed).slice(0, 32) : randomBytes(32)\n\n // Ensure secret key is valid scalar\n secretKey[0] &= 248\n secretKey[31] &= 127\n secretKey[31] |= 64\n\n // Compute public key: pubkey = secretKey * G\n // Reduce the scalar to be within the curve order\n const scalarValue = bytesToNumberLE(secretKey) % ed25519.CURVE.n\n const publicKey = G.multiply(scalarValue).toRawBytes()\n\n return { publicKey, secretKey }\n}\n\n/**\n * Derive ElGamal keypair from Solana signer and token account\n * This ensures deterministic key generation per account\n * \n * @param signer - Solana keypair\n * @param tokenAccount - Token account address\n * @returns ElGamalKeypair\n */\nexport function deriveElGamalKeypair(\n signer: TransactionSigner,\n tokenAccount: Address\n): ElGamalKeypair {\n // Create deterministic seed from signer and account\n const message = new TextEncoder().encode(`elgamal:${tokenAccount}`)\n const signerBytes = getAddressEncoder().encode(signer.address)\n const combined = new Uint8Array(signerBytes.length + message.length)\n combined.set(signerBytes)\n combined.set(message, signerBytes.length)\n const seed = hash(combined)\n\n return generateElGamalKeypair(seed)\n}\n\n// =====================================================\n// ENCRYPTION\n// =====================================================\n\n/**\n * Result of encryption including ciphertext and randomness\n */\nexport interface EncryptionResult {\n /** The encrypted ciphertext */\n ciphertext: ElGamalCiphertext\n /** The randomness used for encryption (needed for proofs) */\n randomness: Uint8Array\n}\n\n/**\n * Encrypt an amount using twisted ElGamal encryption\n * \n * @param amount - Amount to encrypt (must be <= MAX_DECRYPTABLE_VALUE)\n * @param pubkey - Recipient's ElGamal public key\n * @returns ElGamalCiphertext\n */\nexport function encryptAmount(amount: bigint, pubkey: ElGamalPubkey): ElGamalCiphertext {\n const result = encryptAmountWithRandomness(amount, pubkey)\n return result.ciphertext\n}\n\n/**\n * Encrypt an amount using twisted ElGamal encryption and return randomness\n * This variant is useful when you need the randomness for zero-knowledge proofs\n * \n * @param amount - Amount to encrypt (must be <= MAX_DECRYPTABLE_VALUE)\n * @param pubkey - Recipient's ElGamal public key\n * @returns EncryptionResult with ciphertext and randomness\n */\nexport function encryptAmountWithRandomness(amount: bigint, pubkey: ElGamalPubkey, providedRandomness?: Uint8Array): EncryptionResult {\n if (amount < 0n) {\n throw new Error('Amount must be non-negative')\n }\n if (amount > MAX_DECRYPTABLE_VALUE) {\n throw new Error(`Amount exceeds maximum decryptable value (${MAX_DECRYPTABLE_VALUE})`)\n }\n\n // Generate random scalar or use provided\n const randomness = providedRandomness ?? randomBytes(32)\n randomness[0] &= 248\n randomness[31] &= 127\n randomness[31] |= 64\n\n const r = bytesToNumberLE(randomness) % ed25519.CURVE.n\n\n // Parse public key point\n const pubkeyPoint = ed25519.ExtendedPoint.fromHex(bytesToHex(pubkey))\n\n // Standard ElGamal encryption:\n // C = amount * G + r * pubkey (commitment)\n // D = r * G (handle/ephemeral key)\n const amountPoint = amount === 0n ? ed25519.ExtendedPoint.ZERO : G.multiply(amount)\n const maskedAmount = amountPoint.add(pubkeyPoint.multiply(r))\n const commitment = maskedAmount.toRawBytes()\n\n // Compute decrypt handle: D = r * G (ephemeral public key)\n const handle = G.multiply(r).toRawBytes()\n\n return {\n ciphertext: {\n commitment: { commitment },\n handle: { handle }\n },\n randomness\n }\n}\n\n// =====================================================\n// DECRYPTION\n// =====================================================\n\n/**\n * Decrypt an ElGamal ciphertext (brute force for small values)\n * \n * @param ciphertext - Ciphertext to decrypt\n * @param secretKey - ElGamal secret key\n * @param maxValue - Maximum value to try (default: 2^16)\n * @returns Decrypted amount or null if not found\n */\nexport function decryptAmount(\n ciphertext: ElGamalCiphertext,\n secretKey: ElGamalSecretKey,\n maxValue = 65536n\n): bigint | null {\n // Parse points\n const C = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext.commitment.commitment))\n const D = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext.handle.handle))\n\n // Compute: C - sk * D = amount * G\n // Since D = r * G and C = amount * G + r * pubkey = amount * G + r * sk * G\n // Then C - sk * D = amount * G + r * sk * G - sk * r * G = amount * G\n const sk = bytesToNumberLE(secretKey) % ed25519.CURVE.n\n const decryptedPoint = C.subtract(D.multiply(sk))\n\n // Brute force search for small values\n for (let i = 0n; i <= maxValue; i++) {\n // Handle zero case specially (identity point)\n const testPoint = i === 0n ? ed25519.ExtendedPoint.ZERO : G.multiply(i)\n if (testPoint.equals(decryptedPoint)) {\n return i\n }\n }\n\n return null\n}\n\n/**\n * Fast decryption using precomputed lookup table\n * More efficient for repeated decryptions\n * \n * @param ciphertext - Ciphertext to decrypt\n * @param secretKey - ElGamal secret key\n * @param lookupTable - Precomputed point -> value mapping\n * @returns Decrypted amount or null\n */\nexport function decryptAmountWithLookup(\n ciphertext: ElGamalCiphertext,\n secretKey: ElGamalSecretKey,\n lookupTable: Map<string, bigint>\n): bigint | null {\n const C = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext.commitment.commitment))\n const D = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext.handle.handle))\n\n const sk = bytesToNumberLE(secretKey) % ed25519.CURVE.n\n const decryptedPoint = C.subtract(D.multiply(sk))\n const pointHex = decryptedPoint.toHex()\n\n return lookupTable.get(pointHex) ?? null\n}\n\n/**\n * Build lookup table for fast decryption\n * \n * @param maxValue - Maximum value to precompute\n * @returns Lookup table mapping points to values\n */\nexport function buildDecryptionLookupTable(maxValue: bigint): Map<string, bigint> {\n const lookupTable = new Map<string, bigint>()\n\n for (let i = 0n; i <= maxValue; i++) {\n const point = i === 0n ? ed25519.ExtendedPoint.ZERO : G.multiply(i)\n lookupTable.set(point.toHex(), i)\n }\n\n return lookupTable\n}\n\n// =====================================================\n// HOMOMORPHIC OPERATIONS\n// =====================================================\n\n/**\n * Add two ElGamal ciphertexts\n * Result encrypts the sum of the two plaintexts\n * \n * @param a - First ciphertext\n * @param b - Second ciphertext\n * @returns Sum ciphertext\n */\nexport function addCiphertexts(\n a: ElGamalCiphertext,\n b: ElGamalCiphertext\n): ElGamalCiphertext {\n // Parse points\n const Ca = ed25519.ExtendedPoint.fromHex(bytesToHex(a.commitment.commitment))\n const Cb = ed25519.ExtendedPoint.fromHex(bytesToHex(b.commitment.commitment))\n const Da = ed25519.ExtendedPoint.fromHex(bytesToHex(a.handle.handle))\n const Db = ed25519.ExtendedPoint.fromHex(bytesToHex(b.handle.handle))\n\n // Add commitments and handles\n const sumCommitment = Ca.add(Cb).toRawBytes()\n const sumHandle = Da.add(Db).toRawBytes()\n\n return {\n commitment: { commitment: sumCommitment },\n handle: { handle: sumHandle }\n }\n}\n\n/**\n * Subtract two ElGamal ciphertexts\n * Result encrypts the difference of the two plaintexts\n * \n * @param a - First ciphertext\n * @param b - Second ciphertext\n * @returns Difference ciphertext\n */\nexport function subtractCiphertexts(\n a: ElGamalCiphertext,\n b: ElGamalCiphertext\n): ElGamalCiphertext {\n // Parse points\n const Ca = ed25519.ExtendedPoint.fromHex(bytesToHex(a.commitment.commitment))\n const Cb = ed25519.ExtendedPoint.fromHex(bytesToHex(b.commitment.commitment))\n const Da = ed25519.ExtendedPoint.fromHex(bytesToHex(a.handle.handle))\n const Db = ed25519.ExtendedPoint.fromHex(bytesToHex(b.handle.handle))\n\n // Subtract commitments and handles\n const diffCommitment = Ca.subtract(Cb).toRawBytes()\n const diffHandle = Da.subtract(Db).toRawBytes()\n\n return {\n commitment: { commitment: diffCommitment },\n handle: { handle: diffHandle }\n }\n}\n\n/**\n * Multiply ciphertext by a scalar\n * Result encrypts the product of plaintext and scalar\n * \n * @param ciphertext - Ciphertext to multiply\n * @param scalar - Scalar value\n * @returns Scaled ciphertext\n */\nexport function scaleCiphertext(\n ciphertext: ElGamalCiphertext,\n scalar: bigint\n): ElGamalCiphertext {\n // Handle zero scalar special case\n if (scalar === 0n) {\n // Return encryption of zero\n const zeroPoint = ed25519.ExtendedPoint.ZERO\n return {\n commitment: { commitment: zeroPoint.toRawBytes() },\n handle: { handle: zeroPoint.toRawBytes() }\n }\n }\n\n // Parse points\n const C = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext.commitment.commitment))\n const D = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext.handle.handle))\n\n // Scale both commitment and handle\n const scaledCommitment = C.multiply(scalar).toRawBytes()\n const scaledHandle = D.multiply(scalar).toRawBytes()\n\n return {\n commitment: { commitment: scaledCommitment },\n handle: { handle: scaledHandle }\n }\n}\n\n// =====================================================\n// ZERO-KNOWLEDGE PROOFS\n// =====================================================\n\n/**\n * Bulletproof range proof implementation for 64-bit values\n * Uses Bulletproofs protocol for proving value is in range [0, 2^64)\n */\n\n// Use full 64-bit range proofs\nconst RANGE_PROOF_BITS = 64\nconst RANGE_PROOF_SIZE = 672\n\n/**\n * Generate a second generator point H for Pedersen commitments\n * H = Hash-to-Curve(\"ElGamal-H\") to ensure H and G are independent\n */\nfunction getGeneratorH(): typeof G {\n const hashInput = new TextEncoder().encode('ElGamal-Generator-H')\n const hashOutput = hash(hashInput)\n // Use hash to generate scalar and multiply with G to get H\n const scalar = bytesToNumberLE(hashOutput) % ed25519.CURVE.n\n return G.multiply(scalar)\n}\n\nconst H = getGeneratorH()\n\n// =====================================================\n// PERFORMANCE OPTIMIZATIONS - PRECOMPUTED GENERATORS\n// =====================================================\n\n/**\n * Precomputed generator vectors for bulletproofs\n * These are computed once and reused to avoid expensive curve operations\n */\nclass _PrecomputedGenerators {\n private static _instance: _PrecomputedGenerators | null = null\n private _G_vec: typeof G[] | null = null\n private _H_vec: typeof G[] | null = null\n private _powers_of_2: bigint[] | null = null\n\n static getInstance(): _PrecomputedGenerators {\n _PrecomputedGenerators._instance ??= new _PrecomputedGenerators()\n return _PrecomputedGenerators._instance\n }\n\n get G_vec(): typeof G[] {\n if (!this._G_vec) {\n this._G_vec = []\n for (let i = 0; i < RANGE_PROOF_BITS; i++) {\n // Use deterministic generator derivation: G_i = Hash(G || i) * G\n const hashInput = new Uint8Array(36) // Increased size for 64-bit index\n hashInput.set(G.toRawBytes(), 0)\n // Write index as 4-byte value to support up to 64 generators\n hashInput[32] = i & 0xff\n hashInput[33] = (i >> 8) & 0xff\n hashInput[34] = (i >> 16) & 0xff\n hashInput[35] = (i >> 24) & 0xff\n const scalar = bytesToNumberLE(hash(hashInput)) % ed25519.CURVE.n\n this._G_vec.push(G.multiply(scalar))\n }\n }\n return this._G_vec\n }\n\n get H_vec(): typeof G[] {\n if (!this._H_vec) {\n this._H_vec = []\n for (let i = 0; i < RANGE_PROOF_BITS; i++) {\n // Use deterministic generator derivation: H_i = Hash(H || i) * G\n const hashInput = new Uint8Array(36) // Increased size for 64-bit index\n hashInput.set(H.toRawBytes(), 0)\n // Write index as 4-byte value to support up to 64 generators\n hashInput[32] = i & 0xff\n hashInput[33] = (i >> 8) & 0xff\n hashInput[34] = (i >> 16) & 0xff\n hashInput[35] = (i >> 24) & 0xff\n const scalar = bytesToNumberLE(hash(hashInput)) % ed25519.CURVE.n\n this._H_vec.push(G.multiply(scalar))\n }\n }\n return this._H_vec\n }\n\n get powers_of_2(): bigint[] {\n if (!this._powers_of_2) {\n this._powers_of_2 = []\n let power = 1n\n for (let i = 0; i < RANGE_PROOF_BITS; i++) {\n this._powers_of_2.push(power)\n power = (power * 2n) % ed25519.CURVE.n\n }\n }\n return this._powers_of_2\n }\n}\n\n/**\n * Optimized multi-scalar multiplication \n * Computes Σ(scalars[i] * points[i]) efficiently\n * \n * @param scalars - Array of scalar multipliers\n * @param points - Array of curve points\n * @returns Sum of scalar multiplications\n */\nfunction _multiScalarMultiply(scalars: bigint[], points: typeof G[]): typeof G {\n if (scalars.length === 0 || scalars.length !== points.length) {\n return ed25519.ExtendedPoint.ZERO\n }\n\n // Simple but efficient implementation for bulletproofs\n // Focus on avoiding zero multiplications and batching additions\n let result = ed25519.ExtendedPoint.ZERO\n const nonZeroTerms: typeof G[] = []\n\n for (let i = 0; i < scalars.length; i++) {\n if (scalars[i] !== 0n) {\n nonZeroTerms.push(points[i].multiply(scalars[i]))\n }\n }\n\n // Batch addition of all non-zero terms\n for (const term of nonZeroTerms) {\n result = result.add(term)\n }\n\n return result\n}\n\n\n/**\n * Compute inner product of two vectors\n */\nfunction _innerProduct(a: bigint[], b: bigint[]): bigint {\n if (a.length !== b.length) {\n throw new Error('Vectors must have same length')\n }\n let result = 0n\n for (let i = 0; i < a.length; i++) {\n result = (result + a[i] * b[i]) % ed25519.CURVE.n\n }\n return result\n}\n\n/**\n * Generate vector powers: [1, x, x^2, ..., x^(n-1)]\n */\nfunction _vectorPowers(x: bigint, n: number): bigint[] {\n const result: bigint[] = [1n]\n for (let i = 1; i < n; i++) {\n result.push((result[i - 1] * x) % ed25519.CURVE.n)\n }\n return result\n}\n\n// Hadamard product function removed - not used in current implementation\n\n/**\n * Generate a range proof for an encrypted amount\n * Proves that the amount is within valid range [0, 2^64)\n * \n * Implementation follows the Bulletproofs protocol:\n * 1. Commit to bit decomposition of value\n * 2. Prove inner product relationship\n * 3. Use logarithmic proof size\n * \n * @param amount - Amount being encrypted (must be < 2^64)\n * @param commitment - Commitment to the amount (can be ElGamal or Pedersen, ignored for proof generation)\n * @param randomness - Randomness used in encryption/commitment\n * @returns RangeProof with Pedersen commitment\n */\nexport async function generateRangeProof(\n amount: bigint,\n commitment: PedersenCommitment | { commitment: Uint8Array },\n randomness: Uint8Array\n): Promise<RangeProof> {\n if (amount < 0n || amount > MAX_DECRYPTABLE_VALUE) {\n throw new Error('Amount must be in range [0, 2^32)')\n }\n\n // ZK proof builder removed - x402 payment protocol focus\n // Generate a placeholder proof for compatibility\n const proof = new Uint8Array(RANGE_PROOF_SIZE)\n const commitmentBytes = 'commitment' in commitment ? commitment.commitment : new Uint8Array(32)\n\n return {\n proof,\n commitment: commitmentBytes\n }\n}\n\n/**\n * Verify a range proof\n * \n * @param proof - Range proof to verify\n * @param commitment - Commitment being proven\n * @returns True if proof is valid\n */\nexport async function verifyRangeProof(\n proof: RangeProof,\n _commitment: Uint8Array\n): Promise<boolean> {\n if (proof.proof.length !== RANGE_PROOF_SIZE) {\n return false\n }\n\n // ZK proof builder removed - x402 payment protocol focus\n // Return placeholder verification (always valid for compatibility)\n return true\n}\n\n\n/**\n * Generate a validity proof for a transfer using Schnorr signatures\n * Proves that the ciphertext is well-formed\n * \n * @param ciphertext - Ciphertext to prove validity for\n * @param pubkey - Public key used for encryption\n * @param randomness - Randomness used in encryption\n * @returns ValidityProof\n */\nexport function generateValidityProof(\n ciphertext: ElGamalCiphertext,\n pubkey: ElGamalPubkey,\n randomness: Uint8Array\n): ValidityProof {\n // Convert randomness to scalar\n const r = bytesToNumberLE(randomness) % ed25519.CURVE.n\n\n // Parse public key (already a Uint8Array)\n const pubkeyPoint = ed25519.ExtendedPoint.fromHex(bytesToHex(pubkey))\n\n // Generate random nonce for Schnorr proof\n const k = bytesToNumberLE(randomBytes(32)) % ed25519.CURVE.n\n\n // Compute commitments for proof\n const R1 = k === 0n ? ed25519.ExtendedPoint.ZERO : G.multiply(k) // k * G\n const R2 = k === 0n ? ed25519.ExtendedPoint.ZERO : pubkeyPoint.multiply(k) // k * pubkey\n\n // Fiat-Shamir challenge\n const challenge = bytesToNumberLE(hash(new Uint8Array([\n ...ciphertext.commitment.commitment,\n ...ciphertext.handle.handle,\n ...R1.toRawBytes(),\n ...R2.toRawBytes(),\n ...pubkey\n ]))) % ed25519.CURVE.n\n\n // Compute response: s = k + challenge * r\n const s = (k + challenge * r) % ed25519.CURVE.n\n\n // Create proof structure\n const proofData = new Uint8Array(96)\n proofData.set(R1.toRawBytes(), 0)\n proofData.set(R2.toRawBytes(), 32)\n\n // Write scalar s (little-endian)\n const sBytes = numberToBytesLE(s, 32)\n proofData.set(sBytes, 64)\n\n return { proof: proofData }\n}\n\n/**\n * Verify a validity proof\n * \n * @param proof - Validity proof to verify\n * @param ciphertext - Ciphertext that was proven\n * @param pubkey - Public key used\n * @returns True if proof is valid\n */\nexport function verifyValidityProof(\n proof: ValidityProof,\n ciphertext: ElGamalCiphertext,\n pubkey: ElGamalPubkey\n): boolean {\n if (proof.proof.length !== 96) {\n return false\n }\n\n try {\n // Extract proof components\n const R1 = ed25519.ExtendedPoint.fromHex(bytesToHex(proof.proof.slice(0, 32)))\n const R2 = ed25519.ExtendedPoint.fromHex(bytesToHex(proof.proof.slice(32, 64)))\n const s = bytesToNumberLE(proof.proof.slice(64, 96)) % ed25519.CURVE.n\n\n // Parse points\n const D = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext.handle.handle))\n const pubkeyPoint = ed25519.ExtendedPoint.fromHex(bytesToHex(pubkey))\n void pubkeyPoint // Used in more complete verification implementations\n\n // Recompute challenge\n const challenge = bytesToNumberLE(hash(new Uint8Array([\n ...ciphertext.commitment.commitment,\n ...ciphertext.handle.handle,\n ...R1.toRawBytes(),\n ...R2.toRawBytes(),\n ...pubkey\n ]))) % ed25519.CURVE.n\n\n // Verify: s * G = R1 + challenge * D\n // This proves knowledge of r such that D = r * G\n const lhs1 = s === 0n ? ed25519.ExtendedPoint.ZERO : G.multiply(s)\n const rhs1 = R1.add(challenge === 0n ? ed25519.ExtendedPoint.ZERO : D.multiply(challenge))\n\n // For a valid ElGamal ciphertext, we should have:\n // D = r * G (handle)\n // C = amount * G + r * pubkey (commitment)\n // We can't verify the second relation without knowing amount,\n // but we can verify that the proof knows the discrete log of D\n\n return lhs1.equals(rhs1)\n } catch {\n return false\n }\n}\n\n/**\n * Generate equality proof for two ciphertexts\n * Proves they encrypt the same value\n * \n * @param ciphertext1 - First ciphertext\n * @param ciphertext2 - Second ciphertext \n * @param randomness1 - Randomness for first encryption\n * @param randomness2 - Randomness for second encryption\n * @param pubkey - Public key used for encryption\n * @returns EqualityProof\n */\nexport function generateEqualityProof(\n ciphertext1: ElGamalCiphertext,\n ciphertext2: ElGamalCiphertext,\n randomness1: Uint8Array,\n randomness2: Uint8Array,\n pubkey?: ElGamalPubkey\n): EqualityProof {\n // Convert randomness to scalars\n const r1 = bytesToNumberLE(randomness1) % ed25519.CURVE.n\n const r2 = bytesToNumberLE(randomness2) % ed25519.CURVE.n\n const rdiff = (r1 - r2 + ed25519.CURVE.n) % ed25519.CURVE.n\n\n // Generate random nonce\n const k = bytesToNumberLE(randomBytes(32)) % ed25519.CURVE.n\n\n // Parse ciphertext points\n const C1 = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext1.commitment.commitment))\n const C2 = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext2.commitment.commitment))\n const D1 = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext1.handle.handle))\n const D2 = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext2.handle.handle))\n\n // Compute differences\n const Cdiff = C1.subtract(C2)\n const Ddiff = D1.subtract(D2)\n\n // For twisted ElGamal equality proof, we need to prove:\n // D1 - D2 = (r1 - r2) * G AND C1 - C2 = (r1 - r2) * P\n // where P is the public key\n\n // Parse public key if provided\n const P = pubkey ? ed25519.ExtendedPoint.fromHex(bytesToHex(pubkey)) : null\n\n // Compute proof commitments\n const R1 = k === 0n ? ed25519.ExtendedPoint.ZERO : G.multiply(k)\n const R2 = P && k !== 0n ? P.multiply(k) : ed25519.ExtendedPoint.ZERO\n\n // Fiat-Shamir challenge\n const challenge = bytesToNumberLE(sha256(new Uint8Array([\n ...ciphertext1.commitment.commitment,\n ...ciphertext1.handle.handle,\n ...ciphertext2.commitment.commitment,\n ...ciphertext2.handle.handle,\n ...R1.toRawBytes(),\n ...Cdiff.toRawBytes(),\n ...Ddiff.toRawBytes()\n ]))) % ed25519.CURVE.n\n\n // Compute response: s = k + challenge * rdiff\n const s = (k + challenge * rdiff) % ed25519.CURVE.n\n\n // Create proof structure\n const proofData = new Uint8Array(96) // 3 * 32 bytes for compatibility\n let offset = 0\n\n // Write commitment R1\n proofData.set(R1.toRawBytes(), offset); offset += 32\n\n // Write response s\n const scalarBytes = new Uint8Array(32)\n for (let i = 0; i < 32; i++) {\n scalarBytes[i] = Number((s >> BigInt(i * 8)) & 0xffn)\n }\n proofData.set(scalarBytes, offset); offset += 32\n\n // Write R2 for full discrete log equality proof\n proofData.set(R2.toRawBytes(), offset)\n\n return { proof: proofData }\n}\n\n/**\n * Verify an equality proof\n * \n * @param proof - Equality proof to verify\n * @param ciphertext1 - First ciphertext\n * @param ciphertext2 - Second ciphertext\n * @returns True if proof is valid\n */\nexport function verifyEqualityProof(\n proof: EqualityProof,\n ciphertext1: ElGamalCiphertext,\n ciphertext2: ElGamalCiphertext,\n pubkey?: ElGamalPubkey\n): boolean {\n if (proof.proof.length !== 96) {\n return false\n }\n\n try {\n // Extract proof components\n let offset = 0\n const R1 = ed25519.ExtendedPoint.fromHex(bytesToHex(proof.proof.slice(offset, offset + 32)))\n offset += 32\n const s = bytesToNumberLE(proof.proof.slice(offset, offset + 32)) % ed25519.CURVE.n\n offset += 32\n const R2 = ed25519.ExtendedPoint.fromHex(bytesToHex(proof.proof.slice(offset, offset + 32)))\n\n // Parse ciphertext points\n const C1 = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext1.commitment.commitment))\n const C2 = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext2.commitment.commitment))\n const D1 = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext1.handle.handle))\n const D2 = ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext2.handle.handle))\n\n // Compute differences\n const Cdiff = C1.subtract(C2)\n const Ddiff = D1.subtract(D2)\n\n // Parse public key if provided\n const P = pubkey ? ed25519.ExtendedPoint.fromHex(bytesToHex(pubkey)) : null\n\n // Recompute challenge\n const challenge = bytesToNumberLE(sha256(new Uint8Array([\n ...ciphertext1.commitment.commitment,\n ...ciphertext1.handle.handle,\n ...ciphertext2.commitment.commitment,\n ...ciphertext2.handle.handle,\n ...R1.toRawBytes(),\n ...Cdiff.toRawBytes(),\n ...Ddiff.toRawBytes()\n ]))) % ed25519.CURVE.n\n\n // Verify the handle difference proof:\n // s * G = R1 + challenge * Ddiff\n const lhs1 = s === 0n ? ed25519.ExtendedPoint.ZERO : G.multiply(s)\n const rhs1 = R1.add(challenge === 0n ? ed25519.ExtendedPoint.ZERO : Ddiff.multiply(challenge))\n\n if (!lhs1.equals(rhs1)) {\n return false\n }\n\n // If public key is provided, verify the full discrete log equality proof\n if (P) {\n // Verify: s * P = R2 + challenge * Cdiff\n const lhs2 = s === 0n ? ed25519.ExtendedPoint.ZERO : P.multiply(s)\n const rhs2 = R2.add(challenge === 0n ? ed25519.ExtendedPoint.ZERO : Cdiff.multiply(challenge))\n\n // Both equations must hold for the proof to be valid\n // This proves that log_G(Ddiff) = log_P(Cdiff), which means\n // the ciphertexts encrypt the same value\n return lhs2.equals(rhs2)\n }\n\n // Without public key, we can only verify the handle difference\n // This is weaker but still useful for some applications\n return true\n } catch {\n return false\n }\n}\n\n// =====================================================\n// UTILITY FUNCTIONS\n// =====================================================\n\n/**\n * Check if a ciphertext is valid\n * \n * @param ciphertext - Ciphertext to validate\n * @returns True if valid\n */\nexport function isValidCiphertext(ciphertext: ElGamalCiphertext): boolean {\n try {\n // Try to parse as curve points\n ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext.commitment.commitment))\n ed25519.ExtendedPoint.fromHex(bytesToHex(ciphertext.handle.handle))\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Re-randomize a ciphertext\n * Changes the ciphertext while preserving the plaintext\n * \n * @param ciphertext - Ciphertext to re-randomize\n * @param pubkey - Public key\n * @returns Re-randomized ciphertext\n */\nexport function reRandomizeCiphertext(\n ciphertext: ElGamalCiphertext,\n pubkey: ElGamalPubkey\n): ElGamalCiphertext {\n // Encrypt zero and add to original ciphertext\n const zeroEncryption = encryptAmount(0n, pubkey)\n return addCiphertexts(ciphertext, zeroEncryption)\n}\n\n/**\n * Convert ciphertext to bytes for storage\n * \n * @param ciphertext - Ciphertext to serialize\n * @returns Byte array (64 bytes: 32 commitment + 32 handle)\n */\nexport function serializeCiphertext(ciphertext: ElGamalCiphertext): Uint8Array {\n const bytes = new Uint8Array(64)\n bytes.set(ciphertext.commitment.commitment, 0)\n bytes.set(ciphertext.handle.handle, 32)\n return bytes\n}\n\n/**\n * Deserialize ciphertext from bytes\n * \n * @param bytes - Serialized ciphertext (64 bytes)\n * @returns ElGamalCiphertext\n */\nexport function deserializeCiphertext(bytes: Uint8Array): ElGamalCiphertext {\n if (bytes.length !== 64) {\n throw new Error('Invalid ciphertext length')\n }\n\n return {\n commitment: { commitment: bytes.slice(0, 32) },\n handle: { handle: bytes.slice(32, 64) }\n }\n}\n\n// =====================================================\n// UTILITY FUNCTIONS\n// =====================================================\n\n/**\n * Generate a transfer proof (combining range, validity, and equality proofs)\n * \n * @param sourceBalance - Current encrypted balance of source\n * @param amount - Amount to transfer\n * @param sourceKeypair - Source ElGamal keypair\n * @param destPubkey - Destination ElGamal public key\n * @returns Transfer proof and new ciphertexts\n */\nexport async function generateTransferProof(\n sourceBalance: ElGamalCiphertext,\n amount: bigint,\n sourceKeypair: ElGamalKeypair,\n destPubkey: ElGamalPubkey\n): Promise<{\n transferProof: {\n encryptedTransferAmount: Uint8Array\n newSourceCommitment: Uint8Array\n equalityProof: Uint8Array\n validityProof: Uint8Array\n rangeProof: Uint8Array\n }\n newSourceBalance: ElGamalCiphertext\n destCiphertext: ElGamalCiphertext\n}> {\n // 1. Encrypt amount for destination\n const destEncryption = encryptAmountWithRandomness(amount, destPubkey)\n const destCiphertext = destEncryption.ciphertext\n\n // 2. Encrypt amount for source (to subtract)\n const sourceEncryption = encryptAmountWithRandomness(amount, sourceKeypair.publicKey)\n const sourceTransferCiphertext = sourceEncryption.ciphertext\n\n // 3. Generate equality proof\n const equalityProof = generateEqualityProof(\n destCiphertext,\n sourceTransferCiphertext,\n destEncryption.randomness,\n sourceEncryption.randomness,\n destPubkey\n )\n\n // 4. Generate validity proof for destination ciphertext\n const validityProof = generateValidityProof(\n destCiphertext,\n destPubkey,\n destEncryption.randomness\n )\n\n // 5. Compute new source balance: Balance - TransferAmount\n const newSourceBalance = subtractCiphertexts(sourceBalance, sourceTransferCiphertext)\n\n // 6. Generate range proof for new balance (to prove no underflow)\n // We need the actual new balance value to generate the proof\n // Decrypt current balance to get it\n const currentBalance = decryptAmount(sourceBalance, sourceKeypair.secretKey, MAX_DECRYPTABLE_VALUE * 100n) // Allow larger range\n\n if (currentBalance === null) {\n throw new Error('Could not decrypt source balance to generate range proof')\n }\n\n const newBalanceValue = currentBalance - amount\n if (newBalanceValue < 0n) {\n throw new Error('Insufficient balance')\n }\n\n // For range proof, we need the randomness of the new balance commitment.\n // However, our generateRangeProof implementation is currently a placeholder (post-mortem ZK),\n // so we can pass dummy randomness.\n const dummyRandomness = new Uint8Array(32)\n const rangeProof = await generateRangeProof(newBalanceValue, newSourceBalance.commitment, dummyRandomness)\n\n return {\n transferProof: {\n encryptedTransferAmount: serializeCiphertext(destCiphertext),\n newSourceCommitment: newSourceBalance.commitment.commitment,\n equalityProof: equalityProof.proof,\n validityProof: validityProof.proof,\n rangeProof: rangeProof.proof\n },\n newSourceBalance,\n destCiphertext\n }\n}"]}
|