diff --git a/src/common/validators/is-valid-address.validator.ts b/src/common/validators/is-valid-address.validator.ts index 26e83e3..c48d9a4 100644 --- a/src/common/validators/is-valid-address.validator.ts +++ b/src/common/validators/is-valid-address.validator.ts @@ -12,7 +12,7 @@ export function IsValidAddress(validationOptions?: ValidationOptions) { const srcChain = (args.object as any).srcChain; if (srcChain === "stellar") { - return typeof value === "string" && value.length === 56; + return typeof value === "string" && /^G[A-Z2-7]{55}$/.test(value); } return typeof value === "string" && /^0x[a-fA-F0-9]{40}$/.test(value); diff --git a/src/intents/dto/list-intents.dto.ts b/src/intents/dto/list-intents.dto.ts index f569bcc..dca9191 100644 --- a/src/intents/dto/list-intents.dto.ts +++ b/src/intents/dto/list-intents.dto.ts @@ -23,8 +23,13 @@ export class ListIntentsDto { @Max(100) limit!: number; + @ApiPropertyOptional({ description: "Cursor for the next page of intents" }) + @IsOptional() + @IsString() + cursor?: string; + @ApiProperty({ minimum: 0, default: 0, description: "Number of results to skip" }) @IsInt() @Min(0) offset!: number; -} \ No newline at end of file +} diff --git a/src/solvers/dto/register-solver.dto.ts b/src/solvers/dto/register-solver.dto.ts index 4bff265..502a235 100644 --- a/src/solvers/dto/register-solver.dto.ts +++ b/src/solvers/dto/register-solver.dto.ts @@ -42,4 +42,9 @@ export class RegisterSolverDto { @IsArray() @IsString({ each: true }) supportedTokens!: string[]; + + @ApiProperty({ description: "Proof-of-control signature for the advertised solver address" }) + @IsString() + @IsNotEmpty() + proofSignature!: string; } diff --git a/src/soroban/account-rate-limit.guard.ts b/src/soroban/account-rate-limit.guard.ts index cc988ff..db06117 100644 --- a/src/soroban/account-rate-limit.guard.ts +++ b/src/soroban/account-rate-limit.guard.ts @@ -9,7 +9,12 @@ export class AccountRateLimitGuard implements CanActivate { canActivate(context: ExecutionContext): boolean { const request = context.switchToHttp().getRequest(); - const ip = (request.headers["x-forwarded-for"] as string) || request.ip || "unknown-ip"; + const forwarded = request.headers["x-forwarded-for"]; + const trustedForwardedIp = + request.ip === "127.0.0.1" && typeof forwarded === "string" + ? forwarded.split(",")[0]?.trim() + : undefined; + const ip = trustedForwardedIp || request.ip || "unknown-ip"; const now = Date.now(); const record = this.requestCounts.get(ip);