@aegis-engine/core 0.4.0 → 0.6.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 +148 -26
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/dist/actions/directPoolSwap.d.ts +1 -0
- package/dist/actions/types.d.ts +55 -0
- package/dist/aegis-core.js +201 -9568
- package/dist/contract/generated/aegis-swap.d.ts +112 -92
- package/dist/engine/actions.d.ts +46 -1
- package/dist/engine/activityLotDisplay.d.ts +8 -0
- package/dist/engine/index.d.ts +4 -0
- package/dist/engine/lendHistory.d.ts +21 -0
- package/dist/engine/positionStrategy.d.ts +15 -0
- package/dist/engine/quotes.d.ts +10 -1
- package/dist/engine/reads.d.ts +11 -2
- package/dist/engine/simpleYield.d.ts +39 -0
- package/dist/engine/trade/buildTapOpenPosition.d.ts +17 -0
- package/dist/engine/trade/route.d.ts +24 -0
- package/dist/engine/trade/sizing.d.ts +136 -0
- package/dist/engine/trade/swapLeg.d.ts +32 -0
- package/dist/engine/trade/systemState.d.ts +44 -0
- package/dist/engine/trade/units.d.ts +41 -0
- package/dist/engine/types.d.ts +328 -4
- package/dist/errors.d.ts +36 -2
- package/dist/index-D9EfUokZ.js +11031 -0
- package/dist/index.d.ts +7 -3
- package/dist/permit.d.ts +5 -0
- package/dist/{sdkRuntime-Dqr9JFXP.js → sdkRuntime-C_vaU-0g.js} +5108 -4800
- package/dist/swap/authorizePermit.d.ts +5 -1
- package/dist/swap/receiptWait.d.ts +26 -3
- package/dist/swap/sendSwapTransaction.d.ts +15 -0
- package/dist/transactionProgress.d.ts +40 -2
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -31,8 +31,9 @@ the published Core package; consumers do not need GitHub Packages credentials.
|
|
|
31
31
|
bounded session caches, and explicit indexed freshness.
|
|
32
32
|
- Engine 12-hour market-metric history for optional rate, utilization, and
|
|
33
33
|
liquidity charts.
|
|
34
|
-
- Engine lend and
|
|
35
|
-
projections
|
|
34
|
+
- Engine lend, borrow, and directional Long/Short quotes; exact rounded
|
|
35
|
+
LP-shaped debt/carry projections; collateral sizing; Permit2 preparation;
|
|
36
|
+
and guarded execution.
|
|
36
37
|
|
|
37
38
|
Direct pool swaps support `exactIn` and `exactOut`. KyberSwap routes currently
|
|
38
39
|
support `exactIn` only because Kyber's route/build flow is exact-input.
|
|
@@ -46,8 +47,10 @@ Engine discovery and wallet positions default to partner-safe REST:
|
|
|
46
47
|
|
|
47
48
|
```ts
|
|
48
49
|
import {
|
|
50
|
+
deriveEngineTradePositionStrategy,
|
|
49
51
|
fetchEngineMarketHistory,
|
|
50
52
|
fetchEngineMarkets,
|
|
53
|
+
fetchEnginePositionActivitySnapshot,
|
|
51
54
|
fetchEnginePositionsSnapshot
|
|
52
55
|
} from '@aegis-engine/core'
|
|
53
56
|
|
|
@@ -63,6 +66,16 @@ const positions = await fetchEnginePositionsSnapshot({
|
|
|
63
66
|
chainId: 1,
|
|
64
67
|
account
|
|
65
68
|
})
|
|
69
|
+
const activity = await fetchEnginePositionActivitySnapshot({
|
|
70
|
+
source,
|
|
71
|
+
chainId: 1,
|
|
72
|
+
account
|
|
73
|
+
})
|
|
74
|
+
const position = positions.positions[0]
|
|
75
|
+
const vault = activity?.vaults.find((entry) => entry.vaultId === position?.vaultId)
|
|
76
|
+
const strategy = position && vault
|
|
77
|
+
? deriveEngineTradePositionStrategy(position, vault)
|
|
78
|
+
: null
|
|
66
79
|
const marketHistory = await fetchEngineMarketHistory({
|
|
67
80
|
source,
|
|
68
81
|
marketId: markets[0].id,
|
|
@@ -71,7 +84,10 @@ const marketHistory = await fetchEngineMarketHistory({
|
|
|
71
84
|
```
|
|
72
85
|
|
|
73
86
|
Hosts that already own deterministic market/position metadata can instead use
|
|
74
|
-
the typed `static` source.
|
|
87
|
+
the typed `static` source. Supply `vaultActivity` when an offline fixture must
|
|
88
|
+
reconstruct Long/Short identity; position rows alone are ordinary borrow-vault
|
|
89
|
+
facts and are not enough to classify a trade. Engine market history remains a
|
|
90
|
+
REST capability.
|
|
75
91
|
|
|
76
92
|
The REST service supplies facts and provenance. Core owns live RPC reads,
|
|
77
93
|
collateral/debt math, quote freshness, recipe construction, simulation,
|
|
@@ -106,6 +122,124 @@ remaining collateral stays in the vault until a separate withdrawal. A
|
|
|
106
122
|
one-token lend is a zap into a two-sided full-range LP, not single-token
|
|
107
123
|
lending.
|
|
108
124
|
|
|
125
|
+
### Simple-yield position summaries
|
|
126
|
+
|
|
127
|
+
Use `summarizeEngineSimpleYieldPosition` when a custom UI needs one honest,
|
|
128
|
+
React-free summary of an Engine lender-share position. The helper values live
|
|
129
|
+
shares first, falls back to trusted indexed shares, projects an optional added
|
|
130
|
+
USD amount, and converts realized share-price growth into a weekly estimate.
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
import {
|
|
134
|
+
readEnginePositionsHydration,
|
|
135
|
+
summarizeEngineSimpleYieldPosition
|
|
136
|
+
} from '@aegis-engine/core'
|
|
137
|
+
|
|
138
|
+
const market = markets[0]
|
|
139
|
+
const positionsHydration = await readEnginePositionsHydration({
|
|
140
|
+
publicClient,
|
|
141
|
+
chainId: market.chainId,
|
|
142
|
+
expectedAccount: account,
|
|
143
|
+
positions: positions.positions,
|
|
144
|
+
lendPositions: positions.lendPositions
|
|
145
|
+
})
|
|
146
|
+
const position = positions.lendPositions.find(
|
|
147
|
+
(entry) =>
|
|
148
|
+
entry.chainId === market.chainId &&
|
|
149
|
+
entry.poolId.toLowerCase() === market.poolId.toLowerCase()
|
|
150
|
+
) ?? null
|
|
151
|
+
const live = position
|
|
152
|
+
? positionsHydration.lendPositions.find(
|
|
153
|
+
(entry) => entry.positionId === position.id
|
|
154
|
+
)
|
|
155
|
+
: undefined
|
|
156
|
+
|
|
157
|
+
const summary = summarizeEngineSimpleYieldPosition({
|
|
158
|
+
market,
|
|
159
|
+
position,
|
|
160
|
+
hydration: live,
|
|
161
|
+
history: marketHistory,
|
|
162
|
+
additionalValueUsd: 100
|
|
163
|
+
})
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
`summary.valuation` identifies whether live or indexed shares produced the
|
|
167
|
+
current USD value. `summary.projection` is null when an existing position cannot
|
|
168
|
+
be valued, so an add-funds UI cannot mislabel it as a new deposit.
|
|
169
|
+
`summary.growth.weeklyEarningsPer100Usd` is a historical share-growth estimate,
|
|
170
|
+
not a promise. `market.metrics.lendApyPct` is the current modeled lender rate;
|
|
171
|
+
it is a different metric and is never substituted for realized history.
|
|
172
|
+
|
|
173
|
+
### Directional Engine positions
|
|
174
|
+
|
|
175
|
+
`quoteEngineTradeOpen` sizes a fresh-vault Long or Short against one
|
|
176
|
+
block-pinned Engine and Uniswap v4 frame. It returns the selected average and
|
|
177
|
+
live leverage, exact opening LTV after the swap minimum, interest carry, risk
|
|
178
|
+
thresholds, gross return at the configured target, actionable solver limits,
|
|
179
|
+
and atomic router calldata when all execution gates pass.
|
|
180
|
+
|
|
181
|
+
Successful and leverage-bound quotes expose `limits.minLeverage` and
|
|
182
|
+
`limits.maxLeverage`. Treat these as live, request-specific bounds rather than
|
|
183
|
+
a protocol-wide constant.
|
|
184
|
+
|
|
185
|
+
`deriveEngineTradePositionStrategy` recognizes the indexed Tap opening action
|
|
186
|
+
shape and recovers its Long/Short direction and executed entry price after a
|
|
187
|
+
reload. The selected target and average-to-target leverage are not transaction
|
|
188
|
+
fields. A host can pass persisted intent records to augment those fields only
|
|
189
|
+
when chain, account, market, pool, transaction, and direction all match.
|
|
190
|
+
A no-swap opening has no indexed direction signal, so this helper deliberately
|
|
191
|
+
leaves it unclassified instead of trusting off-chain intent alone.
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
import { quoteEngineTradeOpen } from '@aegis-engine/core'
|
|
195
|
+
|
|
196
|
+
const quote = await quoteEngineTradeOpen({
|
|
197
|
+
publicClient,
|
|
198
|
+
market,
|
|
199
|
+
owner: account,
|
|
200
|
+
direction: 'long',
|
|
201
|
+
collateralIn: 1_000_000n,
|
|
202
|
+
inputIsToken0: false,
|
|
203
|
+
leverage: 1.5,
|
|
204
|
+
horizonSeconds: 30 * 24 * 60 * 60,
|
|
205
|
+
priceMove: 0.2,
|
|
206
|
+
slippageBps: 100
|
|
207
|
+
})
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Treat `feasible` and `executable` separately. A feasible quote can still need
|
|
211
|
+
the trusted router's vault-operator grant or Permit2 authorization. After an
|
|
212
|
+
authorization transaction, request the submit quote with
|
|
213
|
+
`forceExecutionEvidenceRefresh: true`; then pass its fresh `tx` and `expiresAt`
|
|
214
|
+
to `sendEngineTransaction`. The prebuilt `AegisLeverageWidget` performs this
|
|
215
|
+
sequence for frontend integrations.
|
|
216
|
+
|
|
217
|
+
Use `readEngineAuthorizationPlan` to present the connected account's current
|
|
218
|
+
wallet sequence before submission:
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
import { readEngineAuthorizationPlan } from '@aegis-engine/core'
|
|
222
|
+
|
|
223
|
+
const plan = await readEngineAuthorizationPlan({
|
|
224
|
+
publicClient,
|
|
225
|
+
market,
|
|
226
|
+
owner: account,
|
|
227
|
+
walletChainId,
|
|
228
|
+
token: market.token0,
|
|
229
|
+
amount: 1_000_000n,
|
|
230
|
+
approvalMode: 'exact'
|
|
231
|
+
})
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
`missingPermissionCount` excludes the final open and any zero-first reset.
|
|
235
|
+
`walletPromptCount` includes every required sequential transaction.
|
|
236
|
+
`walletChainSwitchRequired` reports the network switch separately and is null
|
|
237
|
+
until the wallet chain is known. The plan is a read-only presentation snapshot, not authorization
|
|
238
|
+
evidence. Submission must still re-read permissions and obtain a fresh
|
|
239
|
+
executable quote. Exact ERC-20 and Permit2 limits are consumed by the successful
|
|
240
|
+
opening transfer; maximum limits and the VaultRegistry operator grant remain
|
|
241
|
+
active until revoked.
|
|
242
|
+
|
|
109
243
|
## Historical token prices
|
|
110
244
|
|
|
111
245
|
Historical prices are intentionally separate from Engine market and
|
|
@@ -113,10 +247,7 @@ transaction truth. A host reads one exact token through the public REST
|
|
|
113
247
|
backend without placing private data-service credentials in the client:
|
|
114
248
|
|
|
115
249
|
```ts
|
|
116
|
-
import {
|
|
117
|
-
AEGIS_BACKEND_PROD_BASE_URL,
|
|
118
|
-
fetchTokenPriceHistory
|
|
119
|
-
} from '@aegis-engine/core'
|
|
250
|
+
import { AEGIS_BACKEND_PROD_BASE_URL, fetchTokenPriceHistory } from '@aegis-engine/core'
|
|
120
251
|
|
|
121
252
|
const history = await fetchTokenPriceHistory({
|
|
122
253
|
baseUrl: AEGIS_BACKEND_PROD_BASE_URL,
|
|
@@ -189,10 +320,7 @@ const wallet = await resolveWalletSession({
|
|
|
189
320
|
Create a read-side viem client from an Aegis chain config:
|
|
190
321
|
|
|
191
322
|
```ts
|
|
192
|
-
import {
|
|
193
|
-
AEGIS_SWAP_MAINNET_CHAIN,
|
|
194
|
-
createSwapPublicClient
|
|
195
|
-
} from '@aegis-engine/core'
|
|
323
|
+
import { AEGIS_SWAP_MAINNET_CHAIN, createSwapPublicClient } from '@aegis-engine/core'
|
|
196
324
|
|
|
197
325
|
const publicClient = createSwapPublicClient(
|
|
198
326
|
AEGIS_SWAP_MAINNET_CHAIN.chain,
|
|
@@ -212,10 +340,7 @@ metadata, market discovery, allowlists, and fee policy come from REST. Swap
|
|
|
212
340
|
execution remains client-side.
|
|
213
341
|
|
|
214
342
|
```ts
|
|
215
|
-
import {
|
|
216
|
-
AEGIS_BACKEND_PROD_BASE_URL,
|
|
217
|
-
createAegisBackendApiClient
|
|
218
|
-
} from '@aegis-engine/core'
|
|
343
|
+
import { AEGIS_BACKEND_PROD_BASE_URL, createAegisBackendApiClient } from '@aegis-engine/core'
|
|
219
344
|
|
|
220
345
|
const aegisApi = createAegisBackendApiClient({
|
|
221
346
|
baseUrl: AEGIS_BACKEND_PROD_BASE_URL
|
|
@@ -281,10 +406,7 @@ provided, core verifies it matches the key.
|
|
|
281
406
|
## Direct Pool Quote
|
|
282
407
|
|
|
283
408
|
```ts
|
|
284
|
-
import {
|
|
285
|
-
AEGIS_SWAP_MAINNET_CHAIN,
|
|
286
|
-
fetchDirectPoolSwapQuote
|
|
287
|
-
} from '@aegis-engine/core'
|
|
409
|
+
import { AEGIS_SWAP_MAINNET_CHAIN, fetchDirectPoolSwapQuote } from '@aegis-engine/core'
|
|
288
410
|
|
|
289
411
|
const quote = await fetchDirectPoolSwapQuote({
|
|
290
412
|
publicClient,
|
|
@@ -339,10 +461,7 @@ protection the user saw.
|
|
|
339
461
|
## KyberSwap Quote
|
|
340
462
|
|
|
341
463
|
```ts
|
|
342
|
-
import {
|
|
343
|
-
AGGREGATED_SWAP_DEFAULT_TOKENS,
|
|
344
|
-
fetchAggregatedSwapQuote
|
|
345
|
-
} from '@aegis-engine/core'
|
|
464
|
+
import { AGGREGATED_SWAP_DEFAULT_TOKENS, fetchAggregatedSwapQuote } from '@aegis-engine/core'
|
|
346
465
|
|
|
347
466
|
const quote = await fetchAggregatedSwapQuote(
|
|
348
467
|
AGGREGATED_SWAP_DEFAULT_TOKENS.USDC,
|
|
@@ -454,9 +573,12 @@ Execution returns:
|
|
|
454
573
|
|
|
455
574
|
## Publishing
|
|
456
575
|
|
|
457
|
-
|
|
458
|
-
|
|
576
|
+
Releases use Changesets and npm trusted publishing. The release workflow builds
|
|
577
|
+
all publishable packages once, validates their tarballs, then publishes the
|
|
578
|
+
prebuilt artifacts with package lifecycle scripts disabled. This prevents
|
|
579
|
+
concurrent package publishes from rebuilding shared workspace artifacts.
|
|
459
580
|
|
|
460
581
|
```sh
|
|
461
|
-
|
|
582
|
+
pnpm build
|
|
583
|
+
pnpm pack:check
|
|
462
584
|
```
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The lazy Engine implementation includes code from these MIT-licensed works:
|
|
4
4
|
|
|
5
|
-
- `@labs-solo/aegis-engine-sdk` 0.
|
|
5
|
+
- `@labs-solo/aegis-engine-sdk` 0.33.0 — Copyright (c) 2026 Solo Labs
|
|
6
6
|
- `@uniswap/sdk-core` 6.1.1 and 7.18.0 — Copyright (c) 2021 Uniswap Labs
|
|
7
7
|
- `@uniswap/v3-sdk` 3.27.0 — Copyright (c) 2021 Uniswap Labs
|
|
8
8
|
- `tiny-invariant` 1.3.3 — Copyright (c) 2019 Alexander Reardon
|
|
@@ -32,6 +32,7 @@ export declare function approveDirectPoolSwapInput(args: {
|
|
|
32
32
|
amount: bigint;
|
|
33
33
|
approvalMode?: AegisSwapApprovalMode;
|
|
34
34
|
onStatus?: AegisSwapActionCallbacks['onStatus'];
|
|
35
|
+
onApprovalProgress?: AegisSwapActionCallbacks['onApprovalProgress'];
|
|
35
36
|
}): Promise<DirectPoolSwapApprovalResult>;
|
|
36
37
|
export declare function executeDirectPoolSwap(args: {
|
|
37
38
|
wallet: WalletSession;
|
package/dist/actions/types.d.ts
CHANGED
|
@@ -3,10 +3,65 @@ import type { DirectSwapQuote } from '../quote.js';
|
|
|
3
3
|
import type { AegisSwapReceiptSummary, SubmitStatus } from '../transactionProgress.js';
|
|
4
4
|
import type { AggregatedSwapQuote } from '../types/aggregatedSwap.js';
|
|
5
5
|
import type { AegisSwapSubmitDetails } from '../swap/types.js';
|
|
6
|
+
/**
|
|
7
|
+
* The grant the approval prompt asks for, as the executor resolved it from the
|
|
8
|
+
* sizing rule. It travels with the progress report so a surface renders the
|
|
9
|
+
* number that will actually be signed instead of re-deriving one from form
|
|
10
|
+
* state — the input amount and the requested amount are the same only under
|
|
11
|
+
* 'exact' sizing. There is no `formatted` field: the unlimited case has no
|
|
12
|
+
* honest formatting and has to be rendered as a word.
|
|
13
|
+
*/
|
|
14
|
+
export type AegisSwapApprovalRequest = {
|
|
15
|
+
/** The exact value passed to `approve()`. */
|
|
16
|
+
value: bigint;
|
|
17
|
+
/** Decimals of the approved token, so `value` is renderable on its own. */
|
|
18
|
+
decimals: number;
|
|
19
|
+
/** True when `value` reads as no limit at all; render a word, not `value`. */
|
|
20
|
+
unlimited: boolean;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* The approval step's wallet prompts: how many it will open, how many the
|
|
24
|
+
* wallet has already confirmed, and what they ask for. Only the executor can
|
|
25
|
+
* answer any of it — its allowance read decides whether a USDT-style zero-reset
|
|
26
|
+
* adds a second prompt, and only it sees that reset's receipt.
|
|
27
|
+
*/
|
|
28
|
+
export type AegisSwapApprovalProgress = {
|
|
29
|
+
/** Prompts the approval step opens: 0, 1, or 2 when a zero-reset precedes it. */
|
|
30
|
+
planned: number;
|
|
31
|
+
/** How many of `planned` have landed on-chain. */
|
|
32
|
+
completed: number;
|
|
33
|
+
/** Absent exactly when `planned` is 0 — nothing will be approved. */
|
|
34
|
+
request?: AegisSwapApprovalRequest;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Wallet prompts used to authorize Permit2 for the router. Usually this is one
|
|
38
|
+
* typed-data signature. A wallet that explicitly reports typed-data as
|
|
39
|
+
* unsupported uses one on-chain spending-cap prompt instead. Returned invalid
|
|
40
|
+
* signatures fail closed, so this is a count rather than a boolean.
|
|
41
|
+
*/
|
|
42
|
+
export type AegisSwapAuthorizationProgress = {
|
|
43
|
+
/** Prompts this authorization step will open from the executor's live state. */
|
|
44
|
+
planned: number;
|
|
45
|
+
/** Prompts already completed by the wallet/user. */
|
|
46
|
+
completed: number;
|
|
47
|
+
};
|
|
6
48
|
export type AegisSwapActionCallbacks<TSwapDetails = AegisSwapSubmitDetails> = {
|
|
7
49
|
onStatus?: (status: SubmitStatus) => void;
|
|
8
50
|
onTxHash?: (hash: Hex | null) => void;
|
|
9
51
|
onSubmitted?: (hash: Hex, swap?: TSwapDetails) => void;
|
|
52
|
+
/**
|
|
53
|
+
* Fires with the plan before the first approval prompt opens, then again
|
|
54
|
+
* after each approval transaction mines. Once allowance resolution is
|
|
55
|
+
* reached, no required approval reports `{ planned: 0, completed: 0 }`.
|
|
56
|
+
* Earlier chain-validation or quote failures can stop before this callback.
|
|
57
|
+
*/
|
|
58
|
+
onApprovalProgress?: (progress: AegisSwapApprovalProgress) => void;
|
|
59
|
+
/**
|
|
60
|
+
* Fires before the first Permit2 authorization prompt, whenever the plan
|
|
61
|
+
* changes, and after each completed prompt. A reusable standing cap reports
|
|
62
|
+
* `{ planned: 0, completed: 0 }`.
|
|
63
|
+
*/
|
|
64
|
+
onAuthorizationProgress?: (progress: AegisSwapAuthorizationProgress) => void;
|
|
10
65
|
};
|
|
11
66
|
export type AegisSwapActionResult<TQuote = DirectSwapQuote | AggregatedSwapQuote> = {
|
|
12
67
|
hash: Hex;
|