@robertprp/intents-sdk
Version:
Shogun Network Intent-based cross-chain swaps SDK
154 lines (124 loc) • 5.37 kB
text/typescript
import { AUCTIONEER_URL } from '../constants.js';
import { NetworkError } from '../errors/index.js';
import type { ApiResponse, ApiUserOrders } from '../types/api.js';
import type {
CrossChainOrderPrepared,
CrossChainUserIntentRequest,
SingleChainOrderPrepared,
SingleChainUserIntentRequest,
} from '../types/intent.js';
import { Parsers } from '../utils/parsers.js';
import { CrossChainOrder, type CreateCrossChainOrderParams } from './orders/cross-chain.js';
import { SingleChainOrder, type CreateSingleChainOrderParams } from './orders/single-chain.js';
/**
* Base SDK providing common functionality for all blockchain implementations
*
* This abstract class serves as the foundation for chain-specific SDK implementations
* (EVM, Solana, Sui), providing shared functionality for creating and sending orders
* across different blockchains.
*/
export abstract class BaseSDK {
public abstract getOrders(): Promise<ApiUserOrders>;
public abstract getUserAddress(): Promise<string>;
protected abstract prepareCrossChainOrder(order: CrossChainOrder): Promise<CrossChainOrderPrepared>;
protected abstract prepareSingleChainOrder(order: SingleChainOrder): Promise<SingleChainOrderPrepared>;
public async createSingleChainOrder(params: CreateSingleChainOrderParams): Promise<SingleChainOrderPrepared> {
const userAddress = await this.getUserAddress();
const order = await SingleChainOrder.create({
...params,
user: userAddress,
});
return this.prepareSingleChainOrder(order);
}
public async createCrossChainOrder(params: CreateCrossChainOrderParams): Promise<CrossChainOrderPrepared> {
const userAddress = await this.getUserAddress();
const order = await CrossChainOrder.create({
...params,
user: userAddress,
});
return this.prepareCrossChainOrder(order);
}
public async createAndSendSingleChainOrder(params: CreateSingleChainOrderParams): Promise<ApiResponse> {
const preparedOrder = await this.createSingleChainOrder(params);
return BaseSDK.sendSingleChainOrder(preparedOrder);
}
public static async sendSingleChainOrder(preparedOrder: SingleChainOrderPrepared): Promise<ApiResponse> {
const intentRequest = preparedOrder.order.toIntentRequest(preparedOrder.preparedData);
const body = JSON.stringify(intentRequest, Parsers.bigIntReplacer);
const url = `${AUCTIONEER_URL}/user_intent/single_chain/limit_order`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body,
});
if (!response.ok) {
const errorJson: ApiResponse = await response.json();
const extraErrorData = errorJson.extra_error_data;
throw new NetworkError(`Server error ${extraErrorData}`);
}
return response.json();
}
public static async validateCrossChainOrder(intentRequest: CrossChainUserIntentRequest): Promise<void> {
const body = JSON.stringify(intentRequest, Parsers.bigIntReplacer);
const url = `${AUCTIONEER_URL}/validate_intent/cross_chain/limit_order`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body,
});
if (!response.ok) {
const errorJson: ApiResponse = await response.json();
const mainError = errorJson.error;
const extraErrorData = errorJson.extra_error_data;
throw new NetworkError(`Validation error: ${mainError}. Extra error data: ${extraErrorData}`);
}
return;
}
public static async validateSingleChainOrder(intentRequest: SingleChainUserIntentRequest): Promise<void> {
const body = JSON.stringify(intentRequest, Parsers.bigIntReplacer);
const url = `${AUCTIONEER_URL}/validate_intent/single_chain/limit_order`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body,
});
if (!response.ok) {
const errorJson: ApiResponse = await response.json();
const mainError = errorJson.error;
const extraErrorData = errorJson.extra_error_data;
throw new NetworkError(`Validation error: ${mainError}. Extra error data: ${extraErrorData}`);
}
return;
}
public async createAndSendCrossChainOrder(params: CreateCrossChainOrderParams): Promise<ApiResponse> {
const preparedOrder = await this.createCrossChainOrder(params);
return BaseSDK.sendCrossChainOrder(preparedOrder);
}
public static async sendCrossChainOrder(preparedOrder: CrossChainOrderPrepared): Promise<ApiResponse> {
const intentRequest = preparedOrder.order.toIntentRequest(preparedOrder.preparedData);
const body = JSON.stringify(intentRequest, Parsers.bigIntReplacer);
const url = `${AUCTIONEER_URL}/user_intent/cross_chain/limit_order`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body,
});
if (!response.ok) {
const errorJson: ApiResponse = await response.json();
const mainError = errorJson.error;
const extraErrorData = errorJson.extra_error_data;
throw new NetworkError(
`Failed to send cross-chain order. Main error: ${mainError}. Extra error data: ${extraErrorData}`,
);
}
return response.json();
}
}