@robertprp/intents-sdk
Version:
Shogun Network Intent-based cross-chain swaps SDK
83 lines (71 loc) • 3.15 kB
text/typescript
import type { CreateCrossChainOrderParams } from '../core/orders/cross-chain.js';
import type { CreateSingleChainOrderParams } from '../core/orders/single-chain.js';
import { ValidationError } from '../errors/index.js';
import type { IChainValidator } from './order-validator.js';
/**
* BaseValidator - Abstract class implementing common validation logic
* This follows the Template Method pattern
*/
export abstract class BaseValidator implements IChainValidator {
abstract isValidAddress(address: string): boolean;
abstract isValidTokenAddress(tokenAddress: string): boolean;
abstract isValidAmount(amount: bigint): boolean;
protected abstract getChainName(): string;
abstract validateCrossChainOrderFeasability(order: CreateCrossChainOrderParams & { user: string }): Promise<void>;
abstract validateSingleChainOrderFeasability(order: CreateSingleChainOrderParams & { user: string }): Promise<void>;
/**
* Validate source chain specific parameters of the order
*/
async validateSourceChain(order: CreateCrossChainOrderParams & { user: string }): Promise<void> {
this.validateTokenAddress(order.sourceTokenAddress);
this.validateAmount(order.sourceTokenAmount);
this.validateAmount(order.minStablecoinAmount ?? 1n);
await this.validateCrossChainOrderFeasability({ ...order, user: order.user });
}
async validateSingleChainOrder(order: CreateSingleChainOrderParams & { user: string }): Promise<void> {
this.validateTokenAddress(order.tokenIn);
this.validateTokenAddress(order.tokenOut);
this.validateAmount(order.amountIn);
this.validateAmount(order.amountOutMin ?? 1n);
if (order.stopLossMaxOut) {
this.validateAmount(order.stopLossMaxOut);
}
if (order.takeProfitMinOut) {
this.validateAmount(order.takeProfitMinOut);
}
await this.validateSingleChainOrderFeasability(order);
}
/**
* Validate destination chain specific parameters of the order
*/
validateDestinationChain(order: CreateCrossChainOrderParams): void {
this.validateAddress(order.destinationAddress);
this.validateTokenAddress(order.destinationTokenAddress);
this.validateAmount(order.destinationTokenMinAmount ?? 1n);
if (order.extraTransfers) {
for (const extraTransfer of order.extraTransfers) {
this.validateAddress(extraTransfer.receiver);
this.validateTokenAddress(extraTransfer.token);
this.validateAmount(extraTransfer.amount);
}
}
}
/**
* Helper methods that throw specific validation errors
*/
protected validateAddress(address: string): void {
if (!this.isValidAddress(address)) {
throw new ValidationError(`Invalid ${this.getChainName()} address: ${address}`);
}
}
protected validateTokenAddress(tokenAddress: string): void {
if (!this.isValidTokenAddress(tokenAddress)) {
throw new ValidationError(`Invalid ${this.getChainName()} token address: ${tokenAddress}`);
}
}
protected validateAmount(amount: bigint): void {
if (!this.isValidAmount(amount)) {
throw new ValidationError(`Amount must be greater than 0. Value: ${amount}`);
}
}
}