Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/defi/defi/defi.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
import { JwtAuthGuard } from "src/core/auth/jwt.guard";
import { User } from "src/core/user/entities/user.entity";
import { CurrentUser } from "src/core/auth/decorators";
import { ProtocolRegistry, ProtocolAdapterMetadata } from "./protocols/protocol-registry";

@Controller("defi")
@UseGuards(JwtAuthGuard)
Expand All @@ -46,8 +47,24 @@ export class DeFiController {
private yieldOptimizationService: YieldOptimizationService,
private riskAssessmentService: RiskAssessmentService,
private transactionOptimizationService: TransactionOptimizationService,
private protocolRegistry: ProtocolRegistry,
) {}

// ==================== Protocols ====================

@Get("protocols")
getAvailableProtocols(): ProtocolAdapterMetadata[] {
return this.protocolRegistry.getAllAdapters().map((adapter) => ({
name: adapter.name,
supportedChains: adapter.supportedChains,
capabilities: [
...(typeof adapter.borrow === "function" ? ["borrow"] : []),
...(typeof adapter.stake === "function" ? ["stake"] : []),
...(typeof adapter.getSwapRoute === "function" ? ["swap"] : []),
],
}));
}

// ==================== Portfolio Management ====================

@Get("portfolio/summary")
Expand Down
31 changes: 29 additions & 2 deletions src/defi/defi/defi.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Module } from "@nestjs/common";
import { Module, OnModuleInit } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm";
import { BullModule } from "@nestjs/bull";
import { DiscoveryModule, DiscoveryService } from "@nestjs/core";

// Entities
import { DeFiPosition } from "./entities/defi-position.entity";
Expand All @@ -19,6 +20,7 @@ import { TransactionOptimizationService } from "./services/transaction-optimizat
import { AaveAdapter } from "./protocols/aave.adapter";
import { CompoundAdapter } from "./protocols/compound.adapter";
import { ProtocolRegistry } from "./protocols/protocol-registry";
import { ProtocolAdapter } from "./protocols/protocol-adapter.interface";

// Controller
import { DeFiController } from "./defi.controller";
Expand Down Expand Up @@ -87,6 +89,7 @@ import { TradeLockService } from "./trade-lock.service";
},
},
),
DiscoveryModule,
],
providers: [
// Protocol Adapters
Expand All @@ -111,4 +114,28 @@ import { TradeLockService } from "./trade-lock.service";
TradeLockService,
],
})
export class DeFiModule {}
export class DeFiModule implements OnModuleInit {
constructor(
private readonly protocolRegistry: ProtocolRegistry,
private readonly discoveryService: DiscoveryService,
) {}

onModuleInit() {
// Auto-discover and register all protocol adapters
const providers = this.discoveryService.getProviders();

providers.forEach((wrapper) => {
const instance = wrapper.instance;
if (
instance &&
typeof instance === "object" &&
"name" in instance &&
"supportedChains" in instance &&
typeof instance.getPosition === "function" &&
wrapper.metatype?.name?.endsWith("Adapter")
) {
this.protocolRegistry.register(instance as ProtocolAdapter);
}
});
}
}
51 changes: 23 additions & 28 deletions src/defi/defi/protocols/protocol-registry.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
import { Injectable, Logger } from "@nestjs/common";
import { ProtocolAdapter } from "./protocol-adapter.interface";
import { AaveAdapter } from "./aave.adapter";
import { CompoundAdapter } from "./compound.adapter";
import { DeFiProtocol } from "../entities/defi-position.entity";

export interface ProtocolAdapterMetadata {
name: string;
supportedChains: string[];
capabilities: string[];
}

@Injectable()
export class ProtocolRegistry {
private logger = new Logger("ProtocolRegistry");
private adapters: Map<DeFiProtocol, ProtocolAdapter> = new Map();

constructor(
private aaveAdapter: AaveAdapter,
private compoundAdapter: CompoundAdapter,
) {
this.registerAdapters();
}
private readonly logger = new Logger(ProtocolRegistry.name);
private readonly adapters: Map<string, ProtocolAdapter> = new Map();

constructor() {}

private registerAdapters() {
this.adapters.set(DeFiProtocol.AAVE, this.aaveAdapter);
this.adapters.set(DeFiProtocol.COMPOUND, this.compoundAdapter);
// Additional adapters would be registered here
// this.adapters.set(DeFiProtocol.YEARN, new YearnAdapter());
// this.adapters.set(DeFiProtocol.LIDO, new LidoAdapter());
register(adapter: ProtocolAdapter) {
if (this.adapters.has(adapter.name)) {
this.logger.warn(
`Protocol adapter ${adapter.name} is already registered. Overwriting.`,
);
}
this.adapters.set(adapter.name, adapter);
this.logger.log(`Registered protocol adapter: ${adapter.name}`);
}

getAdapter(protocol: DeFiProtocol): ProtocolAdapter {
const adapter = this.adapters.get(protocol);
getAdapter(protocolName: string): ProtocolAdapter {
const adapter = this.adapters.get(protocolName);
if (!adapter) {
throw new Error(`Protocol adapter not found: ${protocol}`);
throw new Error(`Protocol adapter not found: ${protocolName}`);
}
return adapter;
}
Expand All @@ -36,8 +36,8 @@ export class ProtocolRegistry {
return Array.from(this.adapters.values());
}

isProtocolSupported(protocol: DeFiProtocol): boolean {
return this.adapters.has(protocol);
isProtocolSupported(protocolName: string): boolean {
return this.adapters.has(protocolName);
}

getSupportedProtocols(): string[] {
Expand All @@ -55,9 +55,4 @@ export class ProtocolRegistry {

return supportingAdapters;
}

registerAdapter(protocol: DeFiProtocol, adapter: ProtocolAdapter) {
this.logger.log(`Registering adapter for protocol: ${protocol}`);
this.adapters.set(protocol, adapter);
}
}