aegis-swap-widget 0.10.3 → 0.12.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 (172) hide show
  1. package/CHANGELOG.md +192 -0
  2. package/DESIGN.md +1 -1
  3. package/README.md +186 -18
  4. package/THIRD_PARTY_NOTICES.md +25 -0
  5. package/agent/schemas/aegis-widget-config.schema.json +1034 -0
  6. package/agent/schemas/aegis-widget-events.schema.json +1180 -0
  7. package/agent/skills/aegis-widget-integration/SKILL.md +100 -0
  8. package/agent/validate-events.d.ts +45 -0
  9. package/agent/validate-events.js +336 -0
  10. package/dist/EngineTradeMarketChart-B-RlSrjp.js +1043 -0
  11. package/dist/aegis-swap-widget.js +52 -27589
  12. package/dist/components/ValueText.d.ts +19 -0
  13. package/dist/components/icons.d.ts +16 -0
  14. package/dist/config/chains.d.ts +1 -1
  15. package/dist/config/constants.d.ts +3 -0
  16. package/dist/config/tokens.d.ts +1 -1
  17. package/dist/config/types.d.ts +2 -2
  18. package/dist/core.d.ts +2 -0
  19. package/dist/core.js +11 -8
  20. package/dist/format.d.ts +12 -0
  21. package/dist/hooks/useEngineAccountPortfolio.d.ts +185 -0
  22. package/dist/hooks/useEngineBalancedLend.d.ts +40 -0
  23. package/dist/hooks/useEngineMarketCandles.d.ts +31 -0
  24. package/dist/hooks/useEnginePositionHistory.d.ts +759 -0
  25. package/dist/hooks/useEnginePositionPnl.d.ts +112 -0
  26. package/dist/hooks/useIsoLayoutEffect.d.ts +2 -0
  27. package/dist/hooks/useKeyedFetch.d.ts +4 -1
  28. package/dist/hooks/useMeasuredSize.d.ts +8 -0
  29. package/dist/hooks/usePairReferenceHistory.d.ts +19 -0
  30. package/dist/hooks/usePrefersReducedMotion.d.ts +2 -0
  31. package/dist/hooks/useSubmitSwap.d.ts +11 -2
  32. package/dist/hooks/useSubmittedReceiptRecovery.d.ts +3216 -3
  33. package/dist/hooks/useTokenAllowance.d.ts +10 -0
  34. package/dist/hooks/useTokenBalances.d.ts +2 -2
  35. package/dist/hooks/useVisibleMotionRef.d.ts +4 -0
  36. package/dist/hooks.d.ts +7 -0
  37. package/dist/hooks.js +11 -0
  38. package/dist/index-SHw1Anop.js +34271 -0
  39. package/dist/index.d.ts +13 -2
  40. package/dist/marketOrientation-B6SD7xSk.js +56 -0
  41. package/dist/markets-CjYBjn94.js +131 -0
  42. package/dist/motion.d.ts +12 -0
  43. package/dist/partner-context.js +46 -49
  44. package/dist/presets/thena.d.ts +18 -0
  45. package/dist/presets/thena.js +22 -0
  46. package/dist/presets/wolf-game.js +1 -1
  47. package/dist/styles.css +1 -1
  48. package/dist/submittedSwapContext.d.ts +4 -1
  49. package/dist/toast/useSwipeDismiss.d.ts +2 -2
  50. package/dist/transactionProgress.d.ts +4 -1
  51. package/dist/useEngineActivity-BkhItrUI.js +427 -0
  52. package/dist/widget/AegisEngineBalancedLend.d.ts +36 -0
  53. package/dist/widget/AegisEnginePortfolio.d.ts +53 -0
  54. package/dist/widget/AegisEngineWidget.d.ts +1 -0
  55. package/dist/widget/AmountField.d.ts +9 -5
  56. package/dist/widget/EngineAmountBox.d.ts +6 -4
  57. package/dist/widget/ProgressRail.d.ts +14 -3
  58. package/dist/widget/SettingsMenu.d.ts +7 -1
  59. package/dist/widget/SpendingLimitChoices.d.ts +13 -0
  60. package/dist/widget/SwapFormBody.d.ts +4 -1
  61. package/dist/widget/SwapWidgetShell.d.ts +9 -11
  62. package/dist/widget/TokenSelector.d.ts +1 -1
  63. package/dist/widget/TransactionPending.d.ts +13 -0
  64. package/dist/widget/TransactionReceipt.d.ts +9 -4
  65. package/dist/widget/TransactionStatusHeader.d.ts +9 -0
  66. package/dist/widget/TransactionStepList.d.ts +3 -1
  67. package/dist/widget/engine-controller/engineAccountDisplay.d.ts +3 -0
  68. package/dist/widget/engine-controller/engineActionState.d.ts +2 -0
  69. package/dist/widget/engine-controller/engineCtaLabel.d.ts +7 -1
  70. package/dist/widget/engine-controller/engineDisplay.d.ts +42 -18
  71. package/dist/widget/engine-controller/engineHistoryRecorder.d.ts +12 -0
  72. package/dist/widget/engine-controller/engineLifecycle.d.ts +3 -2
  73. package/dist/widget/engine-controller/enginePermissionFamilies.d.ts +23 -25
  74. package/dist/widget/engine-controller/enginePermissionRun.d.ts +32 -0
  75. package/dist/widget/engine-controller/enginePortfolioActivity.d.ts +24 -0
  76. package/dist/widget/engine-controller/enginePortfolioDisplay.d.ts +149 -0
  77. package/dist/widget/engine-controller/enginePositionBook.d.ts +10 -11
  78. package/dist/widget/engine-controller/enginePositionManageCopy.d.ts +15 -1
  79. package/dist/widget/engine-controller/engineQuoteFetch.d.ts +7 -0
  80. package/dist/widget/engine-controller/engineRetry.d.ts +1 -0
  81. package/dist/widget/engine-controller/engineTokenPull.d.ts +4 -0
  82. package/dist/widget/engine-controller/engineTransactionProgress.d.ts +13 -2
  83. package/dist/widget/engine-controller/marketOrientation.d.ts +15 -0
  84. package/dist/widget/engine-controller/simpleBorrowSizing.d.ts +17 -0
  85. package/dist/widget/engine-controller/useBorrowWalletCollateral.d.ts +5 -0
  86. package/dist/widget/engine-controller/useEngineAccountNavigation.d.ts +34 -0
  87. package/dist/widget/engine-controller/useEngineActivity.d.ts +32 -4
  88. package/dist/widget/engine-controller/useEngineAuthorizationPlan.d.ts +0 -1
  89. package/dist/widget/engine-controller/useEngineBuySwapProps.d.ts +5 -5
  90. package/dist/widget/engine-controller/useEngineChainConfig.d.ts +2 -1
  91. package/dist/widget/engine-controller/useEngineFills.d.ts +2 -2
  92. package/dist/widget/engine-controller/useEngineMarketLinks.d.ts +0 -1
  93. package/dist/widget/engine-controller/useEngineMarketMarks.d.ts +2 -1
  94. package/dist/widget/engine-controller/useEnginePermissionSetup.d.ts +15 -1
  95. package/dist/widget/engine-controller/useEnginePositionActions.d.ts +40 -12
  96. package/dist/widget/engine-controller/useEnginePositionStrategies.d.ts +6 -4
  97. package/dist/widget/engine-controller/useEnginePositions.d.ts +7 -2
  98. package/dist/widget/engine-controller/useEngineSubmit.d.ts +12 -5
  99. package/dist/widget/engine-controller/useEngineTradePermissions.d.ts +16 -3
  100. package/dist/widget/engine-controller/useEngineTradeSubmit.d.ts +41 -3
  101. package/dist/widget/engine-ui/EngineAccountPortfolioPanel.d.ts +6 -0
  102. package/dist/widget/engine-ui/EngineAccountSummary.d.ts +13 -0
  103. package/dist/widget/engine-ui/EngineBuyPanel.d.ts +4 -1
  104. package/dist/widget/engine-ui/EngineChartSkeleton.d.ts +1 -0
  105. package/dist/widget/engine-ui/EngineDetailsBreakdown.d.ts +4 -1
  106. package/dist/widget/engine-ui/EngineDirectionLedger.d.ts +18 -0
  107. package/dist/widget/engine-ui/EngineDisclosure.d.ts +7 -0
  108. package/dist/widget/engine-ui/EngineLeverageControl.d.ts +5 -1
  109. package/dist/widget/engine-ui/EngineManageHealthPreview.d.ts +11 -0
  110. package/dist/widget/engine-ui/EngineMarketDialog.d.ts +3 -1
  111. package/dist/widget/engine-ui/EngineMarketNavigation.d.ts +11 -0
  112. package/dist/widget/engine-ui/EngineMarketUtilization.d.ts +4 -0
  113. package/dist/widget/engine-ui/EngineOnboardingAuthorize.d.ts +16 -3
  114. package/dist/widget/engine-ui/EngineOnboardingFooter.d.ts +8 -2
  115. package/dist/widget/engine-ui/EngineOnboardingProgress.d.ts +3 -4
  116. package/dist/widget/engine-ui/EngineOnboardingReview.d.ts +17 -9
  117. package/dist/widget/engine-ui/EngineOnboardingSuccess.d.ts +6 -4
  118. package/dist/widget/engine-ui/EngineOverlaySheet.d.ts +5 -2
  119. package/dist/widget/engine-ui/EnginePermissionRail.d.ts +2 -8
  120. package/dist/widget/engine-ui/EnginePermissionRailRow.d.ts +29 -6
  121. package/dist/widget/engine-ui/EnginePositionActions.d.ts +18 -0
  122. package/dist/widget/engine-ui/EnginePositionHealth.d.ts +8 -0
  123. package/dist/widget/engine-ui/EnginePositionHistoryPanel.d.ts +14 -0
  124. package/dist/widget/engine-ui/EnginePositionManageDialog.d.ts +6 -1
  125. package/dist/widget/engine-ui/EnginePositionsPanel.d.ts +22 -3
  126. package/dist/widget/engine-ui/EnginePriceChart.d.ts +39 -0
  127. package/dist/widget/engine-ui/EngineRealizedPnl.d.ts +13 -0
  128. package/dist/widget/engine-ui/EngineRiskMeter.d.ts +6 -8
  129. package/dist/widget/engine-ui/EngineSegmentedControl.d.ts +10 -4
  130. package/dist/widget/engine-ui/EngineSurgePill.d.ts +6 -6
  131. package/dist/widget/engine-ui/EngineTapDrawer.d.ts +9 -0
  132. package/dist/widget/engine-ui/EngineTapTicket.d.ts +9 -0
  133. package/dist/widget/engine-ui/EngineTimeRail.d.ts +8 -0
  134. package/dist/widget/engine-ui/EngineTradeEconomics.d.ts +10 -0
  135. package/dist/widget/engine-ui/EngineTradeEstimate.d.ts +2 -0
  136. package/dist/widget/engine-ui/EngineTradeIntentSummary.d.ts +16 -0
  137. package/dist/widget/engine-ui/EngineTradeMarketChart.d.ts +17 -0
  138. package/dist/widget/engine-ui/EngineTradeOnboarding.d.ts +20 -4
  139. package/dist/widget/engine-ui/EngineTradePermissions.d.ts +16 -8
  140. package/dist/widget/engine-ui/EngineTradePermissionsPanels.d.ts +11 -42
  141. package/dist/widget/engine-ui/EngineTradeShare.d.ts +36 -0
  142. package/dist/widget/engine-ui/EngineTransactionReceipt.d.ts +9 -2
  143. package/dist/widget/engine-ui/chartPriceLabel.d.ts +2 -0
  144. package/dist/widget/engine-ui/chartSeries.d.ts +37 -0
  145. package/dist/widget/engine-ui/engineOnboardingPanelTypes.d.ts +7 -1
  146. package/dist/widget/engine-ui/enginePermissionCopy.d.ts +31 -3
  147. package/dist/widget/engine-ui/enginePermissionRailGeometry.d.ts +5 -8
  148. package/dist/widget/engine-ui/engineReviewReasonCopy.d.ts +3 -0
  149. package/dist/widget/engine-ui/pairDayChange.d.ts +5 -0
  150. package/dist/widget/engine-ui/shareVerification.d.ts +29 -0
  151. package/dist/widget/engine-ui/useAnimatedDomain.d.ts +6 -0
  152. package/dist/widget/engine-ui/useChartPriceViewport.d.ts +37 -0
  153. package/dist/widget/engine-ui/useEngineChartSession.d.ts +8 -0
  154. package/dist/widget/engine-ui/useEngineTradeEducation.d.ts +1 -1
  155. package/dist/widget/engine-ui/useSuccessHeightSettle.d.ts +8 -0
  156. package/dist/widget/engineTradeViewModel.d.ts +28 -4
  157. package/dist/widget/focusTrap.d.ts +1 -0
  158. package/dist/widget/simpleBorrowMath.d.ts +0 -20
  159. package/dist/widget/simpleBorrowViewModel.d.ts +4 -0
  160. package/dist/widget/spendingLimit.d.ts +4 -0
  161. package/dist/widget/transactionSteps.d.ts +1 -1
  162. package/dist/widget/types.d.ts +75 -14
  163. package/dist/widget/useAggregatedSwapController.d.ts +17 -15
  164. package/dist/widget/useEngineController.d.ts +218 -99
  165. package/dist/widget/useSheetEntrance.d.ts +3 -0
  166. package/dist/widget/useStatusSurface.d.ts +2 -1
  167. package/dist/widget/useSwapConfig.d.ts +10 -2
  168. package/dist/widget/useSwapController.d.ts +23 -17
  169. package/dist/widget/viewState.d.ts +6 -3
  170. package/package.json +35 -4
  171. package/dist/markets-D31LUAsv.js +0 -71
  172. package/dist/widget/useRailAutoReset.d.ts +0 -11
