@aegis-engine/core 0.2.0 → 0.3.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.
Files changed (41) hide show
  1. package/README.md +109 -4
  2. package/THIRD_PARTY_NOTICES.md +211 -0
  3. package/dist/actions/kyberSwap.d.ts +3 -2
  4. package/dist/address.d.ts +3 -1
  5. package/dist/aegis-core.js +8421 -5279
  6. package/dist/backendAdapters.d.ts +25 -1
  7. package/dist/config/constants.d.ts +4 -0
  8. package/dist/config/types.d.ts +5 -0
  9. package/dist/contract/backendClient.d.ts +16 -6
  10. package/dist/contract/generated/aegis-swap.d.ts +2682 -96
  11. package/dist/contract/schemas.d.ts +27 -20
  12. package/dist/engine/actions.d.ts +56 -0
  13. package/dist/engine/borrowCostProjection.d.ts +1 -0
  14. package/dist/engine/dataSource.d.ts +63 -0
  15. package/dist/engine/index.d.ts +7 -0
  16. package/dist/engine/marketAdapter.d.ts +8 -0
  17. package/dist/engine/quotes.d.ts +8 -0
  18. package/dist/engine/reads.d.ts +41 -0
  19. package/dist/engine/registry.d.ts +27 -0
  20. package/dist/engine/restSchemas.d.ts +409 -0
  21. package/dist/engine/sdk.d.ts +1 -0
  22. package/dist/engine/sdkRuntime.d.ts +1 -0
  23. package/dist/engine/types.d.ts +992 -0
  24. package/dist/errors.d.ts +10 -0
  25. package/dist/historicalPrices.d.ts +78 -0
  26. package/dist/index.d.ts +13 -8
  27. package/dist/internal/requestSignal.d.ts +9 -0
  28. package/dist/internal/ttlCache.d.ts +19 -0
  29. package/dist/metadata.d.ts +4 -0
  30. package/dist/permit.d.ts +1 -0
  31. package/dist/quote/aggregatedSwapQuote.d.ts +12 -0
  32. package/dist/quote/kyberCalldata.d.ts +211 -0
  33. package/dist/quote.d.ts +1 -0
  34. package/dist/sdkRuntime-CCRVvSwD.js +16052 -0
  35. package/dist/services/kyberSwap.d.ts +22 -2
  36. package/dist/swap/receiptWait.d.ts +17 -0
  37. package/dist/swap/sendSwapTransaction.d.ts +40 -6
  38. package/dist/swap/settlement.d.ts +15 -0
  39. package/dist/transactionProgress.d.ts +8 -1
  40. package/dist/types/aggregatedSwap.d.ts +18 -0
  41. package/package.json +15 -7
@@ -1,4 +1,5 @@
1
1
  import { type Address, type Hex } from 'viem';
2
+ import { z } from 'zod';
2
3
  export type KyberSwapFeeParams = {
3
4
  feeAmount: string;
4
5
  chargeFeeBy: 'currency_in' | 'currency_out';
@@ -46,6 +47,13 @@ export type KyberSwapBuild = {
46
47
  routerAddress: Address;
47
48
  transactionValue?: string;
48
49
  requestId?: string;
50
+ /**
51
+ * Unix-seconds deadline this build was requested with. Client-computed (it
52
+ * is a request parameter, not part of the wire response); the encoded
53
+ * calldata reverts on-chain past this moment, so callers can fail fresh
54
+ * checks closed before prompting the wallet.
55
+ */
56
+ deadline?: number;
49
57
  };
50
58
  export type KyberSwapError = {
51
59
  code?: number;
@@ -64,8 +72,16 @@ export declare class KyberSwapApiError extends Error {
64
72
  body?: unknown;
65
73
  });
66
74
  }
75
+ export declare class KyberSwapContractError extends Error {
76
+ readonly endpoint: string;
77
+ readonly issues: z.core.$ZodIssue[];
78
+ constructor({ endpoint, issues }: {
79
+ endpoint: string;
80
+ issues: z.core.$ZodIssue[];
81
+ });
82
+ }
67
83
  export declare function isRetryableKyberSwapError(error: unknown): boolean;
