@xian-tech/dex 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # `@xian-tech/dex`
2
+
3
+ Dependency-free routing and transaction-planning primitives for DEX clients,
4
+ agents, and browser applications. The package performs no RPC reads, key
5
+ handling, simulation, signing, or submission.
6
+
7
+ The public surface has three layers:
8
+
9
+ - protocol-neutral route enumeration driven by caller-supplied pool and quote
10
+ adapters;
11
+ - reusable constant-product pricing with numeric or string pool IDs and
12
+ optional per-pool fees;
13
+ - an explicit canonical Xian DEX v1 adapter for `con_pairs` / `con_dex` call
14
+ shapes and fee-on-transfer behavior.
15
+
16
+ ## Canonical Xian DEX v1
17
+
18
+ ```ts
19
+ import {
20
+ deadlineFromNow,
21
+ planXianDexV1ExactInExecution,
22
+ selectBestXianDexV1ExactInRoute,
23
+ } from "@xian-tech/dex";
24
+
25
+ const quote = selectBestXianDexV1ExactInRoute({
26
+ pairs,
27
+ fromToken: "currency",
28
+ toToken: "con_usdc",
29
+ amountIn: 10,
30
+ feeBps: 30,
31
+ maxHops: 3,
32
+ });
33
+
34
+ if (!quote) throw new Error("No route");
35
+
36
+ const plan = planXianDexV1ExactInExecution({
37
+ quote,
38
+ recipient: agentAddress,
39
+ allowance,
40
+ approvalAmount: 10,
41
+ slippageBps: 50,
42
+ deadline: deadlineFromNow(15),
43
+ routerContract: "con_dex",
44
+ feeOnTransferTokens: knownFeeOnTransferTokens,
45
+ });
46
+
47
+ for (const call of plan.calls) await submitCall(call);
48
+ ```
49
+
50
+ Pass `routerContract` to target another deployment of the same v1 contract
51
+ interface. The canonical adapter chooses the supporting fee-on-transfer
52
+ entrypoint for flagged source/destination tokens and rejects a flagged
53
+ intermediate token.
54
+
55
+ ## Another DEX or Pool Model
56
+
57
+ Use the routing core with records and quote semantics owned by the integration:
58
+
59
+ ```ts
60
+ import { selectBestExactInRoute } from "@xian-tech/dex/routing";
61
+
62
+ const quote = selectBestExactInRoute({
63
+ pools,
64
+ adapter: {
65
+ poolId: (pool) => pool.address,
66
+ tokens: (pool) => pool.assets,
67
+ quoteExactIn: ({ pool, fromToken, amountIn }) =>
68
+ quoteStablePool(pool, fromToken, amountIn),
69
+ },
70
+ fromToken: "currency",
71
+ toToken: "con_usdc",
72
+ amountIn: 10,
73
+ });
74
+ ```
75
+
76
+ An execution adapter supplies the approval and swap ABI. The generic planner
77
+ then applies slippage and allowance rules without assuming a router contract,
78
+ function name, or keyword shape. See `tests/execution.test.ts` for a complete
79
+ custom-ABI example.
80
+
81
+ ## Boundaries
82
+
83
+ - Pool state and quote adapters are caller-owned.
84
+ - All built-in quote math currently uses JavaScript numbers. Consumers needing
85
+ arbitrary precision must validate against on-chain simulation before signing.
86
+ - The generic router handles simple non-split exact-input routes. DEX-specific
87
+ split routing or concentrated-liquidity traversal belongs in an adapter or a
88
+ future focused module.
89
+ - New DEX integrations should add adapters, not duplicate the routing core.
90
+
91
+ ## Validation
92
+
93
+ From the `xian-js` root:
94
+
95
+ ```bash
96
+ npm run typecheck
97
+ npm run build
98
+ npm run test
99
+ ```
100
+
101
+ Against a stack localnet with the canonical demo pool installed:
102
+
103
+ ```bash
104
+ XIAN_PRIVATE_KEY="$XIAN_PRIVATE_KEY" npm run test:live:dex
105
+ ```
106
+
107
+ The smoke test reads real reserves and signer fees, plans through the Xian DEX
108
+ v1 adapter, submits any required approval plus the exact planned router call,
109
+ and requires finalized successful receipts.
@@ -0,0 +1,73 @@
1
+ import { type ConstantProductExactInQuote, type ConstantProductPool } from "../constant-product.js";
2
+ import { type ContractCallPlan, type ExactInExecutionAdapter, type ExactInExecutionPlan, type ExactInSwapPlan, type XianDatetime } from "../execution.js";
3
+ export declare const DEFAULT_XIAN_DEX_V1_CONTRACTS: {
4
+ readonly router: "con_dex";
5
+ readonly pairs: "con_pairs";
6
+ };
7
+ export declare const DEFAULT_XIAN_DEX_V1_TRADE_FEE_BPS = 30;
8
+ export interface XianFixed {
9
+ __fixed__: string;
10
+ }
11
+ export interface XianDexV1Pair extends Omit<ConstantProductPool<number>, "feeBps"> {
12
+ }
13
+ export interface XianDexV1ExactInQuoteHop {
14
+ pairId: number;
15
+ fromToken: string;
16
+ toToken: string;
17
+ reserveIn: number;
18
+ reserveOut: number;
19
+ amountIn: number;
20
+ amountOut: number;
21
+ }
22
+ export interface XianDexV1ExactInQuote extends Omit<ConstantProductExactInQuote<number>, "hops"> {
23
+ hops: XianDexV1ExactInQuoteHop[];
24
+ /** The canonical v1 signer fee applied uniformly to each hop. */
25
+ feeBps: number;
26
+ }
27
+ export interface XianDexV1QuoteRequest {
28
+ pairs: readonly XianDexV1Pair[];
29
+ fromToken: string;
30
+ toToken: string;
31
+ amountIn: number;
32
+ feeBps?: number;
33
+ maxHops?: number;
34
+ }
35
+ export interface XianDexV1ExecutionOptions {
36
+ routerContract?: string;
37
+ feeOnTransferTokens?: Iterable<string>;
38
+ supportingFeeOnTransfer?: boolean;
39
+ }
40
+ interface XianDexV1ExecutionMetadata {
41
+ supportingFeeOnTransfer: boolean;
42
+ }
43
+ export interface XianDexV1TokenApprovalRequest {
44
+ token: string;
45
+ spender?: string;
46
+ amount: number;
47
+ }
48
+ export interface XianDexV1SwapPlanRequest extends XianDexV1ExecutionOptions {
49
+ quote: XianDexV1ExactInQuote;
50
+ recipient: string;
51
+ slippageBps: number;
52
+ deadline: XianDatetime;
53
+ }
54
+ export interface XianDexV1ExecutionPlanRequest extends XianDexV1SwapPlanRequest {
55
+ allowance: number;
56
+ approvalAmount?: number;
57
+ }
58
+ export interface XianDexV1SwapPlan extends ExactInSwapPlan<XianDexV1ExecutionMetadata> {
59
+ supportingFeeOnTransfer: boolean;
60
+ }
61
+ export interface XianDexV1ExecutionPlan extends ExactInExecutionPlan<XianDexV1ExecutionMetadata> {
62
+ supportingFeeOnTransfer: boolean;
63
+ }
64
+ /** Encode a deterministic decimal for Xian transaction payloads. */
65
+ export declare function xianFixed(value: number | string): XianFixed;
66
+ export declare function enumerateXianDexV1ExactInRoutes(request: XianDexV1QuoteRequest): XianDexV1ExactInQuote[];
67
+ export declare function selectBestXianDexV1ExactInRoute(request: XianDexV1QuoteRequest): XianDexV1ExactInQuote | null;
68
+ export declare function planXianDexV1TokenApproval(request: XianDexV1TokenApprovalRequest): ContractCallPlan;
69
+ export declare function createXianDexV1ExecutionAdapter(): ExactInExecutionAdapter<XianDexV1ExactInQuote, XianDexV1ExecutionOptions, XianDexV1ExecutionMetadata>;
70
+ export declare function planXianDexV1ExactInSwap(request: XianDexV1SwapPlanRequest): XianDexV1SwapPlan;
71
+ export declare function planXianDexV1ExactInExecution(request: XianDexV1ExecutionPlanRequest): XianDexV1ExecutionPlan;
72
+ export {};
73
+ //# sourceMappingURL=xian-v1.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xian-v1.d.ts","sourceRoot":"","sources":["../../src/adapters/xian-v1.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,153 @@
1
+ import { createConstantProductAdapter, } from "../constant-product.js";
2
+ import { planExactInExecution, planExactInSwap, } from "../execution.js";
3
+ import { enumerateExactInRoutes } from "../routing.js";
4
+ export const DEFAULT_XIAN_DEX_V1_CONTRACTS = {
5
+ router: "con_dex",
6
+ pairs: "con_pairs",
7
+ };
8
+ export const DEFAULT_XIAN_DEX_V1_TRADE_FEE_BPS = 30;
9
+ function assertNonEmpty(value, label) {
10
+ if (value.trim().length === 0)
11
+ throw new RangeError(`${label} must not be empty`);
12
+ }
13
+ function assertFinitePositive(value, label) {
14
+ if (!Number.isFinite(value) || value <= 0) {
15
+ throw new RangeError(`${label} must be a finite positive number`);
16
+ }
17
+ }
18
+ /** Encode a deterministic decimal for Xian transaction payloads. */
19
+ export function xianFixed(value) {
20
+ const text = String(value).trim();
21
+ if (text.length === 0 || !Number.isFinite(Number(text))) {
22
+ throw new RangeError("fixed value must be finite");
23
+ }
24
+ return { __fixed__: text };
25
+ }
26
+ function routeEndpoints(quote) {
27
+ if (quote.hops.length === 0 || quote.path.length !== quote.hops.length) {
28
+ throw new RangeError("quote must contain matching non-empty hops and path");
29
+ }
30
+ const firstHop = quote.hops[0];
31
+ const lastHop = quote.hops[quote.hops.length - 1];
32
+ if (!firstHop || !lastHop)
33
+ throw new RangeError("quote route is incomplete");
34
+ return { source: firstHop.fromToken, destination: lastHop.toToken };
35
+ }
36
+ export function enumerateXianDexV1ExactInRoutes(request) {
37
+ const feeBps = request.feeBps ?? DEFAULT_XIAN_DEX_V1_TRADE_FEE_BPS;
38
+ const quotes = enumerateExactInRoutes({
39
+ pools: request.pairs,
40
+ adapter: createConstantProductAdapter(feeBps),
41
+ fromToken: request.fromToken,
42
+ toToken: request.toToken,
43
+ amountIn: request.amountIn,
44
+ maxHops: request.maxHops,
45
+ });
46
+ return quotes.map((quote) => ({
47
+ ...quote,
48
+ feeBps,
49
+ hops: quote.hops.map((hop) => ({
50
+ pairId: hop.poolId,
51
+ fromToken: hop.fromToken,
52
+ toToken: hop.toToken,
53
+ reserveIn: hop.metadata.reserveIn,
54
+ reserveOut: hop.metadata.reserveOut,
55
+ amountIn: hop.amountIn,
56
+ amountOut: hop.amountOut,
57
+ })),
58
+ }));
59
+ }
60
+ export function selectBestXianDexV1ExactInRoute(request) {
61
+ return enumerateXianDexV1ExactInRoutes(request)[0] ?? null;
62
+ }
63
+ export function planXianDexV1TokenApproval(request) {
64
+ assertNonEmpty(request.token, "token");
65
+ const spender = request.spender ?? DEFAULT_XIAN_DEX_V1_CONTRACTS.router;
66
+ assertNonEmpty(spender, "spender");
67
+ assertFinitePositive(request.amount, "approval amount");
68
+ return {
69
+ contract: request.token,
70
+ function: "approve",
71
+ kwargs: { amount: xianFixed(request.amount), to: spender },
72
+ };
73
+ }
74
+ export function createXianDexV1ExecutionAdapter() {
75
+ return {
76
+ amountIn: (quote) => quote.amountIn,
77
+ amountOut: (quote) => quote.amountOut,
78
+ sourceToken: (quote) => routeEndpoints(quote).source,
79
+ approvalSpender: (options) => options.routerContract ?? DEFAULT_XIAN_DEX_V1_CONTRACTS.router,
80
+ buildApprovalCall: ({ token, spender, amount }) => planXianDexV1TokenApproval({ token, spender, amount }),
81
+ buildSwapCall: ({ quote, recipient, amountOutMin, deadline, options }) => {
82
+ const routerContract = options.routerContract ?? DEFAULT_XIAN_DEX_V1_CONTRACTS.router;
83
+ assertNonEmpty(routerContract, "routerContract");
84
+ const { source, destination } = routeEndpoints(quote);
85
+ const feeOnTransferTokens = new Set(options.feeOnTransferTokens ?? []);
86
+ const blockedIntermediate = quote.hops
87
+ .slice(0, -1)
88
+ .map((hop) => hop.toToken)
89
+ .find((token) => feeOnTransferTokens.has(token));
90
+ if (blockedIntermediate) {
91
+ throw new RangeError(`fee-on-transfer token ${blockedIntermediate} cannot be an intermediate route token`);
92
+ }
93
+ const supportingFeeOnTransfer = options.supportingFeeOnTransfer === true ||
94
+ feeOnTransferTokens.has(source) ||
95
+ feeOnTransferTokens.has(destination);
96
+ return {
97
+ call: {
98
+ contract: routerContract,
99
+ function: supportingFeeOnTransfer
100
+ ? "swapExactTokensForTokensSupportingFeeOnTransferTokens"
101
+ : "swapExactTokensForTokens",
102
+ kwargs: {
103
+ amountIn: xianFixed(quote.amountIn),
104
+ amountOutMin: xianFixed(amountOutMin),
105
+ path: [...quote.path],
106
+ src: source,
107
+ to: recipient,
108
+ deadline,
109
+ },
110
+ },
111
+ metadata: { supportingFeeOnTransfer },
112
+ };
113
+ },
114
+ };
115
+ }
116
+ function executionOptions(request) {
117
+ return {
118
+ routerContract: request.routerContract,
119
+ feeOnTransferTokens: request.feeOnTransferTokens,
120
+ supportingFeeOnTransfer: request.supportingFeeOnTransfer,
121
+ };
122
+ }
123
+ export function planXianDexV1ExactInSwap(request) {
124
+ const plan = planExactInSwap({
125
+ quote: request.quote,
126
+ recipient: request.recipient,
127
+ slippageBps: request.slippageBps,
128
+ deadline: request.deadline,
129
+ adapter: createXianDexV1ExecutionAdapter(),
130
+ options: executionOptions(request),
131
+ });
132
+ return {
133
+ ...plan,
134
+ supportingFeeOnTransfer: plan.adapterMetadata.supportingFeeOnTransfer,
135
+ };
136
+ }
137
+ export function planXianDexV1ExactInExecution(request) {
138
+ const plan = planExactInExecution({
139
+ quote: request.quote,
140
+ recipient: request.recipient,
141
+ allowance: request.allowance,
142
+ approvalAmount: request.approvalAmount,
143
+ slippageBps: request.slippageBps,
144
+ deadline: request.deadline,
145
+ adapter: createXianDexV1ExecutionAdapter(),
146
+ options: executionOptions(request),
147
+ });
148
+ return {
149
+ ...plan,
150
+ supportingFeeOnTransfer: plan.adapterMetadata.supportingFeeOnTransfer,
151
+ };
152
+ }
153
+ //# sourceMappingURL=xian-v1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xian-v1.js","sourceRoot":"","sources":["../../src/adapters/xian-v1.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { type ExactInQuote, type ExactInRoutingAdapter, type PoolId } from "./routing.js";
2
+ export declare const DEFAULT_CONSTANT_PRODUCT_FEE_BPS = 30;
3
+ export interface ConstantProductPool<Id extends PoolId = PoolId> {
4
+ id: Id;
5
+ token0: string;
6
+ token1: string;
7
+ reserve0: number;
8
+ reserve1: number;
9
+ /** Optional pool-specific fee; otherwise the adapter default is used. */
10
+ feeBps?: number;
11
+ }
12
+ export interface ConstantProductHopMetadata {
13
+ reserveIn: number;
14
+ reserveOut: number;
15
+ feeBps: number;
16
+ }
17
+ export type ConstantProductExactInQuote<Id extends PoolId = PoolId> = ExactInQuote<Id, ConstantProductHopMetadata>;
18
+ export interface ConstantProductQuoteRequest<Id extends PoolId> {
19
+ pools: readonly ConstantProductPool<Id>[];
20
+ fromToken: string;
21
+ toToken: string;
22
+ amountIn: number;
23
+ defaultFeeBps?: number;
24
+ maxHops?: number;
25
+ }
26
+ export declare function amountOutForExactIn(amountIn: number, reserveIn: number, reserveOut: number, feeBps?: number): number;
27
+ export declare function createConstantProductAdapter<Id extends PoolId>(defaultFeeBps?: number): ExactInRoutingAdapter<ConstantProductPool<Id>, Id, ConstantProductHopMetadata>;
28
+ export declare function enumerateConstantProductExactInRoutes<Id extends PoolId>(request: ConstantProductQuoteRequest<Id>): ConstantProductExactInQuote<Id>[];
29
+ export declare function selectBestConstantProductExactInRoute<Id extends PoolId>(request: ConstantProductQuoteRequest<Id>): ConstantProductExactInQuote<Id> | null;
30
+ //# sourceMappingURL=constant-product.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constant-product.d.ts","sourceRoot":"","sources":["../src/constant-product.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EACZ,MAAM,cAAc,CAAC;AAEtB,eAAO,MAAM,gCAAgC,KAAK,CAAC;AAEnD,MAAM,WAAW,mBAAmB,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM;IAC7D,EAAE,EAAE,EAAE,CAAC;IACP,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,2BAA2B,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,IAAI,YAAY,CAChF,EAAE,EACF,0BAA0B,CAC3B,CAAC;AAEF,MAAM,WAAW,2BAA2B,CAAC,EAAE,SAAS,MAAM;IAC5D,KAAK,EAAE,SAAS,mBAAmB,CAAC,EAAE,CAAC,EAAE,CAAC;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAQD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,SAAmC,GACxC,MAAM,CAcR;AAED,wBAAgB,4BAA4B,CAAC,EAAE,SAAS,MAAM,EAC5D,aAAa,SAAmC,GAC/C,qBAAqB,CACtB,mBAAmB,CAAC,EAAE,CAAC,EACvB,EAAE,EACF,0BAA0B,CAC3B,CAqBA;AAED,wBAAgB,qCAAqC,CAAC,EAAE,SAAS,MAAM,EACrE,OAAO,EAAE,2BAA2B,CAAC,EAAE,CAAC,GACvC,2BAA2B,CAAC,EAAE,CAAC,EAAE,CASnC;AAED,wBAAgB,qCAAqC,CAAC,EAAE,SAAS,MAAM,EACrE,OAAO,EAAE,2BAA2B,CAAC,EAAE,CAAC,GACvC,2BAA2B,CAAC,EAAE,CAAC,GAAG,IAAI,CASxC"}
@@ -0,0 +1,65 @@
1
+ import { enumerateExactInRoutes, selectBestExactInRoute, } from "./routing.js";
2
+ export const DEFAULT_CONSTANT_PRODUCT_FEE_BPS = 30;
3
+ function assertBps(value, label) {
4
+ if (!Number.isInteger(value) || value < 0 || value > 10_000) {
5
+ throw new RangeError(`${label} must be an integer from 0 to 10000`);
6
+ }
7
+ }
8
+ export function amountOutForExactIn(amountIn, reserveIn, reserveOut, feeBps = DEFAULT_CONSTANT_PRODUCT_FEE_BPS) {
9
+ assertBps(feeBps, "feeBps");
10
+ if (!Number.isFinite(amountIn) ||
11
+ !Number.isFinite(reserveIn) ||
12
+ !Number.isFinite(reserveOut) ||
13
+ amountIn <= 0 ||
14
+ reserveIn <= 0 ||
15
+ reserveOut <= 0) {
16
+ return 0;
17
+ }
18
+ const amountInWithFee = amountIn * ((10_000 - feeBps) / 10_000);
19
+ return (amountInWithFee * reserveOut) / (reserveIn + amountInWithFee);
20
+ }
21
+ export function createConstantProductAdapter(defaultFeeBps = DEFAULT_CONSTANT_PRODUCT_FEE_BPS) {
22
+ assertBps(defaultFeeBps, "defaultFeeBps");
23
+ return {
24
+ poolId: (pool) => pool.id,
25
+ tokens: (pool) => [pool.token0, pool.token1],
26
+ quoteExactIn: ({ pool, fromToken, toToken, amountIn }) => {
27
+ const forward = fromToken === pool.token0 && toToken === pool.token1;
28
+ const reverse = fromToken === pool.token1 && toToken === pool.token0;
29
+ if (!forward && !reverse)
30
+ return null;
31
+ const reserveIn = forward ? pool.reserve0 : pool.reserve1;
32
+ const reserveOut = forward ? pool.reserve1 : pool.reserve0;
33
+ const feeBps = pool.feeBps ?? defaultFeeBps;
34
+ const amountOut = amountOutForExactIn(amountIn, reserveIn, reserveOut, feeBps);
35
+ if (amountOut <= 0)
36
+ return null;
37
+ return {
38
+ amountOut,
39
+ midPriceOut: reserveOut / reserveIn,
40
+ metadata: { reserveIn, reserveOut, feeBps },
41
+ };
42
+ },
43
+ };
44
+ }
45
+ export function enumerateConstantProductExactInRoutes(request) {
46
+ return enumerateExactInRoutes({
47
+ pools: request.pools,
48
+ adapter: createConstantProductAdapter(request.defaultFeeBps),
49
+ fromToken: request.fromToken,
50
+ toToken: request.toToken,
51
+ amountIn: request.amountIn,
52
+ maxHops: request.maxHops,
53
+ });
54
+ }
55
+ export function selectBestConstantProductExactInRoute(request) {
56
+ return selectBestExactInRoute({
57
+ pools: request.pools,
58
+ adapter: createConstantProductAdapter(request.defaultFeeBps),
59
+ fromToken: request.fromToken,
60
+ toToken: request.toToken,
61
+ amountIn: request.amountIn,
62
+ maxHops: request.maxHops,
63
+ });
64
+ }
65
+ //# sourceMappingURL=constant-product.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constant-product.js","sourceRoot":"","sources":["../src/constant-product.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ export interface XianDatetime {
2
+ __time__: [number, number, number, number, number, number, number];
3
+ }
4
+ export interface ContractCallPlan {
5
+ contract: string;
6
+ function: string;
7
+ kwargs: Record<string, unknown>;
8
+ }
9
+ export interface ExactInExecutionAdapter<Quote, Options, Metadata = unknown> {
10
+ amountIn(quote: Quote): number;
11
+ amountOut(quote: Quote): number;
12
+ sourceToken(quote: Quote): string;
13
+ approvalSpender(options: Options): string;
14
+ buildSwapCall(args: {
15
+ quote: Quote;
16
+ recipient: string;
17
+ amountOutMin: number;
18
+ deadline: XianDatetime;
19
+ options: Options;
20
+ }): {
21
+ call: ContractCallPlan;
22
+ metadata: Metadata;
23
+ };
24
+ buildApprovalCall(args: {
25
+ token: string;
26
+ spender: string;
27
+ amount: number;
28
+ options: Options;
29
+ }): ContractCallPlan;
30
+ }
31
+ export interface ExactInSwapPlanRequest<Quote, Options, Metadata = unknown> {
32
+ quote: Quote;
33
+ recipient: string;
34
+ slippageBps: number;
35
+ deadline: XianDatetime;
36
+ adapter: ExactInExecutionAdapter<Quote, Options, Metadata>;
37
+ options: Options;
38
+ }
39
+ export interface ExactInSwapPlan<Metadata = unknown> {
40
+ call: ContractCallPlan;
41
+ amountOutMin: number;
42
+ adapterMetadata: Metadata;
43
+ }
44
+ export interface ExactInExecutionPlanRequest<Quote, Options, Metadata = unknown> extends ExactInSwapPlanRequest<Quote, Options, Metadata> {
45
+ allowance: number;
46
+ approvalAmount?: number;
47
+ }
48
+ export interface ExactInExecutionPlan<Metadata = unknown> extends ExactInSwapPlan<Metadata> {
49
+ approval: ContractCallPlan | null;
50
+ calls: ContractCallPlan[];
51
+ }
52
+ export declare function minimumAmountOut(amountOut: number, slippageBps: number): number;
53
+ export declare function deadlineFromDate(date: Date): XianDatetime;
54
+ export declare function deadlineFromNow(minutesFromNow: number, now?: number | Date): XianDatetime;
55
+ export declare function requiresApproval(allowance: number, amountIn: number): boolean;
56
+ export declare function planExactInSwap<Quote, Options, Metadata = unknown>(request: ExactInSwapPlanRequest<Quote, Options, Metadata>): ExactInSwapPlan<Metadata>;
57
+ export declare function planExactInExecution<Quote, Options, Metadata = unknown>(request: ExactInExecutionPlanRequest<Quote, Options, Metadata>): ExactInExecutionPlan<Metadata>;
58
+ //# sourceMappingURL=execution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../src/execution.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ function assertNonEmpty(value, label) {
2
+ if (value.trim().length === 0)
3
+ throw new RangeError(`${label} must not be empty`);
4
+ }
5
+ function assertFiniteNonNegative(value, label) {
6
+ if (!Number.isFinite(value) || value < 0) {
7
+ throw new RangeError(`${label} must be a finite non-negative number`);
8
+ }
9
+ }
10
+ function assertFinitePositive(value, label) {
11
+ if (!Number.isFinite(value) || value <= 0) {
12
+ throw new RangeError(`${label} must be a finite positive number`);
13
+ }
14
+ }
15
+ function assertBps(value, label) {
16
+ if (!Number.isInteger(value) || value < 0 || value > 10_000) {
17
+ throw new RangeError(`${label} must be an integer from 0 to 10000`);
18
+ }
19
+ }
20
+ export function minimumAmountOut(amountOut, slippageBps) {
21
+ assertFiniteNonNegative(amountOut, "amountOut");
22
+ assertBps(slippageBps, "slippageBps");
23
+ return amountOut * (1 - slippageBps / 10_000);
24
+ }
25
+ export function deadlineFromDate(date) {
26
+ if (!Number.isFinite(date.getTime()))
27
+ throw new RangeError("deadline date must be valid");
28
+ return {
29
+ __time__: [
30
+ date.getUTCFullYear(),
31
+ date.getUTCMonth() + 1,
32
+ date.getUTCDate(),
33
+ date.getUTCHours(),
34
+ date.getUTCMinutes(),
35
+ date.getUTCSeconds(),
36
+ date.getUTCMilliseconds() * 1_000,
37
+ ],
38
+ };
39
+ }
40
+ export function deadlineFromNow(minutesFromNow, now = Date.now()) {
41
+ assertFiniteNonNegative(minutesFromNow, "minutesFromNow");
42
+ const nowMs = now instanceof Date ? now.getTime() : now;
43
+ if (!Number.isFinite(nowMs))
44
+ throw new RangeError("now must be a valid date or timestamp");
45
+ return deadlineFromDate(new Date(nowMs + minutesFromNow * 60_000));
46
+ }
47
+ export function requiresApproval(allowance, amountIn) {
48
+ assertFiniteNonNegative(allowance, "allowance");
49
+ assertFinitePositive(amountIn, "amountIn");
50
+ return allowance < amountIn;
51
+ }
52
+ export function planExactInSwap(request) {
53
+ assertNonEmpty(request.recipient, "recipient");
54
+ const amountIn = request.adapter.amountIn(request.quote);
55
+ const amountOut = request.adapter.amountOut(request.quote);
56
+ assertFinitePositive(amountIn, "quote amountIn");
57
+ assertFiniteNonNegative(amountOut, "quote amountOut");
58
+ const amountOutMin = minimumAmountOut(amountOut, request.slippageBps);
59
+ const built = request.adapter.buildSwapCall({
60
+ quote: request.quote,
61
+ recipient: request.recipient,
62
+ amountOutMin,
63
+ deadline: request.deadline,
64
+ options: request.options,
65
+ });
66
+ return { call: built.call, amountOutMin, adapterMetadata: built.metadata };
67
+ }
68
+ export function planExactInExecution(request) {
69
+ const swap = planExactInSwap(request);
70
+ const amountIn = request.adapter.amountIn(request.quote);
71
+ const approvalNeeded = requiresApproval(request.allowance, amountIn);
72
+ const approvalAmount = request.approvalAmount ?? amountIn;
73
+ if (approvalNeeded && approvalAmount < amountIn) {
74
+ throw new RangeError("approvalAmount must cover the exact input amount");
75
+ }
76
+ const approval = approvalNeeded
77
+ ? request.adapter.buildApprovalCall({
78
+ token: request.adapter.sourceToken(request.quote),
79
+ spender: request.adapter.approvalSpender(request.options),
80
+ amount: approvalAmount,
81
+ options: request.options,
82
+ })
83
+ : null;
84
+ return {
85
+ ...swap,
86
+ approval,
87
+ calls: approval ? [approval, swap.call] : [swap.call],
88
+ };
89
+ }
90
+ //# sourceMappingURL=execution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution.js","sourceRoot":"","sources":["../src/execution.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export * from "./routing.js";
2
+ export * from "./constant-product.js";
3
+ export * from "./execution.js";
4
+ export * from "./adapters/xian-v1.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from "./routing.js";
2
+ export * from "./constant-product.js";
3
+ export * from "./execution.js";
4
+ export * from "./adapters/xian-v1.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,50 @@
1
+ export declare const DEFAULT_MAX_HOPS = 3;
2
+ export type PoolId = string | number;
3
+ export interface ExactInPoolQuote<HopMetadata = unknown> {
4
+ amountOut: number;
5
+ /** Output tokens per input token before price impact and fees. */
6
+ midPriceOut: number;
7
+ metadata: HopMetadata;
8
+ }
9
+ export interface ExactInRoutingAdapter<Pool, Id extends PoolId, HopMetadata = unknown> {
10
+ poolId(pool: Pool): Id;
11
+ tokens(pool: Pool): readonly [string, string];
12
+ quoteExactIn(args: {
13
+ pool: Pool;
14
+ fromToken: string;
15
+ toToken: string;
16
+ amountIn: number;
17
+ }): ExactInPoolQuote<HopMetadata> | null;
18
+ comparePoolIds?(left: Id, right: Id): number;
19
+ }
20
+ export interface ExactInQuoteHop<Id extends PoolId, HopMetadata = unknown> {
21
+ poolId: Id;
22
+ fromToken: string;
23
+ toToken: string;
24
+ amountIn: number;
25
+ amountOut: number;
26
+ metadata: HopMetadata;
27
+ }
28
+ export interface ExactInQuote<Id extends PoolId = PoolId, HopMetadata = unknown> {
29
+ amountIn: number;
30
+ amountOut: number;
31
+ hops: ExactInQuoteHop<Id, HopMetadata>[];
32
+ path: Id[];
33
+ /** Fractional loss versus the route's spot mid-price, including route fees. */
34
+ priceImpact: number;
35
+ /** Output tokens per input token at the route's zero-impact spot price. */
36
+ midPriceOut: number;
37
+ }
38
+ export interface ExactInQuoteRequest<Pool, Id extends PoolId, HopMetadata = unknown> {
39
+ pools: readonly Pool[];
40
+ adapter: ExactInRoutingAdapter<Pool, Id, HopMetadata>;
41
+ fromToken: string;
42
+ toToken: string;
43
+ amountIn: number;
44
+ maxHops?: number;
45
+ }
46
+ export declare function calculatePriceImpact(amountIn: number, amountOut: number, midPriceOut: number): number;
47
+ /** Enumerate viable simple routes using caller-supplied pool and quote semantics. */
48
+ export declare function enumerateExactInRoutes<Pool, Id extends PoolId, HopMetadata = unknown>(request: ExactInQuoteRequest<Pool, Id, HopMetadata>): ExactInQuote<Id, HopMetadata>[];
49
+ export declare function selectBestExactInRoute<Pool, Id extends PoolId, HopMetadata = unknown>(request: ExactInQuoteRequest<Pool, Id, HopMetadata>): ExactInQuote<Id, HopMetadata> | null;
50
+ //# sourceMappingURL=routing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../src/routing.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAErC,MAAM,WAAW,gBAAgB,CAAC,WAAW,GAAG,OAAO;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,WAAW,CAAC;CACvB;AAED,MAAM,WAAW,qBAAqB,CACpC,IAAI,EACJ,EAAE,SAAS,MAAM,EACjB,WAAW,GAAG,OAAO;IAErB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC;IACvB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,YAAY,CAAC,IAAI,EAAE;QACjB,IAAI,EAAE,IAAI,CAAC;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,gBAAgB,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;IACzC,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,GAAG,MAAM,CAAC;CAC9C;AAED,MAAM,WAAW,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,WAAW,GAAG,OAAO;IACvE,MAAM,EAAE,EAAE,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,WAAW,CAAC;CACvB;AAED,MAAM,WAAW,YAAY,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,EAAE,WAAW,GAAG,OAAO;IAC7E,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,eAAe,CAAC,EAAE,EAAE,WAAW,CAAC,EAAE,CAAC;IACzC,IAAI,EAAE,EAAE,EAAE,CAAC;IACX,+EAA+E;IAC/E,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB,CAClC,IAAI,EACJ,EAAE,SAAS,MAAM,EACjB,WAAW,GAAG,OAAO;IAErB,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IACvB,OAAO,EAAE,qBAAqB,CAAC,IAAI,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA2JD,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,MAAM,CAGR;AAqDD,qFAAqF;AACrF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,EAAE,SAAS,MAAM,EAAE,WAAW,GAAG,OAAO,EACnF,OAAO,EAAE,mBAAmB,CAAC,IAAI,EAAE,EAAE,EAAE,WAAW,CAAC,GAClD,YAAY,CAAC,EAAE,EAAE,WAAW,CAAC,EAAE,CA+BjC;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,EAAE,SAAS,MAAM,EAAE,WAAW,GAAG,OAAO,EACnF,OAAO,EAAE,mBAAmB,CAAC,IAAI,EAAE,EAAE,EAAE,WAAW,CAAC,GAClD,YAAY,CAAC,EAAE,EAAE,WAAW,CAAC,GAAG,IAAI,CAEtC"}
@@ -0,0 +1,192 @@
1
+ export const DEFAULT_MAX_HOPS = 3;
2
+ function assertNonEmpty(value, label) {
3
+ if (value.trim().length === 0)
4
+ throw new RangeError(`${label} must not be empty`);
5
+ }
6
+ function assertFinitePositive(value, label) {
7
+ if (!Number.isFinite(value) || value <= 0) {
8
+ throw new RangeError(`${label} must be a finite positive number`);
9
+ }
10
+ }
11
+ function compareStrings(left, right) {
12
+ return left < right ? -1 : left > right ? 1 : 0;
13
+ }
14
+ function defaultComparePoolIds(left, right) {
15
+ if (typeof left === "number" && typeof right === "number")
16
+ return left - right;
17
+ const leftKey = `${typeof left}:${String(left)}`;
18
+ const rightKey = `${typeof right}:${String(right)}`;
19
+ return compareStrings(leftKey, rightKey);
20
+ }
21
+ function compareIdLists(left, right, compare) {
22
+ const sharedLength = Math.min(left.length, right.length);
23
+ for (let index = 0; index < sharedLength; index += 1) {
24
+ const leftValue = left[index];
25
+ const rightValue = right[index];
26
+ if (leftValue === undefined || rightValue === undefined)
27
+ continue;
28
+ const result = compare(leftValue, rightValue);
29
+ if (result !== 0)
30
+ return result;
31
+ }
32
+ return left.length - right.length;
33
+ }
34
+ function poolIdentity(id) {
35
+ return `${typeof id}:${String(id)}`;
36
+ }
37
+ function buildAdjacency(pools, adapter) {
38
+ const adjacency = new Map();
39
+ const seenPoolIds = new Set();
40
+ const compareIds = adapter.comparePoolIds ?? defaultComparePoolIds;
41
+ const sortedPools = [...pools].sort((left, right) => {
42
+ const idComparison = compareIds(adapter.poolId(left), adapter.poolId(right));
43
+ if (idComparison !== 0)
44
+ return idComparison;
45
+ const [left0, left1] = adapter.tokens(left);
46
+ const [right0, right1] = adapter.tokens(right);
47
+ return compareStrings(left0, right0) || compareStrings(left1, right1);
48
+ });
49
+ const push = (token, edge) => {
50
+ const edges = adjacency.get(token);
51
+ if (edges)
52
+ edges.push(edge);
53
+ else
54
+ adjacency.set(token, [edge]);
55
+ };
56
+ for (const pool of sortedPools) {
57
+ const id = adapter.poolId(pool);
58
+ if ((typeof id === "string" && id.length === 0) ||
59
+ (typeof id === "number" && !Number.isFinite(id))) {
60
+ throw new RangeError("pool ids must be non-empty strings or finite numbers");
61
+ }
62
+ const identity = poolIdentity(id);
63
+ if (seenPoolIds.has(identity))
64
+ throw new RangeError(`duplicate pool id ${String(id)}`);
65
+ seenPoolIds.add(identity);
66
+ const [token0, token1] = adapter.tokens(pool);
67
+ assertNonEmpty(token0, `pool ${String(id)} token0`);
68
+ assertNonEmpty(token1, `pool ${String(id)} token1`);
69
+ if (token0 === token1) {
70
+ throw new RangeError(`pool ${String(id)} must contain two different tokens`);
71
+ }
72
+ push(token0, { pool, poolId: id, other: token1 });
73
+ push(token1, { pool, poolId: id, other: token0 });
74
+ }
75
+ for (const edges of adjacency.values()) {
76
+ edges.sort((left, right) => compareIds(left.poolId, right.poolId) || compareStrings(left.other, right.other));
77
+ }
78
+ return adjacency;
79
+ }
80
+ function enumerateCandidates(adjacency, fromToken, toToken, maxHops, compareIds) {
81
+ const candidates = [];
82
+ const visitedTokens = new Set([fromToken]);
83
+ const usedPools = new Set();
84
+ const visit = (current, route) => {
85
+ if (route.poolIds.length > 0 && current === toToken) {
86
+ candidates.push({
87
+ poolIds: [...route.poolIds],
88
+ tokens: [...route.tokens],
89
+ edges: [...route.edges],
90
+ });
91
+ return;
92
+ }
93
+ if (route.poolIds.length >= maxHops)
94
+ return;
95
+ for (const edge of adjacency.get(current) ?? []) {
96
+ const identity = poolIdentity(edge.poolId);
97
+ if (usedPools.has(identity))
98
+ continue;
99
+ if (visitedTokens.has(edge.other) && edge.other !== toToken)
100
+ continue;
101
+ usedPools.add(identity);
102
+ visitedTokens.add(edge.other);
103
+ route.poolIds.push(edge.poolId);
104
+ route.tokens.push(edge.other);
105
+ route.edges.push(edge);
106
+ visit(edge.other, route);
107
+ route.edges.pop();
108
+ route.tokens.pop();
109
+ route.poolIds.pop();
110
+ usedPools.delete(identity);
111
+ if (edge.other !== toToken)
112
+ visitedTokens.delete(edge.other);
113
+ }
114
+ };
115
+ visit(fromToken, { poolIds: [], tokens: [fromToken], edges: [] });
116
+ return candidates.sort((left, right) => left.poolIds.length - right.poolIds.length ||
117
+ compareIdLists(left.poolIds, right.poolIds, compareIds) ||
118
+ compareStrings(left.tokens.join("\u0000"), right.tokens.join("\u0000")));
119
+ }
120
+ export function calculatePriceImpact(amountIn, amountOut, midPriceOut) {
121
+ if (amountIn <= 0 || amountOut <= 0 || midPriceOut <= 0)
122
+ return 0;
123
+ return Math.max(0, 1 - amountOut / amountIn / midPriceOut);
124
+ }
125
+ function quoteCandidate(candidate, amountIn, adapter) {
126
+ let currentAmount = amountIn;
127
+ let midPriceOut = 1;
128
+ const hops = [];
129
+ for (let index = 0; index < candidate.edges.length; index += 1) {
130
+ const edge = candidate.edges[index];
131
+ const fromToken = candidate.tokens[index];
132
+ const toToken = candidate.tokens[index + 1];
133
+ if (!edge || fromToken === undefined || toToken === undefined)
134
+ return null;
135
+ const quoted = adapter.quoteExactIn({
136
+ pool: edge.pool,
137
+ fromToken,
138
+ toToken,
139
+ amountIn: currentAmount,
140
+ });
141
+ if (quoted === null ||
142
+ !Number.isFinite(quoted.amountOut) ||
143
+ !Number.isFinite(quoted.midPriceOut) ||
144
+ quoted.amountOut <= 0 ||
145
+ quoted.midPriceOut <= 0) {
146
+ return null;
147
+ }
148
+ hops.push({
149
+ poolId: edge.poolId,
150
+ fromToken,
151
+ toToken,
152
+ amountIn: currentAmount,
153
+ amountOut: quoted.amountOut,
154
+ metadata: quoted.metadata,
155
+ });
156
+ midPriceOut *= quoted.midPriceOut;
157
+ currentAmount = quoted.amountOut;
158
+ }
159
+ return {
160
+ amountIn,
161
+ amountOut: currentAmount,
162
+ hops,
163
+ path: [...candidate.poolIds],
164
+ priceImpact: calculatePriceImpact(amountIn, currentAmount, midPriceOut),
165
+ midPriceOut,
166
+ };
167
+ }
168
+ /** Enumerate viable simple routes using caller-supplied pool and quote semantics. */
169
+ export function enumerateExactInRoutes(request) {
170
+ assertNonEmpty(request.fromToken, "fromToken");
171
+ assertNonEmpty(request.toToken, "toToken");
172
+ assertFinitePositive(request.amountIn, "amountIn");
173
+ const maxHops = request.maxHops ?? DEFAULT_MAX_HOPS;
174
+ if (!Number.isInteger(maxHops) || maxHops <= 0) {
175
+ throw new RangeError("maxHops must be a positive integer");
176
+ }
177
+ if (request.fromToken === request.toToken)
178
+ return [];
179
+ const compareIds = request.adapter.comparePoolIds ?? defaultComparePoolIds;
180
+ const candidates = enumerateCandidates(buildAdjacency(request.pools, request.adapter), request.fromToken, request.toToken, maxHops, compareIds);
181
+ return candidates
182
+ .map((candidate) => quoteCandidate(candidate, request.amountIn, request.adapter))
183
+ .filter((quote) => quote !== null)
184
+ .sort((left, right) => right.amountOut - left.amountOut ||
185
+ left.path.length - right.path.length ||
186
+ compareIdLists(left.path, right.path, compareIds) ||
187
+ compareStrings(left.hops.map((hop) => hop.toToken).join("\u0000"), right.hops.map((hop) => hop.toToken).join("\u0000")));
188
+ }
189
+ export function selectBestExactInRoute(request) {
190
+ return enumerateExactInRoutes(request)[0] ?? null;
191
+ }
192
+ //# sourceMappingURL=routing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing.js","sourceRoot":"","sources":["../src/routing.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@xian-tech/dex",
3
+ "version": "0.2.0",
4
+ "description": "Deterministic Xian DEX quoting and transaction planning",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/xian-technology/xian-js.git",
10
+ "directory": "packages/dex"
11
+ },
12
+ "type": "module",
13
+ "sideEffects": false,
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.js",
18
+ "default": "./dist/index.js"
19
+ },
20
+ "./routing": {
21
+ "types": "./dist/routing.d.ts",
22
+ "import": "./dist/routing.js",
23
+ "default": "./dist/routing.js"
24
+ },
25
+ "./constant-product": {
26
+ "types": "./dist/constant-product.d.ts",
27
+ "import": "./dist/constant-product.js",
28
+ "default": "./dist/constant-product.js"
29
+ },
30
+ "./execution": {
31
+ "types": "./dist/execution.d.ts",
32
+ "import": "./dist/execution.js",
33
+ "default": "./dist/execution.js"
34
+ },
35
+ "./adapters/xian-v1": {
36
+ "types": "./dist/adapters/xian-v1.d.ts",
37
+ "import": "./dist/adapters/xian-v1.js",
38
+ "default": "./dist/adapters/xian-v1.js"
39
+ }
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "files": [
45
+ "dist"
46
+ ],
47
+ "scripts": {
48
+ "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
49
+ "build": "npm run clean && tsc -p tsconfig.json",
50
+ "typecheck": "tsc --noEmit -p tsconfig.json"
51
+ }
52
+ }