/** * Integration Test for Multi-Platform Signing * * Tests end-to-end signing functionality across all supported platforms. * Validates the complete integration between credential manager, signers, and account pools. */ import { CredentialManager } from '@/core/credential-manager/CredentialManager' import { Platform } from '@/types/credential' import { TradingOperation } from '@/core/credential-manager/TradingIntegration' describe('Multi-Platform Signing Integration Test', () => { let credentialManager: CredentialManager beforeEach(async () => { const config = { accounts: [ { id: 'pacifica-main', name: 'Pacifica Main Account', platform: Platform.PACIFICA, enabled: true, credentials: { type: 'ed25519' as const, privateKey: 'f26670e2ca334117f8859f9f32e50251641953a30b54f6ffcf82db836cfdfea5' } }, { id: 'aster-main', name: 'Aster Main Account', platform: Platform.ASTER, enabled: true, credentials: { type: 'secp256k1' as const, privateKey: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' } }, { id: 'binance-main', name: 'Binance Main Account', platform: Platform.BINANCE, enabled: true, credentials: { type: 'hmac' as const, apiKey: 'test-api-key', secretKey: 'test-secret-key' } } ], hedging: { platforms: { [Platform.PACIFICA]: { enabled: true, primaryAccounts: ['pacifica-main'], backupAccounts: [], loadBalanceStrategy: 'round-robin', healthCheckInterval: 30000, failoverThreshold: 3 }, [Platform.ASTER]: { enabled: true, primaryAccounts: ['aster-main'], backupAccounts: [], loadBalanceStrategy: 'round-robin', healthCheckInterval: 30000, failoverThreshold: 3 }, [Platform.BINANCE]: { enabled: true, primaryAccounts: ['binance-main'], backupAccounts: [], loadBalanceStrategy: 'round-robin', healthCheckInterval: 30000, failoverThreshold: 3 } }, hedging: { enableCrossplatformBalancing: true, maxAccountsPerPlatform: 5, reservationTimeoutMs: 60000 } } } credentialManager = new CredentialManager() await credentialManager.loadConfiguration(config) }) afterEach(async () => { await credentialManager.shutdown() }) describe('Basic Signing Operations', () => { test('should sign messages for Pacifica platform', async () => { const message = new TextEncoder().encode('test message for pacifica') const result = await credentialManager.sign('pacifica-main', message) expect(result.success).toBe(true) expect(result.signature).toBeDefined() expect(result.algorithm).toBe('ed25519') expect(result.metadata?.platform).toBe(Platform.PACIFICA) }) test('should sign messages for Aster platform', async () => { const message = new TextEncoder().encode('test message for aster') const result = await credentialManager.sign('aster-main', message) expect(result.success).toBe(true) expect(result.signature).toBeDefined() expect(result.algorithm).toBe('eip191') expect(result.metadata?.platform).toBe(Platform.ASTER) }) test('should sign messages for Binance platform', async () => { const message = new TextEncoder().encode('test message for binance') const result = await credentialManager.sign('binance-main', message) expect(result.success).toBe(true) expect(result.signature).toBeDefined() expect(result.algorithm).toBe('hmac-sha256') expect(result.metadata?.platform).toBe(Platform.BINANCE) }) test('should handle signing failures gracefully', async () => { const message = new TextEncoder().encode('test message') const result = await credentialManager.sign('non-existent-account', message) expect(result.success).toBe(false) expect(result.error).toBeDefined() expect(result.error).toContain('Account not found') }) }) describe('Performance Requirements', () => { test('should complete signing within 50ms for all platforms', async () => { const message = new TextEncoder().encode('performance test message') const platforms = [ { accountId: 'pacifica-main', platform: Platform.PACIFICA }, { accountId: 'aster-main', platform: Platform.ASTER }, { accountId: 'binance-main', platform: Platform.BINANCE } ] for (const { accountId, platform } of platforms) { const startTime = Date.now() const result = await credentialManager.sign(accountId, message) const duration = Date.now() - startTime expect(result.success).toBe(true) expect(duration).toBeLessThan(50) // Performance requirement expect(result.metadata?.duration).toBeLessThan(50) } }) test('should handle concurrent signing operations', async () => { const message = new TextEncoder().encode('concurrent test message') const startTime = Date.now() const promises = [ credentialManager.sign('pacifica-main', message), credentialManager.sign('aster-main', message), credentialManager.sign('binance-main', message), credentialManager.sign('pacifica-main', message), credentialManager.sign('aster-main', message) ] const results = await Promise.all(promises) const duration = Date.now() - startTime expect(results).toHaveLength(5) expect(results.every(r => r.success)).toBe(true) expect(duration).toBeLessThan(100) // All 5 operations within 100ms }) }) describe('Trading Integration', () => { test('should sign trading requests for different platforms', async () => { const tradingRequests = [ { operation: TradingOperation.PLACE_ORDER, platform: Platform.PACIFICA, parameters: { symbol: 'SOL/USDC', side: 'buy' as const, type: 'limit' as const, quantity: 1.0, price: 100.0 } }, { operation: TradingOperation.GET_BALANCE, platform: Platform.ASTER, parameters: {} }, { operation: TradingOperation.CANCEL_ORDER, platform: Platform.BINANCE, parameters: { symbol: 'BTCUSDT', orderId: '12345' } } ] for (const request of tradingRequests) { const result = await credentialManager.signTradingRequest(request) expect(result.success).toBe(true) expect(result.selectedAccount).toBeDefined() expect(result.selectedAccount.platform).toBe(request.platform) expect(result.operation).toBe(request.operation) expect(result.platformSignature).toBeDefined() } }) test('should handle batch trading requests', async () => { const batchRequests = [ { operation: TradingOperation.PLACE_ORDER, platform: Platform.PACIFICA, parameters: { symbol: 'SOL/USDC', side: 'buy' as const, quantity: 1.0 } }, { operation: TradingOperation.PLACE_ORDER, platform: Platform.ASTER, parameters: { symbol: 'ETH/USDC', side: 'sell' as const, quantity: 0.5 } }, { operation: TradingOperation.GET_BALANCE, platform: Platform.BINANCE, parameters: {} } ] const results = await credentialManager.signBatchTradingRequests(batchRequests) expect(results).toHaveLength(3) expect(results.every(r => r.success)).toBe(true) const platforms = results.map(r => r.selectedAccount.platform) expect(platforms).toContain(Platform.PACIFICA) expect(platforms).toContain(Platform.ASTER) expect(platforms).toContain(Platform.BINANCE) }) }) describe('Account Pool Integration', () => { test('should select accounts from hedging pool for trading', async () => { const accounts = await credentialManager.getAvailableAccountsForTrading({ minBalance: 1000, riskTolerance: 'medium' }) expect(accounts.length).toBeGreaterThan(0) const platforms = new Set(accounts.map(a => a.platform)) expect(platforms.size).toBeGreaterThan(1) // Multiple platforms available }) test('should handle account health monitoring', async () => { const accountIds = ['pacifica-main', 'aster-main', 'binance-main'] const healthStatuses = await credentialManager.checkAccountHealth(accountIds) expect(healthStatuses.size).toBe(3) for (const [accountId, status] of healthStatuses) { expect(accountIds).toContain(accountId) expect(status.accountId).toBe(accountId) expect(status.isHealthy).toBe(true) // Fresh accounts should be healthy expect(status.healthScore).toBeGreaterThan(0) } }) test('should handle account reservation for trading', async () => { const accountIds = ['pacifica-main', 'aster-main'] const reservation = await credentialManager.reserveAccountsForTrading(accountIds, 30000) expect(reservation.success).toBe(true) expect(reservation.reservedAccounts).toEqual(expect.arrayContaining(accountIds)) // Reserved accounts should not be selected for other operations const availableAccounts = await credentialManager.getAvailableAccountsForTrading({}) const availableIds = availableAccounts.map(a => a.accountId) // Should have fewer available accounts (reserved ones excluded) expect(availableIds).not.toContain('pacifica-main') expect(availableIds).not.toContain('aster-main') // Release reservations const release = await credentialManager.releaseReservedAccounts(accountIds) expect(release.success).toBe(true) }) }) describe('Cross-Platform Hedging', () => { test('should distribute hedging across multiple platforms', async () => { const platforms = [Platform.PACIFICA, Platform.ASTER, Platform.BINANCE] const totalVolume = 30000 const distribution = await credentialManager.getHedgingAccountDistribution( totalVolume, platforms ) expect(distribution.size).toBe(3) // All platforms should have accounts for (const [platform, accounts] of distribution) { expect(platforms).toContain(platform) expect(accounts.length).toBeGreaterThan(0) expect(accounts.every(a => a.platform === platform)).toBe(true) } }) test('should handle cross-platform account selection', async () => { const platforms = [Platform.PACIFICA, Platform.ASTER] const accountCount = 2 const accounts = await credentialManager.selectAccountsAcrossPlatforms( platforms, accountCount ) expect(accounts.length).toBeLessThanOrEqual(accountCount) const selectedPlatforms = new Set(accounts.map(a => a.platform)) expect(selectedPlatforms.size).toBeGreaterThan(1) // Multiple platforms selected }) }) describe('Error Recovery and Failover', () => { test('should handle account failures and recover', async () => { const message = new TextEncoder().encode('test message') // Simulate account failure credentialManager.updateAccountAfterTrade('pacifica-main', { success: false, error: 'Simulated failure', timestamp: new Date() }) // Account should still be usable (not immediately disabled) const result = await credentialManager.sign('pacifica-main', message) expect(result.success).toBe(true) // Record success to recover credentialManager.updateAccountAfterTrade('pacifica-main', { success: true, tradeId: 'recovery-test', timestamp: new Date() }) const healthCheck = await credentialManager.checkAccountHealth(['pacifica-main']) const health = healthCheck.get('pacifica-main') expect(health?.isHealthy).toBe(true) }) test('should disable accounts after repeated failures', async () => { // Simulate multiple failures for (let i = 0; i < 5; i++) { credentialManager.updateAccountAfterTrade('pacifica-main', { success: false, error: `Failure ${i + 1}`, timestamp: new Date() }) } const healthCheck = await credentialManager.checkAccountHealth(['pacifica-main']) const health = healthCheck.get('pacifica-main') expect(health?.consecutiveFailures).toBe(5) expect(health?.isHealthy).toBe(false) }) }) describe('Platform-Specific Signature Formats', () => { test('should generate correct signature format for Pacifica', async () => { const request = { operation: TradingOperation.PLACE_ORDER, platform: Platform.PACIFICA, parameters: { symbol: 'SOL/USDC', side: 'buy' as const, quantity: 1.0 } } const result = await credentialManager.signTradingRequest(request) expect(result.platformSignature.format).toBe('base64') expect(result.platformSignature.headers?.['X-Algorithm']).toBe('ed25519') }) test('should generate correct signature format for Aster', async () => { const request = { operation: TradingOperation.GET_BALANCE, platform: Platform.ASTER, parameters: {} } const result = await credentialManager.signTradingRequest(request) expect(result.platformSignature.format).toBe('hex') expect(result.platformSignature.headers?.['X-Algorithm']).toBe('eip191') }) test('should generate correct signature format for Binance', async () => { const request = { operation: TradingOperation.GET_POSITIONS, platform: Platform.BINANCE, parameters: { apiKey: 'test-api-key' } } const result = await credentialManager.signTradingRequest(request) expect(result.platformSignature.format).toBe('hex') expect(result.platformSignature.headers?.['X-MBX-APIKEY']).toBeDefined() expect(result.platformSignature.headers?.['X-MBX-SIGNATURE']).toBeDefined() }) }) })