package/CHANGELOG.md CHANGED
@@ -1,5 +1,197 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ed4f81a: Add a bounded account portfolio and paged activity contract, a reusable multi-chain portfolio view, and explicit receipt/indexer/portfolio acknowledgement. Preserve unknown valuations and per-chain coverage, resolve management through live position identity, and retain known transaction hashes across reloads without resubmission.
8
+ - fc5419f: Ship agent-readable widget config and versioned, correlated event schemas, a focused integration skill, a Swap event projector, a semantic event validator, and package resource exports.
9
+ - 7157400: Trade Long/Short now refers to the market's displayed asset across all markets. On USDC-ETH, Long means Long ETH; on BNB-QQQB, Long means Long QQQB. Displayed prices, leverage, existing positions and outcome estimates use that same orientation, including interest tooltips.
10
+
11
+ Host `tradeDirections`, `defaultTradeDirection` and the `direction` in onboarding event payloads use asset direction. Hosts that previously constrained token0 direction must invert their values on quote-first markets to preserve the same exposure. Core quotes, indexed actions and stored position records keep their protocol direction; hosts must not rewrite those records. See the Trade direction migration section in the widget README.
12
+
13
+ - 2c39b4b: Add a direct two-token lending quote and guarded execution flow, a headless React hook, and an opt-in linked-pair lending surface with exact token limits and persistent receipt recovery.
14
+ - 603c625: Add trusted BSC Aegis Engine v1.0.3 and direct-swap support to Core and Widget. This registers the BSC router and V4 contracts, enables production REST discovery, includes the BNB/BNCB, BNB/QQQB, and NVDAB/USDC pool catalogue, and handles native BNB without ERC-20 or Permit2 approval prompts.
15
+ - df98b19: Add a selective account reader and headless hook for completed tap trade token PnL from a retained accounting snapshot. Validate identity, cash-flow arithmetic and expiry; keep unsupported histories and total economic PnL explicitly unavailable. The hook reads once per snapshot, cancels replaced requests and honors Retry-After on manual refresh.
16
+ - 86da1ff: Add selective Core account and React hooks entry points, validated position-history and closed-position catalog reads, and shared transaction metadata recovery. Qualify installed public tarballs on the configured CI runtime and React 18/19. Validate the consumed live backend contract before enabling its features in an environment. History retains missing values, actual observation intervals and incomplete accounting coverage.
17
+ - 8d07a0b: Add the account-only position accounting reader and matching widget hook. Preserve raw event details, proven ownership, immutable snapshot cursors and explicit unavailable financial capabilities. Pin the consumed backend contract to the accounting endpoint source.
18
+ - 1c32ae1: Add lazy historical position discovery and recorded values to account and trading views, including closed positions and optional previously owned vaults. Preserve missing valuation and ownership coverage, reject expired or changed pagination, and expose history wire validators for host proxies.
19
+ - e53591d: Add a React-free Engine trade execution session with explicit wallet request,
20
+ submission, confirmation, failure, cancellation, receipt reconciliation, and
21
+ typed recovery states.
22
+
23
+ Use that lifecycle in the leverage widget so wallet rejection cannot appear as
24
+ chain confirmation, submitted hashes cannot be retried blindly, refreshed
25
+ quotes return to review, and completed permission evidence survives later
26
+ prompts.
27
+
28
+ Freeze the submitted Swap hash, chain, account, and asset identity in status
29
+ events so controlled host props cannot rewrite explorer links or settlement
30
+ copy while a transaction is pending.
31
+
32
+ Reject caller-provided V4 quoters that differ from the trusted Engine registry
33
+ before using their output in an executable minimum amount.
34
+
35
+ Pin Lend and Trade internal-swap quotes to the same block as their Engine
36
+ frame. Require a host price-impact limit, fail closed with typed reasons when
37
+ impact is unavailable or above that limit, and re-check the frame hash before
38
+ returning executable calldata. The Widget defaults this policy to 500 basis
39
+ points and exposes a host override.
40
+
41
+ Trade-open quotes now include a required `intent` echo. Update hand-built quote
42
+ fixtures to include owner, side, collateral, strategy, slippage, and impact cap.
43
+
44
+ Expose same-block DynamicFeeManager evidence as post-swap surge telemetry,
45
+ including manual-override changes, without presenting its adaptive tick
46
+ threshold as a Router price limit.
47
+
48
+ Keep the exposure asset in Long and Short actions, disclose the internal swap,
49
+ require acknowledgement for severe price impact, and lead with one compact
50
+ leverage-limit signal. The progress rail and success confirmation remain
51
+ CSS-only and honor reduced-motion preferences.
52
+
53
+ Floor compact minimum-receive copy instead of rounding it upward, while keeping
54
+ the exact executable amount accessible. Re-open review only when refreshed
55
+ market utilization changes at the precision shown to the user.
56
+
57
+ - 8234bad: Add trusted Ink Aegis Engine v1.0.3 support, upgrade the Engine SDK to 0.35.0, and expose Ink markets, positions, and history through the existing REST data source.
58
+ - e53591d: Install the approval authority the caller asked for, and stop bundling a Permit2
59
+ signature the chain will reject.
60
+
61
+ `approvePermit2ToRouter` read `amount` for truthiness, so an explicit `0n` — the
62
+ natural revoke, and the value `approveErc20ToPermit2` already takes for the
63
+ USDT-style reset — installed MAX_UINT160 with a far-future expiration instead.
64
+ `0n` now means zero, omitting `amount` still means maximum, and an amount wider
65
+ than uint160 is clamped.
66
+
67
+ The ERC-20 → Permit2, aggregator-router, and Permit2 → router gates each
68
+ short-circuited on amount alone, so "No limit" silently reused any allowance
69
+ that happened to cover the trade and nothing unlimited was ever installed. All
70
+ three are mode-aware now: `max` requires a standing grant that still reads as
71
+ effectively unlimited, `exact` is unchanged.
72
+
73
+ `authorizePermit` previously turned every non-rejection signing failure into an
74
+ on-chain approval. It now uses that fallback only for explicit unsupported
75
+ typed-data method codes. Disconnects, timeouts, internal RPC errors, and unknown
76
+ wallet failures abort without opening a broader approval prompt.
77
+
78
+ Permit2 branches on the owner's code, not the signature's shape, so a returned
79
+ but unacceptable signature — an ERC-6492 wrapper, or an ordinary 65-byte
80
+ signature from an EIP-7702-delegated EOA whose delegate has no ERC-1271 — would
81
+ revert the bundled swap. The signature is now checked the way Permit2 will check
82
+ it, and an unacceptable result fails closed before any transaction is sent.
83
+
84
+ The widget's approval prediction is mode-aware too. Once submission starts, the
85
+ executor's fresh prompt plan replaces that prediction, including a zero-reset,
86
+ and mined approvals remain credited if a later wallet prompt is rejected.
87
+
88
+ Zero-reset is now a token capability, not an inference from any finite standing
89
+ allowance. Hosts can set `requiresApprovalReset` on a token, and Ethereum USDT
90
+ keeps its well-known address rule. Ordinary ERC-20 allowance upgrades use one
91
+ approval transaction.
92
+
93
+ Submission now freezes quote state synchronously, including background requests
94
+ that were already in flight. Engine close also returns to review when a fresh
95
+ block-pinned quote introduces a router/operator authorization gate or widens a
96
+ token approval. Permit2 signature progress is complete only after its owner
97
+ verification path accepts the signature.
98
+
99
+ Leverage-open quotes now expose exact market utilization before and after the
100
+ final integer-rounded debt. Both values use the same block-pinned Core frame;
101
+ the widget shows them inside the compact Execution disclosure and never mixes
102
+ them with the REST market snapshot.
103
+
104
+ - 5d200cb: Improve Tap account equity and scoped estimated P&L, exact position navigation, permission progress and cancellation recovery, and unavailable chart states. Align asset direction, leverage and outcome currencies while preserving exact spending limits as the default.
105
+ - 6c6d894: Add a `layout` prop (`'vertical' | 'horizontal'`, default `'vertical'`) to the Engine and Leverage widgets, exported as `AegisEngineLayout`. `horizontal` re-flows Tap trading (the Trade surface with `showTradeChart`) into a trading-terminal view: a market bar across the top, the price chart in a wide left column, and a fixed-width order ticket on the right, with Positions beside the session activity rail. The grid engages once the widget is at least 640px wide and falls back to the vertical stack below that; Buy, Lend, Borrow, and Positions stay vertical. The root reflects the prop as `data-layout`, and the new `engine-layout.css` module sets `--aegis-trade-chart-height` on the chart region for the wide plot. Every widget still opens vertical unless a host opts in.
106
+ - 37b614d: Add a Thena presentation preset for BSC Tap integrations.
107
+
108
+ ### Patch Changes
109
+
110
+ - 7c3a598: Add bounded pool-candle, token-reference-line and qualified rate-history readers. Preserve source provenance, explicit gaps, APR semantics and display-only reference limitations without automatic fallback or wallet RPC reads.
111
+
112
+ Share bounded market-history requests with short caching and server-aware cooldowns, validate chart token units, and expose candle segments that preserve explicit gaps. Back off failed Widget pool-mark reads independently while keeping stale-price expiry and healthy-market polling.
113
+
114
+ - 2ab8cb1: Unify the trade chart across time windows and render recorded swap candles with visible dojis. Keep live pool observations distinct from swap OHLC, show empty-period and delayed-indexing states, and preserve gaps.
115
+ - c1f58b5: Value debt and equity from block-pinned SDK repayment legs instead of a balanced USD-price approximation. Missing or inconsistent pool reads withhold the USD estimate while retaining live ownership and risk state.
116
+ - c415d24: Name the partial-liquidation and full-repayment thresholds consistently in visible and accessible risk descriptions. Label the legacy time estimate with its full-repayment threshold and constant-rate assumptions.
117
+ - 6c6d894: Compact Tap trading into a chart, position or trade ticket, and portfolio workspace. Keep position navigation, entry-price navigation, spending-limit changes and explicit revocation in the existing workflows. Use consistent inset focus rings, responsive controls and reduced-motion disclosures.
118
+
119
+ Show current and estimated debt ratios while adding margin or reducing leverage. Repayment uses a display-only SDK projection; unavailable evidence stays unavailable. Keep deposit and leverage editable during trade review, block confirmation while a replacement quote is pending, and animate market utilization without overshoot. Preserve separate partial-reduction and full-repayment thresholds.
120
+
121
+ - 6c6d894: Tap trading draws one price chart for Live, 1H, 6H, 1D and target selection. Indexed 5-minute closes hold flat across verified coverage up to `coverage.completedThrough`, unobserved spans (not-yet-indexed buckets, declared gaps, live pauses) are dashed and labelled, and the live pool-state session is the tail of the same line. The plot's right edge follows the wall clock: Live scrolls continuously with a heartbeat on the last price, range switches morph the same line, and the current price stays visible while a target is chosen. The chart sizes itself from its box, so the horizontal layout's taller cell gets more gridlines and ticks without stretching text. The canvas `liveline` renderer is no longer used.
122
+ - 98f5187: Keep the indexed debt-action token ratio separate from executed entry price. The position card requires explicit receipt-reconciled entry evidence before displaying entry, price movement, or entry-based plans.
123
+ - e53591d: Fix two approval-path failures found by an audit of the approval work, and
124
+ correct the permissions sheet's surface label.
125
+
126
+ `approveErc20ToPermit2` and `approveErc20Spender` simulated `approve` against
127
+ viem's `erc20Abi`, which declares a `bool` return. Ethereum USDT returns no
128
+ data, so `decodeFunctionResult` threw `AbiDecodingZeroDataError` and the
129
+ approval failed before the wallet was ever asked — the token that
130
+ `requiresApprovalReset` exists for could not be approved at all, in either the
131
+ reset or the grant. Both writers now simulate against an approve ABI that
132
+ declares no outputs, which accepts the return-less and bool-returning shapes
133
+ alike. Nothing is lost: the returned value was already discarded, and the
134
+ post-write allowance read is what confirms the grant.
135
+
136
+ The aggregated-swap settlement floor is the stronger of the fresh and reviewed
137
+ minimums, but the calldata was still requested at the raw slippage tolerance
138
+ against the fresh route. KyberSwap embeds that tolerance in the bytes it
139
+ returns, so once the reviewed floor was the stronger of the two, the build could
140
+ not satisfy the floor it was then checked against and
141
+ `assertKyberCalldataMatchesQuote` rejected a build we had asked for. Any
142
+ in-tolerance price dip after review therefore failed the swap outright instead
143
+ of settling at the reviewed minimum. The build is now requested at the tightest
144
+ tolerance that still clears the settlement floor; the result never exceeds the
145
+ requested tolerance, so the wallet is only ever offered a stricter minimum than
146
+ the user set.
147
+
148
+ The permissions sheet's final footer hardcoded "Ready to open" on every surface,
149
+ so Lend and Borrow ended on trade wording while the surface-aware label was
150
+ computed and unreachable. Lend now reads "Ready to deposit" and Borrow "Ready to
151
+ borrow".
152
+
153
+ The permission rail's target and spender rows, and each row's Details
154
+ disclosure, reach assistive technology and touch: full addresses are no longer
155
+ tooltip-only, and each disclosure is named for its own permission. The
156
+ price-impact consent checkbox is named by the acknowledgement rather than by the
157
+ entire warning paragraph.
158
+
159
+ - Updated dependencies [ed4f81a]
160
+ - Updated dependencies [2c39b4b]
161
+ - Updated dependencies [603c625]
162
+ - Updated dependencies [df98b19]
163
+ - Updated dependencies [86da1ff]
164
+ - Updated dependencies [8d07a0b]
165
+ - Updated dependencies [7c3a598]
166
+ - Updated dependencies [c1f58b5]
167
+ - Updated dependencies [ec0018b]
168
+ - Updated dependencies [1c32ae1]
169
+ - Updated dependencies [e53591d]
170
+ - Updated dependencies [8234bad]
171
+ - Updated dependencies [e53591d]
172
+ - Updated dependencies [55c2173]
173
+ - Updated dependencies [98f5187]
174
+ - Updated dependencies [e53591d]
175
+ - @aegis-engine/core@0.8.0
176
+
177
+ ## 0.11.0
178
+
179
+ ### Minor Changes
180
+
181
+ - Refresh the widget layout, styling, amount transitions, permission review, and transaction progress across Swap, Borrow, Lend, and Leverage. Keep the chart visible during Leverage execution and show transaction links after confirmation.
182
+
183
+ Add editable spending limits, wallet-aware borrow limits, receipt-based swap amounts, and consistent confirmed transaction progress to support the updated widget experience.
184
+
185
+ Improve the landing site and playground with funded multi-chain demo portfolios, simulated transaction lifecycles, clearer wallet prompts, installation snippets, event inspection, sharing, reset controls, and walkthroughs. Tap Trading remains marked as coming soon.
186
+
187
+ ### Patch Changes
188
+
189
+ - 1727b9d: Expose settled borrow collateral sizing outcomes and align the Widget's advice,
190
+ button, retry, and existing-vault withdrawal review with them.
191
+ - Updated dependencies [1727b9d]
192
+ - Updated dependencies
193
+ - @aegis-engine/core@0.7.0
194
+
3
195
  ## 0.10.3
