UNPKG

@robertprp/intents-sdk

Version:

Shogun Network Intent-based cross-chain swaps SDK

102 lines (80 loc) 3.5 kB
import { ChainType, chainIdToChainTypeMap, type SupportedChain } from '../chains.js'; import { EvmValidator } from '../core/evm/validator.js'; import type { CreateCrossChainOrderParams } from '../core/orders/cross-chain.js'; import type { CreateSingleChainOrderParams } from '../core/orders/single-chain.js'; import { SolanaValidator } from '../core/solana/validator.js'; import { SuiValidator } from '../core/sui/validator.js'; import { ValidationError } from '../errors/index.js'; export interface IAddressValidator { isValidAddress(address: string): boolean; } export interface ITokenValidator { isValidTokenAddress(tokenAddress: string): boolean; } export interface IAmountValidator { isValidAmount(amount: bigint): boolean; } export interface IDeadlineValidator { isValidDeadline(deadline: number): boolean; } export interface IChainValidator extends IAddressValidator, ITokenValidator, IAmountValidator { validateSourceChain(order: CreateCrossChainOrderParams & { user: string }): Promise<void>; validateDestinationChain(order: CreateCrossChainOrderParams): void; validateSingleChainOrder(order: CreateSingleChainOrderParams & { user: string }): Promise<void>; } /** * CommonValidator - Handles validations shared across chains */ export class CommonValidator implements IDeadlineValidator { isValidDeadline(deadline: number): boolean { return deadline > Math.floor(Date.now() / 1000); } validateDeadline(deadline: number): void { if (!this.isValidDeadline(deadline)) { throw new ValidationError('Deadline must be in the future'); } } } export class ValidatorFactory { private static validators: Map<ChainType, IChainValidator> = new Map(); static getValidator(chainType: ChainType): IChainValidator { if (!this.validators.has(chainType)) { switch (chainType) { case ChainType.EVM: this.validators.set(chainType, new EvmValidator()); break; case ChainType.Solana: this.validators.set(chainType, new SolanaValidator()); break; case ChainType.Sui: this.validators.set(chainType, new SuiValidator()); break; default: throw new ValidationError(`Chain type ${chainType} validation is not implemented.`); } } return this.validators.get(chainType)!; } static getValidatorForChain(chainId: SupportedChain): IChainValidator { const chainType = chainIdToChainTypeMap[chainId]; return this.getValidator(chainType); } } export class CrossChainOrderValidator { private readonly commonValidator = new CommonValidator(); async validateOrder(order: CreateCrossChainOrderParams & { user: string }): Promise<void> { const sourceValidator = ValidatorFactory.getValidatorForChain(order.sourceChainId); await sourceValidator.validateSourceChain({ ...order, user: order.user }); const destinationValidator = ValidatorFactory.getValidatorForChain(order.destinationChainId); destinationValidator.validateDestinationChain(order); this.commonValidator.validateDeadline(order.deadline); } } export class SingleChainOrderValidator { private readonly commonValidator = new CommonValidator(); async validateOrder(order: CreateSingleChainOrderParams & { user: string }): Promise<void> { this.commonValidator.validateDeadline(order.deadline); const chainValidator = ValidatorFactory.getValidatorForChain(order.chainId); chainValidator.validateSingleChainOrder(order); } }