@aegis-engine/core 0.10.0 → 0.11.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.
@@ -33,8 +33,114 @@ export type BuiltSwapTransaction = {
33
33
  value: bigint;
34
34
  };
35
35
  export declare const MAX_UINT128: bigint;
36
+ export declare const AEGIS_ACTION: {
37
+ readonly SWAP_EXACT_IN_SINGLE: 6;
38
+ readonly SWAP_EXACT_IN: 7;
39
+ readonly SWAP_EXACT_OUT_SINGLE: 8;
40
+ readonly SETTLE: 11;
41
+ readonly TAKE: 14;
42
+ readonly TAKE_PORTION: 16;
43
+ readonly SWEEP: 20;
44
+ };
45
+ export declare const SWAP_EXACT_IN_ABI: readonly [{
46
+ readonly name: "params";
47
+ readonly type: "tuple";
48
+ readonly components: readonly [{
49
+ readonly name: "currencyIn";
50
+ readonly type: "address";
51
+ }, {
52
+ readonly name: "path";
53
+ readonly type: "tuple[]";
54
+ readonly components: readonly [{
55
+ readonly name: "intermediateCurrency";
56
+ readonly type: "address";
57
+ }, {
58
+ readonly name: "fee";
59
+ readonly type: "uint24";
60
+ }, {
61
+ readonly name: "tickSpacing";
62
+ readonly type: "int24";
63
+ }, {
64
+ readonly name: "hooks";
65
+ readonly type: "address";
66
+ }, {
67
+ readonly name: "hookData";
68
+ readonly type: "bytes";
69
+ }];
70
+ }, {
71
+ readonly name: "amountIn";
72
+ readonly type: "uint128";
73
+ }, {
74
+ readonly name: "amountOutMinimum";
75
+ readonly type: "uint128";
76
+ }];
77
+ }];
78
+ export declare const SETTLE_ABI: readonly [{
79
+ readonly name: "currency";
80
+ readonly type: "address";
81
+ }, {
82
+ readonly name: "amount";
83
+ readonly type: "uint256";
84
+ }, {
85
+ readonly name: "payerIsUser";
86
+ readonly type: "bool";
87
+ }];
88
+ export declare const TAKE_ABI: readonly [{
89
+ readonly name: "currency";
90
+ readonly type: "address";
91
+ }, {
92
+ readonly name: "recipient";
93
+ readonly type: "address";
94
+ }, {
95
+ readonly name: "amount";
96
+ readonly type: "uint256";
97
+ }];
98
+ export declare const TAKE_PORTION_ABI: readonly [{
99
+ readonly name: "currency";
100
+ readonly type: "address";
101
+ }, {
102
+ readonly name: "recipient";
103
+ readonly type: "address";
104
+ }, {
105
+ readonly name: "bips";
106
+ readonly type: "uint256";
107
+ }];
36
108
  export declare function assertUint128(value: bigint, label?: string): void;
37
109
  export declare function computePoolId(poolKey: AegisPoolKey): Hex;