68
- export declare function fetchKyberSwapRoute({ tokenIn, tokenOut, amountIn, chainId, origin, fee, signal }: {
84
+ export declare function fetchKyberSwapRoute({ tokenIn, tokenOut, amountIn, chainId, origin, fee, signal, timeoutMs }: {
69
85
  tokenIn: Address;
70
86
  tokenOut: Address;
71
87
  amountIn: string;
@@ -73,12 +89,16 @@ export declare function fetchKyberSwapRoute({ tokenIn, tokenOut, amountIn, chain
73
89
  origin?: Address | null;
74
90
  fee?: KyberSwapFeeParams | null;
75
91
  signal?: AbortSignal;
92
+ /** Abort after this many ms (composes with `signal`); defaults to 20s. */
93
+ timeoutMs?: number;
76
94
  }): Promise<KyberSwapRoute>;
77
- export declare function buildKyberSwapRoute({ routeSummary, sender, recipient, slippageBps, chainId, signal }: {
95
+ export declare function buildKyberSwapRoute({ routeSummary, sender, recipient, slippageBps, chainId, signal, timeoutMs }: {
78
96
  routeSummary: KyberSwapRouteSummary;
79
97
  sender: Address;
80
98
  recipient: Address;
81
99
  slippageBps: number;
82
100
  chainId?: number;
83
101
  signal?: AbortSignal;
102
+ /** Abort after this many ms (composes with `signal`); defaults to 20s. */
103
+ timeoutMs?: number;
84
104
  }): Promise<KyberSwapBuild>;
@@ -0,0 +1,17 @@
1
+ import { type Hex, type PublicClient, type TransactionReceipt } from 'viem';
2
+ export declare const APPROVAL_RECEIPT_TIMEOUT_MS: number;
3
+ export declare const SWAP_RECEIPT_TIMEOUT_MS: number;
4
+ type OnReplacedParameter = NonNullable<Parameters<PublicClient['waitForTransactionReceipt']>[0]['onReplaced']>;
5
+ /**
6
+ * waitForTransactionReceipt with a hard timeout, mapping viem's timeout error
7
+ * to the SDK's TransactionReceiptTimeoutError (which carries the tx hash so
8
+ * the UI can degrade to an explorer link). Every other failure passes through
9
+ * untouched.
10
+ */
11
+ export declare function waitForReceiptWithTimeout(args: {
12
+ publicClient: PublicClient;
13
+ hash: Hex;
14
+ timeoutMs: number;
15
+ onReplaced?: OnReplacedParameter;
16
+ }): Promise<TransactionReceipt>;
17
+ export {};
@@ -1,16 +1,44 @@
1
1
  import { type Address, type Chain, type Hex, type PublicClient, type TransactionReceipt } from 'viem';
2
2
  import type { AegisSwapReceiptSummary } from '../transactionProgress.js';
3
+ import { type SwapSettlementContext } from './settlement.js';
3
4
  import type { AegisSwapSubmitDetails, WalletSession } from './types.js';
4
5
  /**
5
- * Sends a prepared swap transaction and waits for its receipt.
6
+ * Guarded send pipeline shared by the swap and engine planes.
7
+ *
8
+ * Immediately before requesting the signature it re-reads the wallet's active
9
+ * chain and fails closed on a mismatch (assertChainMatches): multi-prompt
10
+ * flows leave room for a wallet-side chain switch, and viem's chainId field
11
+ * is only honored by well-behaved wallets.
6
12
  *
7
13
  * Surfaces the optimistic hash through `onHash` (and `onSubmitted`) before
8
- * mining, then tracks replacements: a wallet speed-up swaps in the hash that
9
- * actually mines, while a wallet cancel mines a no-op whose "successful" receipt
10
- * must not count as a swap — so a cancelled or reverted receipt throws. Callers
11
- * compute their own gas and pass it via `gas`, so each keeps its gas strategy
12
- * (omit `gas` to let the wallet estimate).
14
+ * mining; a throwing host `onSubmitted` callback is swallowed with a warning
15
+ * rather than failing an already-submitted transaction. Then tracks
16
+ * replacements: a wallet speed-up swaps in the hash that actually mines,
17
+ * while a wallet cancel mines a no-op whose "successful"
18
+ * receipt must not count as success — so a cancelled or reverted receipt
19
+ * throws (`cancelledMessage`/`revertedMessage`). Callers compute their own
20
+ * gas and pass it via `gas`, so each keeps its gas strategy (omit `gas` to
21
+ * let the wallet estimate). The receipt wait carries a hard timeout; a
22
+ * dropped transaction surfaces as TransactionReceiptTimeoutError (with the
23
+ * hash) instead of hanging the flow forever.
13
24
  */
25
+ export declare function sendGuardedTransactionAndAwait(args: {
26
+ wallet: WalletSession;
27
+ publicClient: PublicClient;
28
+ chain: Chain;
29
+ to: Address;
30
+ data: Hex;
31
+ value: bigint;
32
+ gas?: bigint;
33
+ cancelledMessage: string;
34
+ revertedMessage: string;
35
+ onHash?: (hash: Hex | null) => void;
36
+ onSubmitted?: (hash: Hex) => void;
37
+ }): Promise<{
38
+ receipt: TransactionReceipt;
39
+ summary: AegisSwapReceiptSummary;
40
+ }>;
41
+ /** Sends a prepared swap transaction through the shared guarded-send pipeline. */
14
42
  export declare function sendSwapTransactionAndAwait(args: {
15
43
  wallet: WalletSession;
16
44
  publicClient: PublicClient;
@@ -20,6 +48,12 @@ export declare function sendSwapTransactionAndAwait(args: {
20
48
  value: bigint;
21
49
  gas?: bigint;
22
50
  swapDetails: AegisSwapSubmitDetails;
51
+ /**
52
+ * When provided, the summary also carries `settledAmountOut` decoded from
53
+ * the mined receipt (Transfer logs for ERC-20 output, balance delta for
54
+ * native). Best-effort: decoding failures leave the field undefined.
55
+ */
56
+ settlement?: SwapSettlementContext;
23
57
  onHash?: (hash: Hex | null) => void;
24
58
  onSubmitted?: (hash: Hex, swap?: AegisSwapSubmitDetails) => void;
25
59
  }): Promise<{
@@ -0,0 +1,15 @@
1
+ import { type Address, type PublicClient, type TransactionReceipt } from 'viem';
2
+ export type SwapSettlementContext = {
3
+ /** Account the swap output settles to (the tx sender in both action flows). */
4
+ recipient: Address;
5
+ /** Output token address; zero address or the 0xEeee… sentinel means native. */
6
+ outputToken: Address;
7
+ };
8
+ /**
9
+ * Best-effort decode of what the swap actually settled to the recipient:
10
+ * summed ERC-20 Transfer logs for token output, balance delta for native
11
+ * output. Returns undefined — never throws — when the receipt cannot answer
12
+ * (lean RPC without logs, balance lookup failure), so a successful swap is
13
+ * never failed retroactively over display data.
14
+ */
15
+ export declare function resolveSettledAmountOut(publicClient: PublicClient, receipt: TransactionReceipt, settlement: SwapSettlementContext): Promise<bigint | undefined>;
@@ -12,6 +12,13 @@ export type AegisSwapReceiptSummary = {
12
12
  effectiveGasPrice: bigint;
13
13
  /** gasUsed * effectiveGasPrice — the L2-exclusive execution fee in native wei. */
14
14
  feeWei: bigint;
15
+ /**
16
+ * Output amount that actually settled to the recipient, decoded from the
17
+ * mined receipt (summed ERC-20 Transfer logs, or the native balance delta).
18
+ * Best-effort and optional: absent when the receipt cannot answer, in which
19
+ * case UIs should keep showing the quote estimate with a "~" affordance.
20
+ */
21
+ settledAmountOut?: bigint;
15
22
  };
16
23
  export declare function isBusy(status: SubmitStatus): boolean;
17
24
  export type TransactionProgressState = 'pending' | 'mining' | 'success' | 'error';
@@ -43,7 +50,7 @@ export declare function transactionProgressView({ status, inputSymbol, txHash, a
43
50
  export type AegisSwapStatusSnapshot = {
44
51
  status: SubmitStatus;
45
52
  progress: TransactionProgressState | null;
46
- /** The rail's phase copy (e.g. "Approving USDC for Permit2 · wallet prompt 1 of 3"); null while idle. */
53
+ /** The rail's phase copy (e.g. "Approving USDC"); null while idle. */
47
54
  label: string | null;
48
55
  /** Swap-flow wallet provider prompt count/progress, derived from current allowances. */
49
56
  walletPrompts: AegisSwapWalletPromptProgress;
@@ -15,6 +15,20 @@ export type AggregatedSwapQuote = {
15
15
  hops: HopInfo[];
16
16
  routerAddress: Address;
17
17
  calldata: Hex | null;
18
+ /**
19
+ * keccak256 of `calldata`, committed when the route was built. Execution
20
+ * verifies the bytes handed to the wallet against this hash
21
+ * (assertCalldataHash) so tx economics cannot be rewritten in between.
22
+ * Optional so host-constructed display quotes stay valid.
23
+ */
24
+ calldataHash?: Hex | null;
25
+ /**
26
+ * ISO timestamp of the built calldata's embedded deadline; the transaction
27
+ * reverts on-chain past it, so execution fails closed (assertQuoteFresh)
28
+ * instead of prompting the wallet for a doomed swap. Absent on display
29
+ * quotes fetched without an account.
30
+ */
31
+ expiresAt?: string;
18
32
  transactionValue: bigint;
19
33
  priceImpact: number;
20
34
  feeAmount: bigint;
@@ -22,6 +36,10 @@ export type AggregatedSwapQuote = {
22
36
  feeRecipient: Address | null;
23
37
  userAmountOutMinimum: bigint;
24
38
  amountOutMinimum: bigint;
39
+ /** USD values from the aggregator's route summary, when present. */
40
+ amountInUsd?: number;
41
+ amountOutUsd?: number;
42
+ gasUsd?: number;
25
43
  };
26
44
  export type AggregatedSwapRoute = {
27
45
  inputToken: AegisSwapToken;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@aegis-engine/core",
3
- "version": "0.2.0",
4
- "description": "React-free Aegis swap operations for direct Uniswap v4 pools and KyberSwap routes.",
3
+ "version": "0.3.0",
4
+ "description": "React-free Aegis Swap and Engine quoting, risk, approval, and execution operations.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "./dist/aegis-core.js",
@@ -10,22 +10,30 @@
10
10
  "exports": {
11
11
  ".": {
12
12
  "types": "./dist/index.d.ts",
13
- "import": "./dist/aegis-core.js"
14
- }
13
+ "import": "./dist/aegis-core.js",
14
+ "require": null,
15
+ "default": "./dist/aegis-core.js"
16
+ },
17
+ "./package.json": "./package.json"
18
+ },
19
+ "publishConfig": {
20
+ "access": "public"
15
21
  },
16
22
  "files": [
17
23
  "dist",
18
24
  "README.md",
19
- "LICENSE"
25
+ "LICENSE",
26
+ "THIRD_PARTY_NOTICES.md"
20
27
  ],
21
28
  "peerDependencies": {
22
- "viem": "^2"
29
+ "viem": "^2.23.1"
23
30
  },
24
31
  "devDependencies": {
32
+ "@labs-solo/aegis-engine-sdk": "0.30.0",
25
33
  "@types/node": "^25.9.1",
26
34
  "openapi-typescript": "^7.13.0",
27
35
  "typescript": "~5.6.2",
28
- "viem": "^2.52.0",
36
+ "viem": "^2.54.3",
29
37
  "vite": "^6.0.1",
30
38
  "vitest": "^4.1.8"
31
39
  },