@aegis-engine/core 0.9.1 → 0.10.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.
@@ -19,4 +19,4 @@ export declare const AEGIS_SWAP_DEFAULT_METADATA_ENDPOINT = "https://aegis.marke
19
19
  export declare const AGGREGATED_SWAP_FEE_BPS = 50;
20
20
  export declare const AGGREGATED_SWAP_FEE_RECIPIENT: `0x${string}`;
21
21
  export declare const AGGREGATED_SWAP_KYBER_ROUTER: `0x${string}`;
22
- export declare const AGGREGATED_SWAP_SUPPORTED_CHAIN_IDS: readonly [1];
22
+ export declare const AGGREGATED_SWAP_SUPPORTED_CHAIN_IDS: readonly [1, 56, 130, 8453];
@@ -49,6 +49,8 @@ export declare function buildExactOutSwapTransaction(args: {
49
49
  poolKey: AegisPoolKey;
50
50
  zeroForOne: boolean;
51
51
  amountOut: bigint;
52
+ /** Required net payout. Defaults to gross amountOut minus the configured fee. */
53
+ amountOutNet?: bigint;
52
54
  amountInMaximum: bigint;
53
55
  recipient: Address;
54
56
  deadline: bigint;
package/dist/index.d.ts CHANGED
@@ -4,12 +4,14 @@ export { assertUint128, buildExactInSwapTransaction, buildExactOutSwapTransactio
4
4
  export type { BuiltSwapTransaction, ExecutionBatch, PermitBatch, PermitDetails, SignedPermitBatch, SwapOutputFee } from './encoding.js';
5
5
  export { getZeroForOne, outputFeeForQuote, quoteSpendAmount, reconcileSubmitQuote, sameQuote } from './quote.js';
6
6
  export type { DirectSwapQuote, ReconciledSubmitQuote, SwapQuoteMode } from './quote.js';
7
- export { AggregatedSwapBuildMismatchError, aggregatedSwapErrorMessage, fetchAggregatedSwapQuote } from './quote/aggregatedSwapQuote.js';
7
+ export { AggregatedSwapBuildMismatchError, aggregatedSwapErrorMessage, assertAggregatedQuoteLiquidity, fetchAggregatedSwapQuote } from './quote/aggregatedSwapQuote.js';
8
+ export { NoAegisRouteError, assertAegisOnlyRouteLegs } from './quote/routeProvider.js';
9
+ export type { NoAegisRouteReason } from './quote/routeProvider.js';
8
10
  export type { AggregatedSwapExecutionIntent } from './quote/aggregatedSwapQuote.js';
9
11
  export { AggregatedSwapCalldataError } from './quote/kyberCalldata.js';
10
12
  export type { AggregatedSwapQuote, AggregatedSwapRoute, HopInfo } from './types/aggregatedSwap.js';
11
- export { KyberSwapApiError, KyberSwapContractError, KyberSwapResourceLimitError, buildKyberSwapRoute, fetchKyberSwapRoute, isRetryableKyberSwapError } from './services/kyberSwap.js';
12
- export type { KyberSwapBuild, KyberSwapError, KyberSwapFeeParams, KyberSwapRoute, KyberSwapRouteLeg, KyberSwapRouteSummary } from './services/kyberSwap.js';
13
+ export { KYBER_AEGIS_LIQUIDITY_SOURCE, KyberSwapApiError, KyberSwapContractError, KyberSwapResourceLimitError, buildKyberSwapRoute, fetchKyberSwapRoute, isRetryableKyberSwapError } from './services/kyberSwap.js';
14
+ export type { AggregatedSwapLiquiditySources, KyberSwapBuild, KyberSwapError, KyberSwapFeeParams, KyberSwapRoute, KyberSwapRouteLeg, KyberSwapRouteSummary } from './services/kyberSwap.js';
13
15
  export { approveErc20Spender, approveErc20ToPermit2, approvePermit2ToRouter, buildSignedPermitBatch, DEFAULT_PERMIT_EXPIRATION_SECONDS, hasUsablePermit2Allowance, isUnlimitedErc20Approval, isUnlimitedPermit2Approval, MAX_UINT160, MAX_UINT256, PERMIT2_FAR_FUTURE_EXPIRATION, readErc20Allowance, readPermit2RouterAllowance, SWAP_TX_DEADLINE_SECONDS, UNLIMITED_ERC20_FLOOR, UNLIMITED_PERMIT2_FLOOR } from './permit.js';
14
16
  export { fetchGlobalTokenMetadata, resolveTokenIconUrl } from './metadata.js';
15
17
  export type { AegisSwapGlobalTokenMetadata, TokenMetadataByAddress } from './metadata.js';
@@ -1,6 +1,7 @@
1
1
  import { type Address, type PublicClient } from 'viem';
2
2
  import { type AegisSwapToken } from '../config/index.js';
3
3
  import { UserFacingError } from '../errors.js';
4
+ import { type AggregatedSwapLiquiditySources } from '../services/kyberSwap.js';
4
5
  import type { AggregatedSwapQuote } from '../types/aggregatedSwap.js';
5
6
  export declare function aggregatedSwapErrorMessage(error: unknown, fallbackMessage: string): string;
6
7
  export declare class AggregatedSwapBuildMismatchError extends UserFacingError {
@@ -18,4 +19,12 @@ export type AggregatedSwapExecutionIntent = Readonly<{
18
19
  reviewedAmountOutMinimum: bigint;
19
20
  }>;
20
21
  export declare function assertAggregatedRouterTrusted(router: Address, chainId: number): void;
21
- export declare function fetchAggregatedSwapQuote(inputToken: AegisSwapToken, outputToken: AegisSwapToken, amount: bigint, slippageBps: number, mode?: 'exactIn' | 'exactOut', account?: Address | null, signal?: AbortSignal, _publicClient?: PublicClient, executionIntent?: AggregatedSwapExecutionIntent): Promise<AggregatedSwapQuote>;
22
+ /**
23
+ * Re-checks, immediately before signing, that an executable quote was built
24
+ * under Aegis-only routing and that every hop it reports is an Aegis pool.
25
+ * Host-constructed quotes without the commitment fail closed.
26
+ */
27
+ export declare function assertAggregatedQuoteLiquidity(quote: Pick<AggregatedSwapQuote, 'hops' | 'liquiditySources'>, liquiditySources: AggregatedSwapLiquiditySources): void;
28
+ export declare function fetchAggregatedSwapQuote(inputToken: AegisSwapToken, outputToken: AegisSwapToken, amount: bigint, slippageBps: number, mode?: 'exactIn' | 'exactOut', account?: Address | null, signal?: AbortSignal, _publicClient?: PublicClient, executionIntent?: AggregatedSwapExecutionIntent, options?: {
29
+ liquiditySources?: AggregatedSwapLiquiditySources;
30
+ }): Promise<AggregatedSwapQuote>;
@@ -0,0 +1,54 @@
1
+ import type { Address } from 'viem';
2
+ import { UserFacingError } from '../errors.js';
3
+ import { type AggregatedSwapLiquiditySources, type KyberSwapBuild, type KyberSwapFeeParams, type KyberSwapRoute, type KyberSwapRouteSummary } from '../services/kyberSwap.js';
4
+ import { assertKyberCalldataMatchesQuote } from './kyberCalldata.js';
5
+ export type NoAegisRouteReason = 'no-route' | 'non-aegis-leg';
6
+ /**
7
+ * Aegis-only routing found no executable path. `reason` separates "the
8
+ * provider has no all-Aegis path" from "the provider answered with a path that
9
+ * leaves Aegis pools", which is refused rather than trusted.
10
+ */
11
+ export declare class NoAegisRouteError extends UserFacingError {
12
+ readonly reason: NoAegisRouteReason;
13
+ readonly detail?: string;
14
+ constructor(reason: NoAegisRouteReason, detail?: string);
15
+ }
16
+ /**
17
+ * Fails closed unless the route is non-empty and every hop of every split is
18
+ * tagged with Kyber's Aegis source. The tag is Kyber's own attribution; there
19
+ * is deliberately no pool-id allowlist on top of it.
20
+ */
21
+ export declare function assertAegisOnlyRouteLegs(route: KyberSwapRouteSummary['route']): void;
22
+ /** Maps a provider "no route under these sources" failure to NoAegisRouteError. */
23
+ export declare function toNoAegisRouteError(error: unknown): unknown;
24
+ /**
25
+ * Internal seam behind fetchAggregatedSwapQuote: quote → build → validate.
26
+ * KyberSwap is the only implementation. Another provider (for example an
27
+ * in-house Ink router) slots in by returning the same route/build shapes and
28
+ * its own router-specific calldata check, without UI changes.
29
+ */
30
+ export type AggregatedRouteProvider = {
31
+ readonly id: string;
32
+ trustedRouter(chainId: number): Address | undefined;
33
+ quote(args: {
34
+ chainId: number;
35
+ tokenIn: Address;
36
+ tokenOut: Address;
37
+ amountIn: bigint;
38
+ origin?: Address | null;
39
+ fee: KyberSwapFeeParams | null;
40
+ liquiditySources: AggregatedSwapLiquiditySources;
41
+ signal?: AbortSignal;
42
+ }): Promise<KyberSwapRoute>;
43
+ build(args: {
44
+ chainId: number;
45
+ route: KyberSwapRoute;
46
+ sender: Address;
47
+ recipient: Address;
48
+ slippageBps: number;
49
+ signal?: AbortSignal;
50
+ }): Promise<KyberSwapBuild>;
51
+ validateRoute(route: KyberSwapRoute, liquiditySources: AggregatedSwapLiquiditySources): void;
52
+ validateCalldata(args: Parameters<typeof assertKyberCalldataMatchesQuote>[0]): void;
53
+ };
54
+ export declare function aggregatedRouteProviderForChain(chainId: number): AggregatedRouteProvider;
package/dist/quote.d.ts CHANGED
@@ -15,13 +15,13 @@ export type DirectSwapQuote = {
15
15
  * Swap-action output floor, enforced on-chain. Semantics differ by mode:
16
16
  * - exactIn: gross floor sized so the user still nets `userAmountOutMinimum`
17
17
  * after the fee portion is taken.
18
- * - exactOut: equals `grossAmountOut` (output is fixed; the on-chain
19
- * protection is `amountInMaximum`). Informational only.
18
+ * - exactOut: equals `grossAmountOut`; the encoder separately requires the
19
+ * net payout after fees as well as enforcing `amountInMaximum`.
20
20
  */
21
21
  amountOutMinimum: bigint;
22
22
  /** exactOut: input ceiling enforced on-chain. exactIn: equals `amountIn`. */
23
23
  amountInMaximum: bigint;
24
- /** Minimum the user nets after slippage and fee. Display/reconciliation value. */
24
+ /** Minimum net receipt after slippage and fee; enforced by the swap recipe. */
25
25
  userAmountOutMinimum: bigint;
26
26
  /** Estimated widget fee in output currency (exact for exactOut, quote-time estimate for exactIn). */
27
27
  feeAmount: bigint;
@@ -3,7 +3,7 @@ var _s = (e, t, n) => t in e ? Ps(e, t, { enumerable: !0, configurable: !0, writ
3
3
  var ie = (e, t, n) => _s(e, typeof t != "symbol" ? t + "" : t, n);
4
4
  import { keccak256 as Et, zeroAddress as Ee, erc721Abi as Wt, hashTypedData as Cs, isAddress as on, erc20Abi as Or, encodeFunctionData as Dn, BaseError as ra, ContractFunctionRevertedError as Qi, numberToHex as Ms, encodeAbiParameters as Xi, parseAbiParameters as Rs, RpcRequestError as Zi, isHex as Ji, decodeErrorResult as Ss, ExecutionRevertedError as Ga, getEventSelector as Ze, getAbiItem as Je, parseAbi as aa, toEventSelector as Os } from "viem";
5
5
  import "viem/actions";
6
- import { X as ja, J as Ka } from "./transactionHistory-BhNsDpNJ.js";
6
+ import { X as ja, J as Ka } from "./transactionHistory-D3PDVGkr.js";
7
7
  class f extends Array {
8
8
  constructor(t, n) {
9
9
  if (super(t), this.sign = n, t > f.__kMaxLength) throw new RangeError("Maximum BigInt size exceeded");
@@ -55,6 +55,14 @@ export type KyberSwapBuild = {
55
55
  */
56
56
  deadline?: number;
57
57
  };
58
+ /**
59
+ * Liquidity the aggregator may route through. `'aegis'` restricts Kyber to the
60
+ * Aegis-hooked Uniswap v4 pools it indexes as {@link KYBER_AEGIS_LIQUIDITY_SOURCE};
61
+ * `'any'` leaves source selection to Kyber.
62
+ */
63
+ export type AggregatedSwapLiquiditySources = 'aegis' | 'any';
64
+ /** Kyber's liquidity-source id for Uniswap v4 pools that use the Aegis hook. */
65
+ export declare const KYBER_AEGIS_LIQUIDITY_SOURCE = "uniswap-v4-aegis";
58
66
  export type KyberSwapError = {
59
67
  code?: number;
60
68
  message?: string;
@@ -93,13 +101,15 @@ export declare class KyberSwapResourceLimitError extends Error {
93
101
  });
94
102
  }
95
103
  export declare function isRetryableKyberSwapError(error: unknown): boolean;
96
- export declare function fetchKyberSwapRoute({ tokenIn, tokenOut, amountIn, chainId, origin, fee, signal, timeoutMs }: {
104
+ export declare function fetchKyberSwapRoute({ tokenIn, tokenOut, amountIn, chainId, origin, fee, liquiditySources, signal, timeoutMs }: {
97
105
  tokenIn: Address;
98
106
  tokenOut: Address;
99
107
  amountIn: string;
100
108
  chainId?: number;
101
109
  origin?: Address | null;
102
110
  fee?: KyberSwapFeeParams | null;
111
+ /** `'aegis'` sends `includedSources=uniswap-v4-aegis`; defaults to `'any'`. */
112
+ liquiditySources?: AggregatedSwapLiquiditySources;
103
113
  signal?: AbortSignal;
104
114
  /** Abort after this many ms (composes with `signal`); defaults to 20s. */
105
115
  timeoutMs?: number;