4
196
 
5
197
  ### Patch Changes
package/DESIGN.md CHANGED
@@ -50,7 +50,7 @@ runtime ships with the widget, and `prefers-reduced-motion` is respected.
50
50
 
51
51
  | Token | Default | Role |
52
52
  | --- | --- | --- |
53
- | `--aegis-switch-dur` | `260ms` | Segmented-pill glide and Sell/Buy token swap. `0ms` disables. |
53
+ | `--aegis-switch-dur` | `260ms` | Segmented-pill glide plus Sell/Buy, Add/Reduce, and Add/Withdraw switches. `0ms` disables. |
54
54
  | `--aegis-spring` | `cubic-bezier(0.22, 1, 0.36, 1)` | Easing for interactive state changes. |
55
55
  | `--aegis-ease` | `cubic-bezier(0.2, 0, 0, 1)` | Easing for entrances and transitions. |
56
56
 
package/README.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Amplifi Swap and Aegis Engine Widget
2
2
 
3
+ Opt in to paired lending with
4
+ `balancedLending={{ nativeGasReserve: yourReserveInWei }}` on
5
+ `AegisEngineWidget`, or embed `AegisEngineBalancedLend` directly.
6
+ `useEngineBalancedLend` exposes the same flow for custom layouts. See
7
+ [the integration guide](../../docs/balanced-lending.md) for the SDK release
8
+ dependency, wallet interface, scoped recovery and native-reserve semantics.
9
+
3
10
  Embed Amplifi Swap or Aegis Engine directly in a React application. Import the