110
+ /** One hop of an exact-input path: the pool and the currency it pays out. */
111
+ export type AegisPathHop = {
112
+ poolKey: AegisPoolKey;
113
+ currencyOut: Address;
114
+ };
115
+ /** V4 PathKeys for a hop list; the quoter and the router read the same shape. */
116
+ export declare function v4PathKeys(path: readonly AegisPathHop[]): {
117
+ intermediateCurrency: `0x${string}`;
118
+ fee: number;
119
+ tickSpacing: number;
120
+ hooks: `0x${string}`;
121
+ hookData: Hex;
122
+ }[];
123
+ /**
124
+ * Multi-hop exact input through the deployed Aegis router: SWAP_EXACT_IN,
125
+ * SETTLE, optional fee TAKE_PORTION, a fixed TAKE of the net minimum (reverts
126
+ * the whole swap on a shortfall), then TAKE(OPEN_DELTA) for any surplus.
127
+ */
128
+ export declare function buildExactInPathTransaction(args: {
129
+ currencyIn: Address;
130
+ path: readonly AegisPathHop[];
131
+ amountIn: bigint;
132
+ /** Gross floor for the swap action, before the fee portion. */
133
+ amountOutMinimum: bigint;
134
+ /** Net payout the recipient must receive after the fee. */
135
+ amountOutNetMinimum: bigint;
136
+ recipient: Address;
137
+ deadline: bigint;
138
+ permit?: SignedPermitBatch | null;
139
+ fee?: {
140
+ recipient: Address;
141
+ bips: number;
142
+ } | null;
143
+ }): BuiltSwapTransaction;
38
144
  export declare function buildExactInSwapTransaction(args: {
39
145
  poolKey: AegisPoolKey;
40
146
  zeroForOne: boolean;
@@ -0,0 +1,43 @@
1
+ import { type Address, type PublicClient } from 'viem';
2
+ import { type TrustedSwapPool } from '../swap/trustedMarket.js';
3
+ import { type AggregatedRouteProvider } from './routeProvider.js';
4
+ /** Canonical Multicall3; its runtime code is live on Ink (57073). */
5
+ export declare const MULTICALL3_ADDRESS: Address;
6
+ export declare const AEGIS_ROUTE_MAX_HOPS = 3;
7
+ type AegisRouteLeg = {
8
+ pool: TrustedSwapPool;
9
+ currencyIn: Address;
10
+ currencyOut: Address;
11
+ };
12
+ export type AegisRouteCandidate = readonly AegisRouteLeg[];
13
+ export type AegisRouteQuote = {
14
+ route: AegisRouteCandidate;
15
+ /** Gross pool output, before the app fee. */
16
+ amountOut: bigint;
17
+ gasEstimate: bigint;
18
+ };
19
+ /**
20
+ * Every simple exact-input path of one to three hops between two tokens, over
21
+ * the chain's shipped pool catalogue only. Breadth-first, so the direct pool
22
+ * comes first and shorter paths survive the candidate cap.
23
+ */
24
+ export declare function enumerateAegisRoutes(chainId: number, tokenIn: Address, tokenOut: Address, maxCandidates?: number): AegisRouteCandidate[];
25
+ /**
26
+ * Quotes every candidate in ONE eth_call: Multicall3 `aggregate3` with
27
+ * `allowFailure` over V4Quoter `quoteExactInput`, plus Multicall3's own
28
+ * `getBlockNumber`, so all results (and the block they share) come from one
29
+ * state. A failed or malformed sub-call yields `null` for that candidate.
30
+ */
31
+ export declare function quoteAegisRoutes(publicClient: Pick<PublicClient, 'call'>, routes: readonly AegisRouteCandidate[], amountIn: bigint): Promise<{
32
+ blockNumber: bigint;
33
+ quotes: (AegisRouteQuote | null)[];
34
+ }>;
35
+ /** Highest gross output; ties keep the earlier (shorter) candidate. */
36
+ export declare function bestAegisRouteQuote(quotes: readonly (AegisRouteQuote | null)[]): AegisRouteQuote | null;
37
+ /**
38
+ * In-house provider for chains Kyber does not cover. Routes only through the
39
+ * shipped pool catalogue and settles on the deployed Aegis router, whose
40
+ * input is pulled through Permit2.
41
+ */
42
+ export declare function createAegisRouteProvider(chainId: number): AggregatedRouteProvider;
43
+ export {};
@@ -1,5 +1,6 @@
1
1
  import { type Address, type PublicClient } from 'viem';
2
2
  import { type AegisSwapToken } from '../config/index.js';
3
+ import type { SignedPermitBatch } from '../encoding.js';
3
4
  import { UserFacingError } from '../errors.js';
4
5
  import { type AggregatedSwapLiquiditySources } from '../services/kyberSwap.js';
5
6
  import type { AggregatedSwapQuote } from '../types/aggregatedSwap.js';
@@ -17,6 +18,8 @@ export declare class AggregatedSwapBuildMismatchError extends UserFacingError {
17
18
  /** Absolute settlement floor established by the quote the user approved. */
18
19
  export type AggregatedSwapExecutionIntent = Readonly<{
19
20
  reviewedAmountOutMinimum: bigint;
21
+ /** Signed Permit2 grant for routers that pull input through Permit2. */
22
+ permit?: SignedPermitBatch | null;
20
23
  }>;
21
24
  export declare function assertAggregatedRouterTrusted(router: Address, chainId: number): void;
22
25
  /**
@@ -25,6 +28,8 @@ export declare function assertAggregatedRouterTrusted(router: Address, chainId:
25
28
  * Host-constructed quotes without the commitment fail closed.
26
29
  */
27
30
  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?: {
31
+ export declare function fetchAggregatedSwapQuote(inputToken: AegisSwapToken, outputToken: AegisSwapToken, amount: bigint, slippageBps: number, mode?: 'exactIn' | 'exactOut', account?: Address | null, signal?: AbortSignal,
32
+ /** Read client; the on-chain Ink provider quotes through it. */
33
+ publicClient?: PublicClient, executionIntent?: AggregatedSwapExecutionIntent, options?: {
29
34
  liquiditySources?: AggregatedSwapLiquiditySources;
30
35
  }): Promise<AggregatedSwapQuote>;
@@ -1,4 +1,5 @@
1
- import type { Address } from 'viem';
1
+ import type { Address, PublicClient } from 'viem';
2
+ import type { SignedPermitBatch } from '../encoding.js';
2
3
  import { UserFacingError } from '../errors.js';
3
4
  import { type AggregatedSwapLiquiditySources, type KyberSwapBuild, type KyberSwapFeeParams, type KyberSwapRoute, type KyberSwapRouteSummary } from '../services/kyberSwap.js';
4
5
  import { assertKyberCalldataMatchesQuote } from './kyberCalldata.js';
@@ -21,15 +22,32 @@ export declare class NoAegisRouteError extends UserFacingError {
21
22
  export declare function assertAegisOnlyRouteLegs(route: KyberSwapRouteSummary['route']): void;
22
23
  /** Maps a provider "no route under these sources" failure to NoAegisRouteError. */
23
24
  export declare function toNoAegisRouteError(error: unknown): unknown;
25
+ /**
26
+ * Provider-neutral route and build shapes. Kyber's wire layout is the
27
+ * canonical one; another provider fills only the fields it can attest (an
28
+ * in-house route has no USD values, request id or route composition).
29
+ */
30
+ export type AggregatedRoute = KyberSwapRoute & {
31
+ /** Block the route was quoted at, when the provider quotes on-chain. */
32
+ blockNumber?: bigint;
33
+ };
34
+ type AggregatedRouteBuild = KyberSwapBuild;
24
35
  /**
25
36
  * 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.
37
+ * KyberSwap serves Ethereum, BSC, Unichain and Base; the in-house Aegis
38
+ * provider serves Ink, where Kyber has no coverage.
29
39
  */
30
40
  export type AggregatedRouteProvider = {
31
41
  readonly id: string;
42
+ /** Names the route source in user-facing trust errors. */
43
+ readonly label: string;
32
44
  trustedRouter(chainId: number): Address | undefined;
45
+ /**
46
+ * Set when the router pulls input through Permit2 (ERC-20 approval to
47
+ * Permit2, then a Permit2 grant to the router) rather than a direct ERC-20
48
+ * allowance to the router.
49
+ */
50
+ permit2?(chainId: number): Address | undefined;
33
51
  quote(args: {
34
52
  chainId: number;
35
53
  tokenIn: Address;
@@ -38,17 +56,24 @@ export type AggregatedRouteProvider = {
38
56
  origin?: Address | null;
39
57
  fee: KyberSwapFeeParams | null;
40
58
  liquiditySources: AggregatedSwapLiquiditySources;
59
+ /** Read client for providers that quote on-chain. */
60
+ publicClient?: PublicClient;
41
61
  signal?: AbortSignal;
42
- }): Promise<KyberSwapRoute>;
62
+ }): Promise<AggregatedRoute>;
43
63
  build(args: {
44
64
  chainId: number;
45
- route: KyberSwapRoute;
65
+ route: AggregatedRoute;
46
66
  sender: Address;
47
67
  recipient: Address;
48
68
  slippageBps: number;
69
+ /** Absolute net floor the calldata must enforce (Kyber derives it from slippageBps). */
70
+ amountOutMinimum: bigint;
71
+ /** Signed Permit2 grant to embed, for Permit2 providers. */
72
+ permit?: SignedPermitBatch | null;
49
73
  signal?: AbortSignal;
50
- }): Promise<KyberSwapBuild>;
51
- validateRoute(route: KyberSwapRoute, liquiditySources: AggregatedSwapLiquiditySources): void;
74
+ }): Promise<AggregatedRouteBuild>;
75
+ validateRoute(route: AggregatedRoute, liquiditySources: AggregatedSwapLiquiditySources): void;
52
76
  validateCalldata(args: Parameters<typeof assertKyberCalldataMatchesQuote>[0]): void;
53
77
  };
54
78
  export declare function aggregatedRouteProviderForChain(chainId: number): AggregatedRouteProvider;
79
+ export {};
@@ -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-D3PDVGkr.js";
6
+ import { X as ja, J as Ka } from "./transactionHistory-B-F6o9hW.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");
@@ -1,3 +1,4 @@
1
+ import { type Address, type Hex } from 'viem';
1
2
  import type { AegisPoolKey, AegisSwapMarket } from '../config/index.js';
2
3
  import { UserFacingError } from '../errors.js';
3
4
  /**
@@ -10,6 +11,19 @@ import { UserFacingError } from '../errors.js';
10
11
  * reviewed SDK release.
11
12
  */
12
13
  export declare const DIRECT_SWAP_MARKET_TRUST_RULE_ID: "DIRECT-MARKET-001";
14
+ type TrustedTokenIdentity = {
15
+ address: Address;
16
+ decimals: number;
17
+ };
18
+ type TrustedDirectSwapMarketIdentity = {
19
+ chainId: number;
20
+ poolId: Hex;
21
+ poolKey: AegisPoolKey;
22
+ tokens: readonly [TrustedTokenIdentity, TrustedTokenIdentity];
23
+ router: Address;
24
+ permit2: Address;
25
+ quoter: Address;
26
+ };
13
27
  export declare class DirectSwapMarketTrustError extends UserFacingError {
14
28
  readonly ruleId: "DIRECT-MARKET-001";
15
29
  constructor(detail?: string);
@@ -23,3 +37,12 @@ export declare function assertDirectSwapPoolKeyMatchesMarket(market: AegisSwapMa
23
37
  * object is the same identity that Core must receive at quote and send time.
24
38
  */
25
39
  export declare function authorizeHostDirectSwapMarket<T extends AegisSwapMarket>(market: T): T;
40
+ /** A reviewed pool from the shipped catalogue, as multi-hop routing sees it. */
41
+ export type TrustedSwapPool = Pick<TrustedDirectSwapMarketIdentity, 'chainId' | 'poolId' | 'poolKey' | 'router' | 'permit2' | 'quoter'>;
42
+ /**
43
+ * DIRECT-MARKET-001 applied to routed swaps: the only pools a multi-hop route
44
+ * may touch are the shipped catalogue's pools on that chain. Host-authorized
45
+ * markets are deliberately excluded; routing never widens the catalogue.
46
+ */
47
+ export declare function trustedSwapPoolsForChain(chainId: number): readonly TrustedSwapPool[];
48
+ export {};
@@ -6908,10 +6908,10 @@ export {
6908
6908
  fd as Q,
6909
6909
  on as R,
6910
6910
  z as S,
6911
- Yf as T,
6911
+ nh as T,
6912
6912
  Bn as U,
6913
- nh as V,
6914
- eh as W,
6913
+ eh as V,
6914
+ Yf as W,
6915
6915
  zf as X,
6916
6916
  Fl as Y,
6917
6917
  hd as Z,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aegis-engine/core",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "React-free Aegis Swap and Engine quoting, risk, approval, and execution operations.",
5
5
  "license": "MIT",
6
6
  "type": "module",