soroswap-utils
Version:
Utilities for interacting with Soroswap, the decentralized exchange (DEX) on Soroban, which is the smart contracts platform of the Stellar network.
141 lines (123 loc) • 4.87 kB
text/typescript
import type { SoroswapContract } from "./types";
import { buildMercuryInstance, resolveContractId } from "./utils";
const soroswapSubscriber = async (
contractId: string,
isEnvironmentVariable = false,
): Promise<boolean> => {
const mercuryInstance = buildMercuryInstance();
const resolvedContract = resolveContractId(contractId, isEnvironmentVariable);
const response = await mercuryInstance.subscribeToContractEvents({
contractId: resolvedContract,
});
return response.data as boolean;
};
/**
* The Soroswap Factory contract emits events when a new pool is created.
* Use this function to subscribe to those events.
* @returns A promise that resolves to true if the subscription was successful.
*/
const subscribeToSoroswapFactory = async (): Promise<boolean> =>
await soroswapSubscriber("SOROSWAP_FACTORY_CONTRACT", true);
/**
* The Soroswap Router contract emits events when a swap is executed.
* Use this function to subscribe to those events.
* @returns A promise that resolves to true if the subscription was successful.
*/
const subscribeToSoroswapRouter = async (): Promise<boolean> =>
await soroswapSubscriber("SOROSWAP_ROUTER_CONTRACT", true);
/**
* Soroswap Pair contracts emit events for operations such as adding or
* removing liquidity, swapping, or skimming.
* Use this function to subscribe to those events.
* @param pairContract The contract ID of the Soroswap Pair contract.
* @returns A promise that resolves to true if the subscription was successful.
*/
const subscribeToSoroswapPair = async (pairContract: string): Promise<boolean> =>
await soroswapSubscriber(pairContract);
/**
* Subscribe to multiple SoroswapPair contracts.
* @param contractIds An array of contract IDs to subscribe to.
* @returns A promise that resolves to true if all subscriptions
* were successful.
*/
const subscribeToSoroswapPairs = async (contractIds: readonly string[]): Promise<boolean> => {
const promises = contractIds.map(
async (pairContract) => await soroswapSubscriber(pairContract),
);
return await Promise.all(promises).then((results) => results.every(Boolean));
};
const doStringContractType = (
contractType: string,
subscriptions: readonly string[],
promises: readonly Readonly<Promise<boolean>>[],
): { promises: Promise<boolean>[]; subscriptions: string[] } => {
if (
["factory", "SoroswapFactory"].includes(contractType) &&
!subscriptions.includes("factory")
) {
return {
promises: [...promises, subscribeToSoroswapFactory()],
subscriptions: [...subscriptions, "factory"],
};
}
if (["router", "SoroswapRouter"].includes(contractType) && !subscriptions.includes("router")) {
return {
promises: [...promises, subscribeToSoroswapRouter()],
subscriptions: [...subscriptions, "router"],
};
}
throw new Error("Invalid contract type");
};
const contractSubscriber = (
{
promises,
subscriptions,
}: Readonly<{
promises: readonly Readonly<Promise<boolean>>[];
subscriptions: readonly string[];
}>,
contractType: SoroswapContract,
): { promises: Promise<boolean>[]; subscriptions: string[] } => {
switch (typeof contractType) {
case "string": {
return doStringContractType(contractType, subscriptions, promises);
}
case "object": {
const pairsToSubscribeTo = contractType.pair ?? contractType.SoroswapPair;
return {
promises: [...promises, subscribeToSoroswapPairs(pairsToSubscribeTo)],
subscriptions: [...subscriptions, ...pairsToSubscribeTo],
};
}
default: {
throw new Error("Invalid contract type");
}
}
};
/**
* Subscribe to Soroswap contracts of the given types.
* @param contractTypes An array of types of contracts to subscribe to.
* These can be:
* - the strings "SoroswapFactory" or "factory"
* - the strings "SoroswapRouter" or "router"
* - an object with either the key "SoroswapPair" or just "pair" and the value
* an array of contract IDs to subscribe to.
* @returns A promise that resolves to true if all subscriptions
* were successful.
*/
const subscribeToSoroswapContracts = async (
contractTypes: readonly SoroswapContract[],
): Promise<boolean> => {
const { promises: returnedPromises } = contractTypes.reduce(contractSubscriber, {
promises: [] as Promise<boolean>[],
subscriptions: [] as string[],
});
return await Promise.all(returnedPromises).then((results) => results.every(Boolean));
};
export {
subscribeToSoroswapContracts,
subscribeToSoroswapFactory,
subscribeToSoroswapPair,
subscribeToSoroswapPairs,
subscribeToSoroswapRouter,
};