4
11
  component and CSS, then configure networks, REST data, wallet handoff, and host
5
12
  styling through props.
@@ -29,6 +36,12 @@ and `viem ^2`. The package is ESM-only. Its only runtime dependencies are
29
36
  The published packages are self-contained: host applications do not need a
30
37
  GitHub Packages token for the Engine SDK.
31
38
 
39
+ The ESM build targets JavaScript syntax supported by Chrome/Edge 92+, Firefox 90+,
40
+ and Safari 15.4+, matching the widget's existing native `Array.prototype.at()` usage.
41
+ Build targets do not add runtime polyfills: hosts must also provide the APIs used
42
+ by their enabled flows, including `structuredClone()` in Engine core, and transpile
43
+ the package if they support older browsers.
44
+
32
45
  ## Basic Usage
33
46
 
34
47
  ```tsx
@@ -52,6 +65,7 @@ export function Engine({ account, provider }) {
52
65
  account={account}
53
66
  provider={provider}
54
67
  defaultSurface="buy"
68
+ maxEngineSwapPriceImpactBps={500}
55
69
  showTokenPriceHistory
56
70
  showEngineMarketHistory
57
71
  surfaces={['buy', 'trade', 'borrow', 'lend', 'positions']}
@@ -164,8 +178,37 @@ re-quotes after wallet authorization before submission.
164
178
  The user chooses Long or Short, a deposit, and leverage inside the live range
165
179
  returned by the quote. The widget shows opening LTV against the borrow limit,
166
180
  gross return at the configured target, entry-to-target price, opening price
167
- impact, and interest over the configured horizon. Engine positions do not have
168
- a single liquidation price; interest accrual increases LTV over time.
181
+ impact, block-pinned market utilization before and after opening, the exact
182
+ internal-swap minimum behind its compact floor, and interest over the configured
183
+ horizon. Engine positions do not have a single liquidation price; interest
184
+ accrual increases LTV over time.
185
+
186
+ ### Trade direction migration
187
+
188
+ Long/Short now refers to the displayed asset on every market. When exactly one
189
+ token is stable, the other token is the asset. Otherwise, when exactly one token
190
+ is native or the chain's trusted wrapped native token, the other token is the
191
+ asset. Remaining pairs use token0 as the asset.
192
+
193
+ For USDC-ETH, Long means Long ETH and Short means Short ETH. For BNB-QQQB, they
194
+ mean Long QQQB and Short QQQB. Prices are displayed in quote tokens per asset;
195
+ leverage and price scenarios follow the same asset exposure. Existing protocol
196
+ limits still apply: a flipped market's Long minimum may be 2×, depending on its
197
+ live quote. The widget does not create a new borrowing range.
198
+
199
+ `tradeDirections`, `defaultTradeDirection` and the `direction` field on
200
+ `onOnboardingEvent` events (`review-opened`, `review-closed`,
201
+ `authorization-started`, `position-opened`) all use this asset direction. Hosts
202
+ that previously restricted token0 exposure must invert `long` and `short` for
203
+ quote-first pairs to preserve their former intent; a host offering both
204
+ directions can keep both values. Update direction-specific copy and analytics
205
+ to name the asset, rather than assuming token0.
206
+
207
+ Core SDK requests and quotes, indexed activity, and stored position records
208
+ retain their protocol token-order direction. The widget converts those values
209
+ for display and maps asset intent back when quoting. Do not invert Core callback
210
+ values or rewrite stored position records. Exact spending limits remain the
211
+ default, and wallet authorization and transaction order are unchanged.
169
212
 
170
213
  For a separate Long/Short experience that starts without
171
214
  Buy/Borrow/Lend/Positions tabs, mount `AegisLeverageWidget`:
@@ -181,6 +224,7 @@ export function LongShort({ account, provider }) {
181
224
  provider={provider}
182
225
  chains={engineChains}
183
226
  engineDataSource={{ kind: 'rest', baseUrl: '/api/engine' }}
227
+ maxEngineSwapPriceImpactBps={500}
184
228
  tradeLeverageOptions={[1.25, 1.5, 2, 3]}
185
229
  defaultTradeLeverage={1.5}
186
230
  onboarding={{ mode: 'guided' }}
@@ -189,6 +233,26 @@ export function LongShort({ account, provider }) {
189
233
  }
190
234
  ```
