Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/pathRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ export interface PathResult {
destinationAmount: bigint;
/** Amount sent from the source (in the source asset's base unit). */
sourceAmount: bigint;
/** Flag indicating if the path was found using the fallback threshold. */
usedFallback?: boolean;
}

export interface FindPathParams {
sourceAsset: Asset;
destinationAsset: Asset;
threshold: bigint;
fallbackSlippagePct?: number;
}

/** Parameters for pathfinding. */
Expand Down Expand Up @@ -184,6 +193,47 @@ export class PathRouter {
}
}

/**
* Find a path using a primary threshold, with an optional fallback.
*/
async findPath(params: FindPathParams): Promise<PathResult> {
const sourceAssetType = assetType(params.sourceAsset);
const destAssetType = assetType(params.destinationAsset);

const trySend = async (amount: bigint) => {
const query = this.queryBuilder.forStrictSend({
sourceAsset: params.sourceAsset,
sourceAmount: amount,
destinationAssets: [params.destinationAsset],
});
return await this.queryBuilder.execute(query);
};

let results = await trySend(params.threshold);
let usedFallback = false;

if (results.length === 0 && params.fallbackSlippagePct !== undefined) {
const pct = params.fallbackSlippagePct;
const multiplier = 1 + pct / 100;
const fallbackAmount = BigInt(Math.floor(Number(params.threshold) * multiplier));

results = await trySend(fallbackAmount);
usedFallback = true;
}

if (results.length === 0) {
throw new PathNotFoundError(sourceAssetType, destAssetType, params.threshold);
}

const best = results[0]!;
return {
path: best.path,
destinationAmount: best.destinationAmount,
sourceAmount: best.sourceAmount,
...(usedFallback ? { usedFallback: true } : {})
};
}

/**
* Find the best path to receive exactly `destAmount` of `destinationAsset`
* while spending as little of `sourceAsset` as possible.
Expand Down