soroswap-utils
Version:
Utilities for interacting with Soroswap, the decentralized exchange (DEX) on Soroban, which is the smart contracts platform of the Stellar network.
98 lines (87 loc) • 3.29 kB
text/typescript
import type {
Asset,
RawRouterEvent,
RawRouterInitEvent,
RawRouterLiquidityEvent,
RawRouterSwapEvent,
RouterAddLiquidityEvent,
RouterEvent,
RouterInitializedEvent,
RouterRemoveLiquidityEvent,
RouterSwapEvent,
} from "../types";
import { parseCommonProperties } from "./common";
const doGetAssetData = (assets: readonly Asset[], token: string): Asset => {
const assetData = assets.find((asset) => asset.contract === token);
// We have full data for a list of certified assets, but it is possible to
// have other tokens in pools, and those we don't have data for.
if (assetData === undefined) {
return { contract: token, isSoroswapCertified: false };
}
return assetData;
};
const parseRouterAddLiquidityEvent = (
rawEvent: RawRouterLiquidityEvent & { readonly topic2: "add" },
assets: readonly Asset[],
): RouterAddLiquidityEvent => ({
...parseCommonProperties(rawEvent),
amountOfFirstTokenDeposited: BigInt(rawEvent.amount_a),
amountOfSecondTokenDeposited: BigInt(rawEvent.amount_b),
firstToken: doGetAssetData(assets, rawEvent.token_a),
liquidityPoolAddress: rawEvent.pair,
liquidityPoolTokensMinted: BigInt(rawEvent.liquidity),
recipientAddress: rawEvent.to,
secondToken: doGetAssetData(assets, rawEvent.token_b),
});
const parseRouterInitEvent = (rawEvent: RawRouterInitEvent): RouterInitializedEvent => ({
...parseCommonProperties(rawEvent),
factoryAddress: rawEvent.factory,
});
const parseRouterRemoveLiquidityEvent = (
rawEvent: RawRouterLiquidityEvent & { readonly topic2: "remove" },
assets: readonly Asset[],
): RouterRemoveLiquidityEvent => ({
...parseCommonProperties(rawEvent),
amountOfFirstTokenWithdrawn: BigInt(rawEvent.amount_a),
amountOfSecondTokenWithdrawn: BigInt(rawEvent.amount_b),
firstToken: doGetAssetData(assets, rawEvent.token_a),
liquidityPoolAddress: rawEvent.pair,
liquidityPoolTokensBurned: BigInt(rawEvent.liquidity),
recipientAddress: rawEvent.to,
secondToken: doGetAssetData(assets, rawEvent.token_b),
});
const parseRouterSwapEvent = (
rawEvent: RawRouterSwapEvent,
assets: readonly Asset[],
): RouterSwapEvent => ({
...parseCommonProperties(rawEvent),
recipientAddress: rawEvent.to,
tokenAmountsInSequence: rawEvent.amounts.map(BigInt),
tradedTokenSequence: rawEvent.path.map((token) => doGetAssetData(assets, token)),
});
const parseRouterEvent = (assets: readonly Asset[], rawEvent: RawRouterEvent): RouterEvent => {
switch (rawEvent.topic2) {
case "add": {
return parseRouterAddLiquidityEvent(
rawEvent as RawRouterLiquidityEvent & { topic2: "add" },
assets,
);
}
case "init": {
return parseRouterInitEvent(rawEvent);
}
case "remove": {
return parseRouterRemoveLiquidityEvent(
rawEvent as RawRouterLiquidityEvent & { topic2: "remove" },
assets,
);
}
case "swap": {
return parseRouterSwapEvent(rawEvent, assets);
}
default: {
throw new Error("Unknown SoroswapRouter event type.");
}
}
};
export { parseRouterEvent };