191
235
 
236
+ ### Layout
237
+
238
+ Every widget ships as a single vertical column (`layout="vertical"`, the
239
+ default). Tap trading — the Trade surface with `showTradeChart` — can also
240
+ run as a horizontal trading terminal:
241
+
242
+ ```tsx
243
+ <AegisLeverageWidget {...props} showTradeChart layout="horizontal" />
244
+ ```
245
+
246
+ `horizontal` re-flows the same blocks the way perps terminals do: a market bar
247
+ across the top (pair picker, liquidity, financing rate), the price chart in a
248
+ wide left column, and a fixed-width order ticket on the right (Long/Short,
249
+ deposit, leverage, estimate, execution details, CTA). Positions sit below the chart and ticket, without a separate top navigation tab. The grid engages once
250
+ the widget itself is at least 640px wide and falls back to the vertical stack
251
+ below that, so a narrow embed never scrolls horizontally. The widget caps
252
+ itself at 1280px; give it a wide container. Buy, Lend, Borrow, and Positions
253
+ stay vertical on the Engine widget. The root carries `data-layout` for host
254
+ styling either way.
255
+
192
256
  This is the frontend integration interface; the host does not call the Engine
193
257
  SDK directly. The host still supplies wallet connectivity, chain/router
194
258
  configuration, and an Engine data source or same-origin proxy. Trade offers
@@ -272,6 +336,7 @@ export function GameMarket({
272
336
  return (
273
337
  <AegisEngineWidget
274
338
  partnerContext={partnerContext}
339
+ maxEngineSwapPriceImpactBps={500}
275
340
  partnerContextVariant="embedded"
276
341
  onPartnerRequirementAction={(requirement, surface) => {
277
342
  console.log(surface, requirement.id)
@@ -350,6 +415,7 @@ const wolfResources = {
350
415
  <AegisEngineWidget
351
416
  chainId={1}
352
417
  enabledChainIds={[1]}
418
+ maxEngineSwapPriceImpactBps={500}
353
419
  marketResource={wolfResources[selectedResource]}
354
420
  />
355
421
  ```
@@ -462,6 +528,12 @@ host supplies `engineDataSource`. Static or offline Engine integrations use
462
528
  `backendBaseUrl={null}` disables token-price history and backend reads for the
463
529
  nested Buy surface; it does not change Engine market discovery.
464
530
 
531
+ For a static source, the widget's best-effort latest vault-activity tail can
532
+ query the public Engine subgraph directly from the browser. The request carries
533
+ the chain and vault identifier. Use a REST source or a host-owned proxy when
534
+ client-side indexer access is not acceptable; fully offline fixtures should
535
+ supply `vaultActivity` with their static position data.
536
+
465
537
  The backend-enabled network list comes from `GET /v1/config` (`chains[]`). By
466
538
  default the widget exposes every backend chain it can configure. Projects that
467
539
  only support a subset should pass `enabledChainIds`; the first entry becomes
@@ -516,9 +588,9 @@ Token icons are hydrated from the same metadata table used by the Aegis website:
516
588
 
517
589
  `aegis-swap-widget` is the production widget SDK. It uses real providers, RPCs,
518
590
  pool config, approvals, Permit2 authorization, swap submission, and callbacks.
519
- Pull requests publish the package demo to the Cloudflare Pages branch URL
520
- reported by Wrangler, for example
521
- `https://pr-<number>.aegis-widget-preview.pages.dev`.
591
+ The Cloudflare Pages package demo deploys only from trusted `main` code while
592
+ the repository uses a Global API Key. Pull requests run the full CI gate but do
593
+ not receive Cloudflare credentials.
522
594
 
523
595
  Demo wallets, fake transaction flows, scenario controls, and mock host shells
524
596
  belong in the playground app (`apps/playground` in this monorepo). They are not
@@ -538,12 +610,31 @@ override points at the intended Aegis or Uniswap deployment. Source those values
538
610
  from your own audited config or backend, not from user input.
539
611
 
540
612
  `onSubmitted`, `onSuccess`, `onError`, `onQuote`, `onStatusChange`,
541
- `onPoolChange`, `onAuthorizationPlan`, `onAuthorizationStepChange`, and
542
- `onOnboardingEvent` are the supported host signals. The in-widget "Latest tx"
613
+ `onPoolChange`, `onAuthorizationPlan`, `onAuthorizationStepChange`,
614
+ `onTradeExecutionChange`, and `onOnboardingEvent` are the supported host signals. The in-widget "Latest tx"
543
615
  drawer is a session-local UI receipt for the most recent confirmed swap; it is
544
616
  not a transaction history API. If a host needs durable history, record
545
617
  `onSubmitted`/`onSuccess` on the host side.
546
618
 
619
+ `onTradeExecutionChange` emits the complete Long/Short execution session. Use
620
+ its stable `sessionId`, monotonic `sequence`, `occurredAt`, `chainId`, and
621
+ `quoteRevision` to correlate wallet rejection, submission, quote review, and
622
+ recovery before a transaction hash exists. The raw callback also contains the
623
+ Core quote, plan, and bigint values; do not serialize it directly. Project the
624
+ JSON-safe fields through the versioned event schema, then run the exported
625
+ `validateAegisWidgetEventSemantics` helper from
626
+ `aegis-swap-widget/agent/validate-events` for matching-step and matching-hash
627
+ invariants.
628
+
629
+ `onStatusChange` remains the small Swap rail payload. To store the same
630
+ versioned event envelope, call `projectAegisSwapStatusEvent` from
631
+ `aegis-swap-widget/agent/events`. The host creates `sessionId` before the first
632
+ wallet request, increments `sequence` for every status event and
633
+ `quoteRevision` whenever `onQuote` replaces the executable quote, stamps
634
+ `occurredAt`, and retains the reviewed `chainId` until the attempt reaches a
635
+ terminal outcome. The projector copies only schema fields; validate its result
636
+ with the v1 schema and semantic validator before persistence.
637
+
547
638
  ## Appearance
548
639
 
549
640
  Hosts can choose the widget surface and brand accent at instantiation time:
@@ -884,14 +975,19 @@ mirror that state outside the widget three ways:
884
975
  `onStatusChange` fires a snapshot on every lifecycle transition. `walletPrompts`
885
976
  is the SDK-owned provider-prompt plan: ERC20 approval, Permit2 authorization,
886
977
  and swap submission are counted from the current allowance/authorization reads.
887
- Use that for step copy or external rails instead of guessing from status names:
978
+ A USDT-style token that reverts a non-zero → non-zero `approve` adds one more
979
+ prompt: the widget resets the standing allowance to zero first. Both approvals
980
+ report `status: 'approving'`, but they are counted and completed separately.
981
+ Use `walletPrompts` for step copy or external rails instead of guessing from
982
+ status names:
888
983
 
889
984
  ```tsx
890
985
  <AegisSwapWidget
891
- onStatusChange={({ status, progress, walletPrompts, txHash, error }) => {
986
+ onStatusChange={({ status, progress, walletPrompts, txHash, transaction, error }) => {
892
987
  // status: 'idle' | 'approving' | 'signing' | 'submitting' | 'success'
893
988
  // progress: 'pending' | 'mining' | 'success' | 'error' | null (rail hidden)
894
989
  // walletPrompts: { total, completed, active } // active is 1-based or null
990
+ // transaction: submission-time chain/account/token identity after broadcast
895
991
  // error: user-facing message, e.g. "Request rejected."
896
992
  }}
897
993
  />
@@ -901,6 +997,11 @@ The rail separates step completion from activity: `completePct` fills the calm
901
997
  completed portion (for example 33.3% after one of three wallet prompts), while
902
998
  the pending/mining shimmer is always a full-width top-border sweep.
903
999
 
1000
+ Once a transaction is broadcast, `transaction` freezes its `hash`, `chainId`,
1001
+ `account`, input/output token identity, and explorer URL. Use this context for
1002
+ pending, timeout, failure, and success UI: controlled host props may already
1003
+ describe a different chain or market while the submitted transaction settles.
1004
+
904
1005
  Errors never appear in `status` (the submit machine resets to `'idle'`); read
905
1006
  them from `progress === 'error'` plus `error`. For classifying the raw `Error`
906
1007
  from `onError`, import `isUserRejectedError` from `@aegis-engine/core`.
@@ -1035,18 +1136,19 @@ package keep two independent toast stores (and two viewports).
1035
1136
 
1036
1137
  ## Motion
1037
1138
 
1038
- Switching pools or the approval mode glides a single active pill between the
1039
- options (iOS-segmented-control style), and the Sell/Buy token pills cross-fade
1040
- when a switch retargets them. Motion uses CSS plus the browser Web Animations
1041
- API for the bottom-sheet entrance; no third-party animation runtime ships with
1042
- the widget. Every animation respects `prefers-reduced-motion` automatically.
1139
+ Switching pools, approval mode, Add/Reduce, or Add/Withdraw glides a single
1140
+ active pill between the options (iOS-segmented-control style), and the Sell/Buy
1141
+ token pills cross-fade when a switch retargets them. Motion uses CSS plus the
1142
+ browser Web Animations API for the bottom-sheet entrance; no third-party
1143
+ animation runtime ships with the widget. Every animation respects
1144
+ `prefers-reduced-motion` automatically.
1043
1145
 
1044
1146
  Hosts tune or disable the switch motion through CSS tokens on the `style` prop:
1045
1147
 
1046
1148
  ```tsx
1047
1149
  <AegisSwapWidget
1048
1150
  style={{
1049
- '--aegis-switch-dur': '180ms', // pill glide + token swap; '0ms' disables
1151
+ '--aegis-switch-dur': '180ms', // segmented/action glide + token swap; '0ms' disables
1050
1152
  '--aegis-spring': 'cubic-bezier(0.2, 0, 0, 1)' // switch easing
1051
1153
  }}
1052
1154
  />
@@ -1093,6 +1195,7 @@ No other props changed. See the [CHANGELOG](./CHANGELOG.md) for the full entry.
1093
1195
  - `poolIds`: optional pool id order/subset. Use this when the host wants to hide pools or control ordering.
1094
1196
  - `defaultDirection`: `buy` (counter token into the pool token) or `sell` (pool token into the counter token). Defaults to `buy`.
1095
1197
  - `defaultSlippagePercent`: number (canonical) or numeric string, in percent. Defaults to `1`.
1198
+ - `maxEngineSwapPriceImpactBps`: maximum block-pinned price impact for Engine internal swaps, in basis points. Lend and Trade fail closed above it or when impact cannot be assessed. Defaults to `500` (5%); valid range is `0` through `10000`. This is an SDK/Widget gate, not a Router-level pool-price invariant.
1096
1199
  - `rpcUrls`: RPC fallback list for the active chain, or a `{ [chainId]: string[] }` map for multichain hosts.
1097
1200
  - `backendBaseUrl`: REST origin for Swap discovery and token-price history, and for the Engine widget's nested Buy surface. Defaults to the Aegis production backend. Engine market and position discovery is controlled separately by `engineDataSource`.
1098
1201
  - `backendRequestTimeoutMs`: timeout for backend REST reads. Defaults to 30000 ms.
@@ -1106,9 +1209,18 @@ No other props changed. See the [CHANGELOG](./CHANGELOG.md) for the full entry.
1106
1209
  - `onSurfaceChange`: Engine callback fired when the active unified tab changes (`'buy'`, `'trade'`, `'borrow'`, `'lend'`, or `'positions'`).
1107
1210
  - `marketResource`: controlled Lend/Borrow market locator (`chainId`, token `address`, and `symbol`). On the active chain, the widget resolves one eligible Engine market, hides its picker, and fails closed on missing or ambiguous matches. It does not lock token direction. Use `marketId` only as an optional disambiguator for the same resource.
1108
1211
  - `surfaces`: Engine tabs to expose. Defaults to `['buy', 'borrow', 'lend', 'positions']`. Add `'trade'` to opt into the Long/Short surface (see Trade surface).
1109
- - `tradeDirections`: directions offered on the Trade surface. Defaults to `['long', 'short']`.
1110
- - `defaultTradeDirection`: initial Trade direction. Defaults to the first `tradeDirections` entry.
1212
+ - `tradeDirections`: asset directions offered on the Trade surface. Defaults to `['long', 'short']`; see [Trade direction migration](#trade-direction-migration).
1213
+ - `defaultTradeDirection`: initial asset direction. Defaults to the first `tradeDirections` entry.
1111
1214
  - `tradeDirectionSelector`: Long/Short selector visibility — `'auto'` (default) hides it when `tradeDirections` resolves to a single entry, `'always'`, or `'never'`.
1215
+ - `showTradeChart`: display-only pool history and live observations on the Trade surface (Tap trading). Defaults to `false`.
1216
+ - `requireTradeLtvAcknowledgement`: defaults to `false`. Set `true` to require explicit acknowledgement when a trade quote is near the borrowing limit. This does not change contract limits, quote validation, or price-impact checks.
1217
+ - `tradeDetails`: `'compact'` (Tap default) or `'expanded'`. Compact reviews show the deposit and leverage without execution diagnostics.
1218
+ - `showTradePositions`: show positions beneath the Tap chart and ticket. Defaults to `true`.
1219
+ - `tradeSuccessDurationMs`: return from successful Tap execution to the chart after this delay. Defaults to `0`, keeping the receipt open until explicitly dismissed.
1220
+
1221
+ Tap uses a single workspace without top section tabs. The chart starts as a line; its Candles control uses the same OHLC history and stays disabled when no candles are available. Verified entry lines are restored from the opening-execution API, scoped to the account, network, vault, pool and token pair. Unavailable execution evidence is never replaced by the reviewed quote. Entry is the opening swap price, not wallet cost basis or net P&L.
1222
+
1223
+ - `layout`: `'vertical'` (default) or `'horizontal'`. Horizontal turns Tap trading (Trade surface with `showTradeChart`) into a terminal view — market bar on top, chart left, order ticket right — once the widget is at least 640px wide; narrower embeds fall back to the vertical stack. Other surfaces stay vertical. Reflected on the root as `data-layout` (see Layout under Trade surface).
1112
1224
  - `tradeLeverageOptions`: shortcuts shown below the quote-driven leverage slider. Defaults to `[2]`, with a separate live `Max` shortcut; preset values must be above `1` and no greater than `5`. The live Engine quote, not this list, sets the actual minimum and maximum.
1113
1225
  - `defaultTradeLeverage`: initial Trade leverage. Defaults to `1.5` and does not need to match a shortcut.
1114
1226
  - `tradeHorizonDays`: horizon used to size the directional position and estimate interest. Defaults to `30`.
@@ -1118,6 +1230,7 @@ No other props changed. See the [CHANGELOG](./CHANGELOG.md) for the full entry.
1118
1230
  - `permissionRailColor`: optional Engine permission-step rail color. It defaults to `accentColor` and derives readable rail ink automatically.
1119
1231
  - `onAuthorizationPlan`: called after the widget reads the connected account's live Long/Short authorization plan.
1120
1232
  - `onAuthorizationStepChange`: called with `requesting` and `confirmed` progress for each required vault, token, Permit2, and final-open action.
1233
+ - `onTradeExecutionChange`: called for every Long/Short execution-session transition, including wallet request, submitted hash, confirmation, typed failure, quote review, and recovery. Its session metadata is stable and JSON-safe; the full quote and plan remain in-process values.
1121
1234
  - `onOnboardingEvent`: product lifecycle callback for education, review, authorization start, and confirmed-position events.
1122
1235
  - `buySwapConfig`: optional host overrides for the nested Engine Buy surface only. Use it to constrain Buy to a chain, pool set, or controlled `poolId` without changing Engine market discovery or the Lend/Borrow/Positions surfaces.
1123
1236
  - `showBuySettings`: show the Engine Buy surface's slippage-settings control. Defaults to `false`.
@@ -1198,7 +1311,62 @@ Local `pnpm pack:check` still runs each package's `prepack` build sequentially.
1198
1311
 
1199
1312
  ```bash
1200
1313
  pnpm changeset # in your PR: pick aegis-swap-widget + bump, write the entry
1201
- # Merge the PR; the Release workflow opens a "Version Packages" PR on main.
1314
+ # After merge and successful release gates, Changesets opens the version PR.
1202
1315
  # Merging that PR publishes to npm via OIDC trusted publishing.
1203
1316
  npm view aegis-swap-widget version
1204
1317
  ```
1318
+
1319
+ ## Account portfolio
1320
+
1321
+ Custom React account pages can selectively import account/activity/status hooks,
1322
+ `useEnginePositionHistory`, `useEngineHistoryPositions`, and
1323
+ `useEngineTransactionHistory` from `aegis-swap-widget/hooks`. This entry imports
1324
+ no stock components or CSS. The transaction hook uses Core's shared metadata,
1325
+ replacement and bounded receipt-recovery rules. History hooks return one page
1326
+ with explicit coverage; passing `null` disables the read. See
1327
+ `docs/package-data-contracts.md` in the repository for examples and the qualified
1328
+ React 18/19, Node and TypeScript matrix.
1329
+
1330
+ Enable `accountPortfolio={{ chainIds: [1, 8453], layout: 'compact' }}` on `AegisEngineWidget` to use the shared account view on Positions. The selected chains must also be enabled by the host. This requires the new portfolio, paged-activity and transaction-status backend APIs; an unavailable service is shown explicitly. Omit the option to keep the existing embedded Positions presentation.
1331
+
1332
+ For a separate account page, use `AegisEnginePortfolio` with a REST `source`, `account`, and `chainIds`. It supports compact/full layout, controlled network filtering, theme/style, labels, position actions, and header/summary/position/footer slots. Hosts can also consume `useEngineAccountPortfolio`, `useEngineAccountActivity`, and `useEngineAccountTransactionStatus` directly. These share Core's identity, amount, coverage and read contracts.
1333
+
1334
+ Both the embedded REST Positions panel and `AegisEnginePortfolio` include a lazy **Engine position history** section. On the account component, `showHistory={false}` hides it. Hosts must proxy `GET /v1/engine/positions/history/catalog` (including `ownerScope`, `limit`, and `cursor`) and `GET /v1/engine/positions/history` (including `kind`, `poolId`, optional `vaultId`, `window`, and `before`). These are private, uncached reads. The playground forwards both routes under `/api/engine`.
1335
+
1336
+ History defaults to current or last-owned vaults and includes closed positions. **Include previously owned vaults** requests `ownerScope=ever-owned`; unsupported indexing produces an explicit unavailable state, with no silent fallback. Borrow records cover the vault lifetime across owners, not wallet profit. Recorded values retain missing USD marks, assumed-price evidence, gaps, and page coverage. Catalog pagination rejects a changed deployment/frame or expired cursor; changing wallet, source, or network clears the prior selection.
1337
+
1338
+ The view separates gross assets, debt, net equity and supplied value, retains known subtotals for incomplete pricing, and shows each network's frame separately. Performance stays unavailable without complete entry/cash-flow evidence. A management callback is disabled while a snapshot is stale, expired or still catching up to an acknowledged transaction. The stock widget additionally checks live position ownership and existing action guards.
1339
+
1340
+ Activity joins local and indexed records by chain and transaction hash and combines split-page events. Lending amounts say spent/received; vault deltas say vault balance change. An indexed event does not imply a checked receipt. A confirmed transaction is reflected in the portfolio only after backend acknowledgement and a sufficiently recent displayed frame.
1341
+
1342
+ Engine transaction hashes and safe display metadata persist in localStorage by wallet and network by default. `transactionStorage` accepts host storage with synchronous `getItem`/`setItem`, or `null` for memory-only history. Storage is best effort and local to the host origin/device. Known pending transactions survive remount and block new actions until the existing receipt reconciler resolves them. Checking status never signs, broadcasts, or reconstructs the original transaction; after confirmation the widget refreshes live positions. Signature/permit payloads and executable drafts are not saved. Future reorgs remain possible after receipt confirmation.
1343
+
1344
+ History synchronizes sibling embeds and merges storage events from other tabs. Superseded hashes remain attached to their replacement, including out-of-order observations. A price-only speed-up can confirm the original action; a replacement that changed execution stays cancelled even after a timeout and reload. Engine ERC-20, Permit2, vault and share authorizations use a separate stage: their confirmation does not announce a portfolio update or fire a final-action success callback. Direct swap hosts can consume `onTransactionObservation` with its frozen account and chain. Pending-history persistence requires working host storage; storage errors are shown explicitly.
1345
+
1346
+ ### Headless completed-trade PnL
1347
+
1348
+ `useEnginePositionPnl(input)` accepts the Core `AegisEnginePositionPnlInput`, or
1349
+ `null` to disable the read. Pass the same account, chain, pool, vault and retained
1350
+ accounting `snapshotId`. It returns `{ data, pending, error, refresh }`, reads once
1351
+ when that scope changes and never starts a polling loop. `refresh()` is explicit
1352
+ and honors the API's Retry-After cooldown. Changed selections hide old results;
1353
+ replaced requests are cancelled, and expired PnL is cleared.
1354
+
1355
+ Render `data.status === 'token-pnl'` as separate token gains/losses. Render an
1356
+ unavailable reason separately from zero. Execution gas is only part of transaction
1357
+ cost, and the result does not supply historical USD or total economic PnL. This
1358
+ hook is an optional host integration and does not enable the live chart.
1359
+
1360
+
1361
+ ### Thena presentation preset
1362
+
1363
+ Import `THENA_TAP_PRESET` from `aegis-swap-widget/presets/thena` and spread it on
1364
+ `AegisLeverageWidget` for BSC, horizontal Tap layout and Thena's dark orchid theme.
1365
+ Supply a controlled `marketId` to connect a host-owned market rail. Import
1366
+ `aegis-swap-widget/styles.css` once in the host.
1367
+
1368
+ This preset contains presentation defaults only. The host owns its market scope,
1369
+ wallet provider, account, data source and access policy. It does not enable a
1370
+ network in the production API or provide share-multiplier conversion. The
1371
+ playground's `/thena` route demonstrates the composition with a live injected
1372
+ wallet. Approvals, signatures and trades require the user's wallet confirmation.
@@ -0,0 +1,25 @@
1
+ # Third-party notices
2
+
3
+ The shared value display includes `torph` 0.1.2 under the MIT License:
4
+
5
+ MIT License
6
+
7
+ Copyright (c) 2025 Lochie Axon
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.