@kasufinance/kasu-sdk 2.10.3 → 2.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.
package/README.md CHANGED
@@ -149,6 +149,7 @@ application formats them in its own design system and language.
149
149
  | Yields | `weeklyInterest`, `dailyInterest`, `accruedInterest`, `projectedAnnualEarnings`, `weightedAverageApy`, `SECONDS_PER_WEEK` — NET of the performance fee |
150
150
  | Batch proof | `validateDepositBatchCalls`, `proveDepositInReceipt`, `DepositBatchMismatchError`, `ENTRY_POINT_V07` |
151
151
  | Tranche display name | `getTrancheDisplayName`, `UPPER_MEZZANINE` |
152
+ | Strategy summary | `pickShortDescription` — the CMS short blurb as one line of plain text, or `undefined` (also on every `Strategy` as `summary`) |
152
153
  | Requests | `deriveRequestState`, `submissionEvents`, `countSubmissions`, `firstSubmissionTimestamp`, `isCycleClosed` |
153
154
  | Settlement | `computeSettlementWindow`, `nextCycleBoundary`, `deriveCycleDates`, `CLEARING_WINDOW_SECONDS` |
154
155
  | Loan contract | `encodeDepositData`, `buildContractVersionType`, `buildLoanAgreementSignMessage`, `buildLegacyContractRequestMessage`, `buildFullNameRequestMessage`, `formatSignTimestampUtc`, `parseFormattedMessage`, `asContractType` |
@@ -169,6 +170,14 @@ Three rules worth knowing:
169
170
  wrong number when an input is out of domain. Render that as "no rate", never
170
171
  as zero, and never substitute a fee of `0` for one you have not loaded — a
171
172
  fee-less rate overstates what a lender earns.
173
+ - **`Strategy.summary` is CMS editorial, cleaned, never authored.** It is
174
+ `liteDescription` when usable, else the first paragraph of `description`,
175
+ with inline markdown markers stripped and whitespace collapsed to one line.
176
+ The `"Not Available"` placeholder and a blank value count as missing, and an
177
+ absent blurb is `undefined`: what to show instead is the app's decision.
178
+ `liteDescription` and `description` stay the raw CMS values. It is NOT
179
+ sanitised: HTML tags and link syntax pass through unchanged, so render it
180
+ as text, never as HTML or markdown.
172
181
  - **The tranche rename is display-only.** `getTrancheDisplayName` maps the
173
182
  `Senior` tranche to "Upper Mezzanine" on Apxium strategies, because the true
174
183
  senior position is held by an institutional lender. Call it at the view
@@ -558,6 +567,14 @@ network problem cannot fail a pull request that did not touch the network.
558
567
  CI runs `build-tc`, `build`, `test:unit` and `rollup-build` on every pull
559
568
  request.
560
569
 
570
+ `npm ci` also installs a **pre-push hook** (`.githooks/pre-push`) that runs the
571
+ same steps locally before every `git push`: first a lockfile check
572
+ (`npm ci --dry-run`, which fails when `package.json` and `package-lock.json`
573
+ disagree), then `build-tc`, `build`, `test:unit` and `rollup-build`. It stops at
574
+ the first failing step and names it. It checks the working tree, not the pushed
575
+ commits, so commit first. `SKIP_PREPUSH=1 git push` skips it with a warning; CI
576
+ is still the gate.
577
+
561
578
  ## Versioning & publishing
562
579
 
563
580
  The package follows semantic versioning. The published runtime entry is the
@@ -27545,6 +27545,82 @@ function maxNetRateCeiling(pools, feePercent) {
27545
27545
  return rate;
27546
27546
  }
27547
27547
 
27548
+ /**
27549
+ * A strategy's SHORT blurb, as plain text: the CMS `liteDescription` first,
27550
+ * else the first paragraph of the long `description`, else nothing.
27551
+ *
27552
+ * Lifted from kasu-ui (`pickShortDescription`, its deposit dialog and landing
27553
+ * strategy card) so every app shows the same line, and pinned to its output
27554
+ * for every live CMS row. The rules are facts about how the CMS is authored,
27555
+ * not formatting preferences:
27556
+ *
27557
+ * - `liteDescription` IS THE SHORT ONE. `description` is the credit
27558
+ * originator's several-paragraph profile; on a card it is a wall.
27559
+ * - `"Not Available"` IS A PLACEHOLDER, not editorial. Several rows carry it
27560
+ * verbatim, and it must read as missing, not print. Matched on the whole
27561
+ * trimmed value, case-insensitively. It applies to `liteDescription` only.
27562
+ * - EMPTY OR BLANK IS MISSING. The service maps a pool with no CMS record to
27563
+ * `''`.
27564
+ * - THE FIELDS HOLD MARKDOWN. `liteDescription` can open with a `**bold**`
27565
+ * lead, and the surfaces this feeds render plain text, so the markers are
27566
+ * stripped (bold, then italic, then inline code).
27567
+ * - AND HARD NEWLINES. Every run of whitespace becomes one space, so a
27568
+ * paragraph break inside the value is not a gap in a one-line slot.
27569
+ * - NOT SANITISED. "Plain text" means text to render AS text. HTML tags,
27570
+ * entities and link syntax (`<script>`, `&lt;`, `[a](javascript:…)`) pass
27571
+ * through unchanged, and removing markers can join fragments into a tag
27572
+ * (`<scr**i**pt>` becomes `<script>`). Render it as a text node, never as
27573
+ * HTML or markdown.
27574
+ *
27575
+ * Two refinements over the kasu-ui original, neither reachable by any live
27576
+ * row: the cleaned text is trimmed (a CRLF value no longer ends in a space),
27577
+ * and a `liteDescription` that cleans to nothing (`** **`) counts as missing,
27578
+ * so the result is never a blank string.
27579
+ *
27580
+ * This authors no string of its own. It selects and cleans editorial the CMS
27581
+ * already holds, and an absent blurb is `undefined`, never a fallback sentence:
27582
+ * what "no blurb" means is the render site's decision.
27583
+ *
27584
+ * Pure. A value that is not a string reads as missing.
27585
+ */
27586
+ function pickShortDescription(source) {
27587
+ var _a;
27588
+ const lite = asTrimmed(source.liteDescription);
27589
+ if (lite && !NOT_AVAILABLE.test(lite)) {
27590
+ const summary = toOneLine(lite);
27591
+ if (summary)
27592
+ return summary;
27593
+ }
27594
+ const long = asTrimmed(source.description);
27595
+ if (long) {
27596
+ const firstParagraph = (_a = long.split(PARAGRAPH_BREAK, 1)[0]) !== null && _a !== void 0 ? _a : long;
27597
+ return toOneLine(firstParagraph) || undefined;
27598
+ }
27599
+ return undefined;
27600
+ }
27601
+ const NOT_AVAILABLE = /^not available$/i;
27602
+ const PARAGRAPH_BREAK = /\n\s*\n/;
27603
+ function asTrimmed(value) {
27604
+ return typeof value === 'string' ? value.trim() : '';
27605
+ }
27606
+ /** Markers off, whitespace runs to one space, ends trimmed. `''` when nothing is left. */
27607
+ function toOneLine(text) {
27608
+ return stripInlineMarkdown(text).replace(/\s+/gu, ' ').trim();
27609
+ }
27610
+ /**
27611
+ * Inline markdown markers off, in the order bold → italic → code. The bold
27612
+ * passes consume every `**` / `__` pair first, so the italic patterns can match
27613
+ * a lone `*` / `_` without lookarounds.
27614
+ */
27615
+ function stripInlineMarkdown(input) {
27616
+ return input
27617
+ .replace(/\*\*(.+?)\*\*/g, '$1')
27618
+ .replace(/__(.+?)__/g, '$1')
27619
+ .replace(/\*(.+?)\*/g, '$1')
27620
+ .replace(/_(.+?)_/g, '$1')
27621
+ .replace(/`([^`]+)`/g, '$1');
27622
+ }
27623
+
27548
27624
  /**
27549
27625
  * High-level facade for browsing Kasu lending strategies (pools).
27550
27626
  *
@@ -27731,6 +27807,7 @@ class StrategiesFacade {
27731
27807
  subheading: nonEmptyOrUndefined(pool.subheading),
27732
27808
  description: pool.description,
27733
27809
  liteDescription: nonEmptyOrUndefined(pool.liteDescription),
27810
+ summary: pickShortDescription(pool),
27734
27811
  isActive: pool.isActive,
27735
27812
  apy: pool.apy,
27736
27813
  tvl: pool.totalValueLocked,
@@ -29203,6 +29280,7 @@ exports.parseMinorUnits = parseMinorUnits;
29203
29280
  exports.parseTrancheBound = parseTrancheBound;
29204
29281
  exports.pickDefaultTrancheId = pickDefaultTrancheId;
29205
29282
  exports.pickHighestYieldTranche = pickHighestYieldTranche;
29283
+ exports.pickShortDescription = pickShortDescription;
29206
29284
  exports.poolAllTranchesFull = poolAllTranchesFull;
29207
29285
  exports.poolMaxApy = poolMaxApy;
29208
29286
  exports.projectedAnnualEarnings = projectedAnnualEarnings;
@@ -27543,6 +27543,82 @@ function maxNetRateCeiling(pools, feePercent) {
27543
27543
  return rate;
27544
27544
  }
27545
27545
 
27546
+ /**
27547
+ * A strategy's SHORT blurb, as plain text: the CMS `liteDescription` first,
27548
+ * else the first paragraph of the long `description`, else nothing.
27549
+ *
27550
+ * Lifted from kasu-ui (`pickShortDescription`, its deposit dialog and landing
27551
+ * strategy card) so every app shows the same line, and pinned to its output
27552
+ * for every live CMS row. The rules are facts about how the CMS is authored,
27553
+ * not formatting preferences:
27554
+ *
27555
+ * - `liteDescription` IS THE SHORT ONE. `description` is the credit
27556
+ * originator's several-paragraph profile; on a card it is a wall.
27557
+ * - `"Not Available"` IS A PLACEHOLDER, not editorial. Several rows carry it
27558
+ * verbatim, and it must read as missing, not print. Matched on the whole
27559
+ * trimmed value, case-insensitively. It applies to `liteDescription` only.
27560
+ * - EMPTY OR BLANK IS MISSING. The service maps a pool with no CMS record to
27561
+ * `''`.
27562
+ * - THE FIELDS HOLD MARKDOWN. `liteDescription` can open with a `**bold**`
27563
+ * lead, and the surfaces this feeds render plain text, so the markers are
27564
+ * stripped (bold, then italic, then inline code).
27565
+ * - AND HARD NEWLINES. Every run of whitespace becomes one space, so a
27566
+ * paragraph break inside the value is not a gap in a one-line slot.
27567
+ * - NOT SANITISED. "Plain text" means text to render AS text. HTML tags,
27568
+ * entities and link syntax (`<script>`, `&lt;`, `[a](javascript:…)`) pass
27569
+ * through unchanged, and removing markers can join fragments into a tag
27570
+ * (`<scr**i**pt>` becomes `<script>`). Render it as a text node, never as
27571
+ * HTML or markdown.
27572
+ *
27573
+ * Two refinements over the kasu-ui original, neither reachable by any live
27574
+ * row: the cleaned text is trimmed (a CRLF value no longer ends in a space),
27575
+ * and a `liteDescription` that cleans to nothing (`** **`) counts as missing,
27576
+ * so the result is never a blank string.
27577
+ *
27578
+ * This authors no string of its own. It selects and cleans editorial the CMS
27579
+ * already holds, and an absent blurb is `undefined`, never a fallback sentence:
27580
+ * what "no blurb" means is the render site's decision.
27581
+ *
27582
+ * Pure. A value that is not a string reads as missing.
27583
+ */
27584
+ function pickShortDescription(source) {
27585
+ var _a;
27586
+ const lite = asTrimmed(source.liteDescription);
27587
+ if (lite && !NOT_AVAILABLE.test(lite)) {
27588
+ const summary = toOneLine(lite);
27589
+ if (summary)
27590
+ return summary;
27591
+ }
27592
+ const long = asTrimmed(source.description);
27593
+ if (long) {
27594
+ const firstParagraph = (_a = long.split(PARAGRAPH_BREAK, 1)[0]) !== null && _a !== void 0 ? _a : long;
27595
+ return toOneLine(firstParagraph) || undefined;
27596
+ }
27597
+ return undefined;
27598
+ }
27599
+ const NOT_AVAILABLE = /^not available$/i;
27600
+ const PARAGRAPH_BREAK = /\n\s*\n/;
27601
+ function asTrimmed(value) {
27602
+ return typeof value === 'string' ? value.trim() : '';
27603
+ }
27604
+ /** Markers off, whitespace runs to one space, ends trimmed. `''` when nothing is left. */
27605
+ function toOneLine(text) {
27606
+ return stripInlineMarkdown(text).replace(/\s+/gu, ' ').trim();
27607
+ }
27608
+ /**
27609
+ * Inline markdown markers off, in the order bold → italic → code. The bold
27610
+ * passes consume every `**` / `__` pair first, so the italic patterns can match
27611
+ * a lone `*` / `_` without lookarounds.
27612
+ */
27613
+ function stripInlineMarkdown(input) {
27614
+ return input
27615
+ .replace(/\*\*(.+?)\*\*/g, '$1')
27616
+ .replace(/__(.+?)__/g, '$1')
27617
+ .replace(/\*(.+?)\*/g, '$1')
27618
+ .replace(/_(.+?)_/g, '$1')
27619
+ .replace(/`([^`]+)`/g, '$1');
27620
+ }
27621
+
27546
27622
  /**
27547
27623
  * High-level facade for browsing Kasu lending strategies (pools).
27548
27624
  *
@@ -27729,6 +27805,7 @@ class StrategiesFacade {
27729
27805
  subheading: nonEmptyOrUndefined(pool.subheading),
27730
27806
  description: pool.description,
27731
27807
  liteDescription: nonEmptyOrUndefined(pool.liteDescription),
27808
+ summary: pickShortDescription(pool),
27732
27809
  isActive: pool.isActive,
27733
27810
  apy: pool.apy,
27734
27811
  tvl: pool.totalValueLocked,
@@ -29093,4 +29170,4 @@ function weightedAverageApy(slices) {
29093
29170
  return weighted / totalBalance;
29094
29171
  }
29095
29172
 
29096
- export { APXIUM, AU_ALPHA3, AU_MIN_CUMULATIVE_BY_STABLE, BatchPendingError, BatchRevertedError, BatchSubmissionError, CHAIN_CONFIGS, CLEARING_WINDOW_SECONDS, CONTRACT_TTL_MS, CallsFacade, DAYS_PER_EPOCH, DAYS_PER_MONTH, DEFAULT_BATCH_POLLING_POLICY, DepositBatchMismatchError, DepositFlow, DepositsFacade, ENTRY_POINT_V07, EPOCHS_IN_YEAR, Flow, FlowStore, FlowsFacade, INVALID_ACCEPTANCE_SIGNATURE_MESSAGE, INVALID_AUTH_SIGNATURE_MESSAGE, INVOICEMATE, Kasu, KasuSdk, MAX_LENDING_AMOUNT_FALLBACK, MIN_DAYS_FOR_MONTHS, MIN_LENDING_AMOUNT_FALLBACK, MIN_TRANCHE_CAPACITY, NOT_A_WITHDRAWAL_CALL_MESSAGE, NO_DIRECTUS_URL_MESSAGE, NO_KYC_PARAMS_MESSAGE, NO_SPENDER_MESSAGE, NO_WITHDRAWAL_ENCODER_MESSAGE, PortfolioFacade, READ_ONLY_MESSAGE, RIXON_CAPITAL, SECONDS_PER_WEEK, SPONSORED_CALL_KINDS, SPONSORED_CALL_SELECTORS, SdkConfig, SponsoredCallInputError, StrategiesFacade, UPPER_MEZZANINE, WithdrawFlow, accruedInterest, apyToEpochRate, asContractType, auMinimumRemaining, auThresholdFor, availableFixedTermConfigs, batchOutcomeOf, buildContractVersionType, buildFullNameRequestMessage, buildLegacyContractRequestMessage, buildLoanAgreementSignMessage, cancelDeadline, ceilToCents, checkBatchOutcome, checkSponsoredCallOutcome, classifyWalletFailure, compareTrancheSeniority, computeSettlementWindow, countSubmissions, dailyInterest, decodeRevert, deriveCycleDates, derivePoolStatus, deriveRequestState, encodeCancelDepositCall, encodeCancelWithdrawalCall, encodeDepositData, encodeRequestWithdrawalCall, encodeStableTransfer, encodeWithdrawAtExpiryCall, epochRateToApy, explorerAddressUrl, explorerTxUrl, extractRevertData, fetchUnusedPoolIds, firstSubmissionTimestamp, floorToCents, formatSignTimestampUtc, getCreditOriginator, getInstitutionalLender, getStrategyRegion, getTrancheDisplayName, isAuMinimumExempt, isAustralianKyc, isBelowMinimumCapacity, isCycleClosed, isDefinitivelyNotSubmitted, isFixedTermConfigId, isUnpredictableGas, isUserRejected, lastEventTimestamp, lockDurationDays, lockDurationMonths, maxNetRateCeiling, netEffectiveApy, netTrancheApyBounds, nextCycleBoundary, parseFormattedMessage, parseMinorUnits, parseTrancheBound, pickDefaultTrancheId, pickHighestYieldTranche, poolAllTranchesFull, poolMaxApy, projectedAnnualEarnings, proveDepositInReceipt, proveUserOperationInReceipt, resolveBoundShortcuts, resolveDepositBounds, selectVisiblePools, submissionEvents, submitBatch, submitSponsoredCall, trancheApyBounds, trancheHasCapacity, trancheRiskRank, validateDepositBatchCalls, weeklyInterest, weightedAverageApy };
29173
+ export { APXIUM, AU_ALPHA3, AU_MIN_CUMULATIVE_BY_STABLE, BatchPendingError, BatchRevertedError, BatchSubmissionError, CHAIN_CONFIGS, CLEARING_WINDOW_SECONDS, CONTRACT_TTL_MS, CallsFacade, DAYS_PER_EPOCH, DAYS_PER_MONTH, DEFAULT_BATCH_POLLING_POLICY, DepositBatchMismatchError, DepositFlow, DepositsFacade, ENTRY_POINT_V07, EPOCHS_IN_YEAR, Flow, FlowStore, FlowsFacade, INVALID_ACCEPTANCE_SIGNATURE_MESSAGE, INVALID_AUTH_SIGNATURE_MESSAGE, INVOICEMATE, Kasu, KasuSdk, MAX_LENDING_AMOUNT_FALLBACK, MIN_DAYS_FOR_MONTHS, MIN_LENDING_AMOUNT_FALLBACK, MIN_TRANCHE_CAPACITY, NOT_A_WITHDRAWAL_CALL_MESSAGE, NO_DIRECTUS_URL_MESSAGE, NO_KYC_PARAMS_MESSAGE, NO_SPENDER_MESSAGE, NO_WITHDRAWAL_ENCODER_MESSAGE, PortfolioFacade, READ_ONLY_MESSAGE, RIXON_CAPITAL, SECONDS_PER_WEEK, SPONSORED_CALL_KINDS, SPONSORED_CALL_SELECTORS, SdkConfig, SponsoredCallInputError, StrategiesFacade, UPPER_MEZZANINE, WithdrawFlow, accruedInterest, apyToEpochRate, asContractType, auMinimumRemaining, auThresholdFor, availableFixedTermConfigs, batchOutcomeOf, buildContractVersionType, buildFullNameRequestMessage, buildLegacyContractRequestMessage, buildLoanAgreementSignMessage, cancelDeadline, ceilToCents, checkBatchOutcome, checkSponsoredCallOutcome, classifyWalletFailure, compareTrancheSeniority, computeSettlementWindow, countSubmissions, dailyInterest, decodeRevert, deriveCycleDates, derivePoolStatus, deriveRequestState, encodeCancelDepositCall, encodeCancelWithdrawalCall, encodeDepositData, encodeRequestWithdrawalCall, encodeStableTransfer, encodeWithdrawAtExpiryCall, epochRateToApy, explorerAddressUrl, explorerTxUrl, extractRevertData, fetchUnusedPoolIds, firstSubmissionTimestamp, floorToCents, formatSignTimestampUtc, getCreditOriginator, getInstitutionalLender, getStrategyRegion, getTrancheDisplayName, isAuMinimumExempt, isAustralianKyc, isBelowMinimumCapacity, isCycleClosed, isDefinitivelyNotSubmitted, isFixedTermConfigId, isUnpredictableGas, isUserRejected, lastEventTimestamp, lockDurationDays, lockDurationMonths, maxNetRateCeiling, netEffectiveApy, netTrancheApyBounds, nextCycleBoundary, parseFormattedMessage, parseMinorUnits, parseTrancheBound, pickDefaultTrancheId, pickHighestYieldTranche, pickShortDescription, poolAllTranchesFull, poolMaxApy, projectedAnnualEarnings, proveDepositInReceipt, proveUserOperationInReceipt, resolveBoundShortcuts, resolveDepositBounds, selectVisiblePools, submissionEvents, submitBatch, submitSponsoredCall, trancheApyBounds, trancheHasCapacity, trancheRiskRank, validateDepositBatchCalls, weeklyInterest, weightedAverageApy };
@@ -16,6 +16,10 @@
16
16
  * reconstructs byte-for-byte to verify a lender's signature. Those are not
17
17
  * copy: nobody may reword them, in any language, without a matching backend
18
18
  * change, which is exactly why they belong in one place.
19
+ *
20
+ * `pickShortDescription` returns a string but AUTHORS none: it selects and
21
+ * cleans editorial the CMS already holds, and an absent blurb is
22
+ * `undefined`, never a sentence of its own.
19
23
  * 2. **Pure.** No network, no clock, no environment. Anything with I/O belongs
20
24
  * in `facade/` (see `fetchUnusedPoolIds`).
21
25
  */
@@ -44,6 +48,8 @@ export { CLEARING_WINDOW_SECONDS, computeSettlementWindow, deriveCycleDates, nex
44
48
  export type { CycleDates, SettlementWindowInput, SettlementWindowState, } from './settlement';
45
49
  export { encodeCancelDepositCall, encodeCancelWithdrawalCall, encodeRequestWithdrawalCall, encodeStableTransfer, encodeWithdrawAtExpiryCall, SPONSORED_CALL_KINDS, SPONSORED_CALL_SELECTORS, SponsoredCallInputError, } from './sponsored-calls';
46
50
  export type { SponsoredCall, SponsoredCallKind } from './sponsored-calls';
51
+ export { pickShortDescription } from './strategy-summary';
52
+ export type { ShortDescriptionSource } from './strategy-summary';
47
53
  export { getTrancheDisplayName, UPPER_MEZZANINE } from './tranche-display-name';
48
54
  export { compareTrancheSeniority, derivePoolStatus, MIN_TRANCHE_CAPACITY, netTrancheApyBounds, pickDefaultTrancheId, poolAllTranchesFull, trancheApyBounds, trancheHasCapacity, trancheRiskRank, } from './tranches';
49
55
  export type { ApyBounds, PoolStatus, TrancheCapacitySignal, } from './tranches';
@@ -16,6 +16,10 @@
16
16
  * reconstructs byte-for-byte to verify a lender's signature. Those are not
17
17
  * copy: nobody may reword them, in any language, without a matching backend
18
18
  * change, which is exactly why they belong in one place.
19
+ *
20
+ * `pickShortDescription` returns a string but AUTHORS none: it selects and
21
+ * cleans editorial the CMS already holds, and an absent blurb is
22
+ * `undefined`, never a sentence of its own.
19
23
  * 2. **Pure.** No network, no clock, no environment. Anything with I/O belongs
20
24
  * in `facade/` (see `fetchUnusedPoolIds`).
21
25
  */
@@ -32,6 +36,7 @@ export { cancelDeadline, countSubmissions, deriveRequestState, firstSubmissionTi
32
36
  export { decodeRevert, extractRevertData } from './revert-errors';
33
37
  export { CLEARING_WINDOW_SECONDS, computeSettlementWindow, deriveCycleDates, nextCycleBoundary, } from './settlement';
34
38
  export { encodeCancelDepositCall, encodeCancelWithdrawalCall, encodeRequestWithdrawalCall, encodeStableTransfer, encodeWithdrawAtExpiryCall, SPONSORED_CALL_KINDS, SPONSORED_CALL_SELECTORS, SponsoredCallInputError, } from './sponsored-calls';
39
+ export { pickShortDescription } from './strategy-summary';
35
40
  export { getTrancheDisplayName, UPPER_MEZZANINE } from './tranche-display-name';
36
41
  export { compareTrancheSeniority, derivePoolStatus, MIN_TRANCHE_CAPACITY, netTrancheApyBounds, pickDefaultTrancheId, poolAllTranchesFull, trancheApyBounds, trancheHasCapacity, trancheRiskRank, } from './tranches';
37
42
  export { classifyWalletFailure, isUnpredictableGas, isUserRejected, } from './wallet-errors';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/domain/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EACH,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,GAClB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACH,SAAS,EACT,2BAA2B,EAC3B,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,eAAe,GAClB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACH,yBAAyB,EACzB,eAAe,EACf,qBAAqB,EACrB,2BAA2B,EAC3B,yBAAyB,GAC5B,MAAM,eAAe,CAAC;AAavB,OAAO,EACH,WAAW,EACX,YAAY,EACZ,sBAAsB,EACtB,2BAA2B,EAC3B,2BAA2B,EAC3B,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,GACvB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGpE,OAAO,EACH,yBAAyB,EACzB,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,GACtB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACH,MAAM,EACN,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,WAAW,EACX,aAAa,GAChB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACH,cAAc,EACd,wBAAwB,EACxB,2BAA2B,EAC3B,iCAAiC,EACjC,6BAA6B,EAC7B,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,GACxB,MAAM,iBAAiB,CAAC;AAYzB,OAAO,EACH,iBAAiB,EACjB,uBAAuB,EACvB,UAAU,EACV,kBAAkB,GACrB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACH,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,wBAAwB,EACxB,aAAa,EACb,kBAAkB,EAClB,gBAAgB,GACnB,MAAM,YAAY,CAAC;AAOpB,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGlE,OAAO,EACH,uBAAuB,EACvB,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,GACpB,MAAM,cAAc,CAAC;AAOtB,OAAO,EACH,uBAAuB,EACvB,0BAA0B,EAC1B,2BAA2B,EAC3B,oBAAoB,EACpB,0BAA0B,EAC1B,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,GAC1B,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEhF,OAAO,EACH,uBAAuB,EACvB,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,GAClB,MAAM,YAAY,CAAC;AAOpB,OAAO,EACH,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,GACjB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACH,eAAe,EACf,aAAa,EACb,uBAAuB,EACvB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,GACrB,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/domain/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EACH,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,GAClB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACH,SAAS,EACT,2BAA2B,EAC3B,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,eAAe,GAClB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACH,yBAAyB,EACzB,eAAe,EACf,qBAAqB,EACrB,2BAA2B,EAC3B,yBAAyB,GAC5B,MAAM,eAAe,CAAC;AAavB,OAAO,EACH,WAAW,EACX,YAAY,EACZ,sBAAsB,EACtB,2BAA2B,EAC3B,2BAA2B,EAC3B,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,GACvB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGpE,OAAO,EACH,yBAAyB,EACzB,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,GACtB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACH,MAAM,EACN,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,WAAW,EACX,aAAa,GAChB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACH,cAAc,EACd,wBAAwB,EACxB,2BAA2B,EAC3B,iCAAiC,EACjC,6BAA6B,EAC7B,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,GACxB,MAAM,iBAAiB,CAAC;AAYzB,OAAO,EACH,iBAAiB,EACjB,uBAAuB,EACvB,UAAU,EACV,kBAAkB,GACrB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACH,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,wBAAwB,EACxB,aAAa,EACb,kBAAkB,EAClB,gBAAgB,GACnB,MAAM,YAAY,CAAC;AAOpB,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGlE,OAAO,EACH,uBAAuB,EACvB,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,GACpB,MAAM,cAAc,CAAC;AAOtB,OAAO,EACH,uBAAuB,EACvB,0BAA0B,EAC1B,2BAA2B,EAC3B,oBAAoB,EACpB,0BAA0B,EAC1B,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,GAC1B,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAG1D,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEhF,OAAO,EACH,uBAAuB,EACvB,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,GAClB,MAAM,YAAY,CAAC;AAOpB,OAAO,EACH,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,GACjB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACH,eAAe,EACf,aAAa,EACb,uBAAuB,EACvB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,GACrB,MAAM,UAAU,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * A strategy's SHORT blurb, as plain text: the CMS `liteDescription` first,
3
+ * else the first paragraph of the long `description`, else nothing.
4
+ *
5
+ * Lifted from kasu-ui (`pickShortDescription`, its deposit dialog and landing
6
+ * strategy card) so every app shows the same line, and pinned to its output
7
+ * for every live CMS row. The rules are facts about how the CMS is authored,
8
+ * not formatting preferences:
9
+ *
10
+ * - `liteDescription` IS THE SHORT ONE. `description` is the credit
11
+ * originator's several-paragraph profile; on a card it is a wall.
12
+ * - `"Not Available"` IS A PLACEHOLDER, not editorial. Several rows carry it
13
+ * verbatim, and it must read as missing, not print. Matched on the whole
14
+ * trimmed value, case-insensitively. It applies to `liteDescription` only.
15
+ * - EMPTY OR BLANK IS MISSING. The service maps a pool with no CMS record to
16
+ * `''`.
17
+ * - THE FIELDS HOLD MARKDOWN. `liteDescription` can open with a `**bold**`
18
+ * lead, and the surfaces this feeds render plain text, so the markers are
19
+ * stripped (bold, then italic, then inline code).
20
+ * - AND HARD NEWLINES. Every run of whitespace becomes one space, so a
21
+ * paragraph break inside the value is not a gap in a one-line slot.
22
+ * - NOT SANITISED. "Plain text" means text to render AS text. HTML tags,
23
+ * entities and link syntax (`<script>`, `&lt;`, `[a](javascript:…)`) pass
24
+ * through unchanged, and removing markers can join fragments into a tag
25
+ * (`<scr**i**pt>` becomes `<script>`). Render it as a text node, never as
26
+ * HTML or markdown.
27
+ *
28
+ * Two refinements over the kasu-ui original, neither reachable by any live
29
+ * row: the cleaned text is trimmed (a CRLF value no longer ends in a space),
30
+ * and a `liteDescription` that cleans to nothing (`** **`) counts as missing,
31
+ * so the result is never a blank string.
32
+ *
33
+ * This authors no string of its own. It selects and cleans editorial the CMS
34
+ * already holds, and an absent blurb is `undefined`, never a fallback sentence:
35
+ * what "no blurb" means is the render site's decision.
36
+ *
37
+ * Pure. A value that is not a string reads as missing.
38
+ */
39
+ export declare function pickShortDescription(source: ShortDescriptionSource): string | undefined;
40
+ /**
41
+ * The two CMS fields `pickShortDescription` reads. A `PoolOverview` and a
42
+ * facade `Strategy` both satisfy it.
43
+ */
44
+ export interface ShortDescriptionSource {
45
+ liteDescription?: string | null;
46
+ description?: string | null;
47
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * A strategy's SHORT blurb, as plain text: the CMS `liteDescription` first,
3
+ * else the first paragraph of the long `description`, else nothing.
4
+ *
5
+ * Lifted from kasu-ui (`pickShortDescription`, its deposit dialog and landing
6
+ * strategy card) so every app shows the same line, and pinned to its output
7
+ * for every live CMS row. The rules are facts about how the CMS is authored,
8
+ * not formatting preferences:
9
+ *
10
+ * - `liteDescription` IS THE SHORT ONE. `description` is the credit
11
+ * originator's several-paragraph profile; on a card it is a wall.
12
+ * - `"Not Available"` IS A PLACEHOLDER, not editorial. Several rows carry it
13
+ * verbatim, and it must read as missing, not print. Matched on the whole
14
+ * trimmed value, case-insensitively. It applies to `liteDescription` only.
15
+ * - EMPTY OR BLANK IS MISSING. The service maps a pool with no CMS record to
16
+ * `''`.
17
+ * - THE FIELDS HOLD MARKDOWN. `liteDescription` can open with a `**bold**`
18
+ * lead, and the surfaces this feeds render plain text, so the markers are
19
+ * stripped (bold, then italic, then inline code).
20
+ * - AND HARD NEWLINES. Every run of whitespace becomes one space, so a
21
+ * paragraph break inside the value is not a gap in a one-line slot.
22
+ * - NOT SANITISED. "Plain text" means text to render AS text. HTML tags,
23
+ * entities and link syntax (`<script>`, `&lt;`, `[a](javascript:…)`) pass
24
+ * through unchanged, and removing markers can join fragments into a tag
25
+ * (`<scr**i**pt>` becomes `<script>`). Render it as a text node, never as
26
+ * HTML or markdown.
27
+ *
28
+ * Two refinements over the kasu-ui original, neither reachable by any live
29
+ * row: the cleaned text is trimmed (a CRLF value no longer ends in a space),
30
+ * and a `liteDescription` that cleans to nothing (`** **`) counts as missing,
31
+ * so the result is never a blank string.
32
+ *
33
+ * This authors no string of its own. It selects and cleans editorial the CMS
34
+ * already holds, and an absent blurb is `undefined`, never a fallback sentence:
35
+ * what "no blurb" means is the render site's decision.
36
+ *
37
+ * Pure. A value that is not a string reads as missing.
38
+ */
39
+ export function pickShortDescription(source) {
40
+ var _a;
41
+ const lite = asTrimmed(source.liteDescription);
42
+ if (lite && !NOT_AVAILABLE.test(lite)) {
43
+ const summary = toOneLine(lite);
44
+ if (summary)
45
+ return summary;
46
+ }
47
+ const long = asTrimmed(source.description);
48
+ if (long) {
49
+ const firstParagraph = (_a = long.split(PARAGRAPH_BREAK, 1)[0]) !== null && _a !== void 0 ? _a : long;
50
+ return toOneLine(firstParagraph) || undefined;
51
+ }
52
+ return undefined;
53
+ }
54
+ const NOT_AVAILABLE = /^not available$/i;
55
+ const PARAGRAPH_BREAK = /\n\s*\n/;
56
+ function asTrimmed(value) {
57
+ return typeof value === 'string' ? value.trim() : '';
58
+ }
59
+ /** Markers off, whitespace runs to one space, ends trimmed. `''` when nothing is left. */
60
+ function toOneLine(text) {
61
+ return stripInlineMarkdown(text).replace(/\s+/gu, ' ').trim();
62
+ }
63
+ /**
64
+ * Inline markdown markers off, in the order bold → italic → code. The bold
65
+ * passes consume every `**` / `__` pair first, so the italic patterns can match
66
+ * a lone `*` / `_` without lookarounds.
67
+ */
68
+ function stripInlineMarkdown(input) {
69
+ return input
70
+ .replace(/\*\*(.+?)\*\*/g, '$1')
71
+ .replace(/__(.+?)__/g, '$1')
72
+ .replace(/\*(.+?)\*/g, '$1')
73
+ .replace(/_(.+?)_/g, '$1')
74
+ .replace(/`([^`]+)`/g, '$1');
75
+ }
76
+ //# sourceMappingURL=strategy-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategy-summary.js","sourceRoot":"","sources":["../../src/domain/strategy-summary.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,UAAU,oBAAoB,CAChC,MAA8B;;IAE9B,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IAC/C,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,OAAO;YAAE,OAAO,OAAO,CAAC;IAChC,CAAC;IACD,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC3C,IAAI,IAAI,EAAE,CAAC;QACP,MAAM,cAAc,GAAG,MAAA,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,mCAAI,IAAI,CAAC;QACjE,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,SAAS,CAAC;IAClD,CAAC;IACD,OAAO,SAAS,CAAC;AACrB,CAAC;AAWD,MAAM,aAAa,GAAG,kBAAkB,CAAC;AACzC,MAAM,eAAe,GAAG,SAAS,CAAC;AAElC,SAAS,SAAS,CAAC,KAAc;IAC7B,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACzD,CAAC;AAED,0FAA0F;AAC1F,SAAS,SAAS,CAAC,IAAY;IAC3B,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAClE,CAAC;AAED;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,KAAa;IACtC,OAAO,KAAK;SACP,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC;SAC/B,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC;SAC3B,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC;SACzB,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;AACrC,CAAC"}
@@ -8,6 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { selectVisiblePools } from '../domain/pools';
11
+ import { pickShortDescription } from '../domain/strategy-summary';
11
12
  /**
12
13
  * High-level facade for browsing Kasu lending strategies (pools).
13
14
  *
@@ -194,6 +195,7 @@ export class StrategiesFacade {
194
195
  subheading: nonEmptyOrUndefined(pool.subheading),
195
196
  description: pool.description,
196
197
  liteDescription: nonEmptyOrUndefined(pool.liteDescription),
198
+ summary: pickShortDescription(pool),
197
199
  isActive: pool.isActive,
198
200
  apy: pool.apy,
199
201
  tvl: pool.totalValueLocked,
@@ -1 +1 @@
1
- {"version":3,"file":"strategies.js","sourceRoot":"","sources":["../../src/facade/strategies.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"strategies.js","sourceRoot":"","sources":["../../src/facade/strategies.ts"],"names":[],"mappings":"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"}
@@ -98,6 +98,19 @@ export interface Strategy {
98
98
  * Absent when the record has none, or an empty one.
99
99
  */
100
100
  liteDescription?: string;
101
+ /**
102
+ * The strategy's short blurb as ONE line of plain text, for cards and
103
+ * compact surfaces: `liteDescription` when it is usable, else the first
104
+ * paragraph of `description`, with inline markdown markers stripped and
105
+ * every run of whitespace collapsed to one space. The `"Not Available"`
106
+ * placeholder, an empty or blank value, and a missing one all count as
107
+ * absent. `undefined` when neither field yields a blurb; the SDK never
108
+ * substitutes a sentence of its own. See `pickShortDescription`.
109
+ *
110
+ * Not sanitised: HTML tags and link syntax pass through unchanged. Render
111
+ * it as text, never as HTML or markdown.
112
+ */
113
+ summary?: string;
101
114
  isActive: boolean;
102
115
  /** Weighted-average APY across tranches (decimal, e.g. 0.08 = 8 %). */
103
116
  apy: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kasufinance/kasu-sdk",
3
- "version": "2.10.3",
3
+ "version": "2.11.0",
4
4
  "description": "TypeScript SDK for the Kasu Finance protocol — pool data, portfolio analytics, and KYC-gated deposits and withdrawals on Base and XDC",
5
5
  "keywords": [
6
6
  "kasu",
@@ -48,6 +48,7 @@
48
48
  "build-tc": "typechain --target ethers-v5 --out-dir src/contracts './abis/*.json'",
49
49
  "build": "eslint . && tsc --build --force tsconfig.json",
50
50
  "prepublishOnly": "npm run build && npm run rollup-build",
51
+ "prepare": "node .githooks/install.cjs",
51
52
  "build:watch": "npx tsc -b --force --watch",
52
53
  "rollup-build": "rollup -c",
53
54
  "lint": "eslint . --fix"
@@ -16,6 +16,10 @@
16
16
  * reconstructs byte-for-byte to verify a lender's signature. Those are not
17
17
  * copy: nobody may reword them, in any language, without a matching backend
18
18
  * change, which is exactly why they belong in one place.
19
+ *
20
+ * `pickShortDescription` returns a string but AUTHORS none: it selects and
21
+ * cleans editorial the CMS already holds, and an absent blurb is
22
+ * `undefined`, never a sentence of its own.
19
23
  * 2. **Pure.** No network, no clock, no environment. Anything with I/O belongs
20
24
  * in `facade/` (see `fetchUnusedPoolIds`).
21
25
  */
@@ -163,6 +167,9 @@ export {
163
167
  } from './sponsored-calls';
164
168
  export type { SponsoredCall, SponsoredCallKind } from './sponsored-calls';
165
169
 
170
+ export { pickShortDescription } from './strategy-summary';
171
+ export type { ShortDescriptionSource } from './strategy-summary';
172
+
166
173
  export { getTrancheDisplayName, UPPER_MEZZANINE } from './tranche-display-name';
167
174
 
168
175
  export {
@@ -0,0 +1,88 @@
1
+ /**
2
+ * A strategy's SHORT blurb, as plain text: the CMS `liteDescription` first,
3
+ * else the first paragraph of the long `description`, else nothing.
4
+ *
5
+ * Lifted from kasu-ui (`pickShortDescription`, its deposit dialog and landing
6
+ * strategy card) so every app shows the same line, and pinned to its output
7
+ * for every live CMS row. The rules are facts about how the CMS is authored,
8
+ * not formatting preferences:
9
+ *
10
+ * - `liteDescription` IS THE SHORT ONE. `description` is the credit
11
+ * originator's several-paragraph profile; on a card it is a wall.
12
+ * - `"Not Available"` IS A PLACEHOLDER, not editorial. Several rows carry it
13
+ * verbatim, and it must read as missing, not print. Matched on the whole
14
+ * trimmed value, case-insensitively. It applies to `liteDescription` only.
15
+ * - EMPTY OR BLANK IS MISSING. The service maps a pool with no CMS record to
16
+ * `''`.
17
+ * - THE FIELDS HOLD MARKDOWN. `liteDescription` can open with a `**bold**`
18
+ * lead, and the surfaces this feeds render plain text, so the markers are
19
+ * stripped (bold, then italic, then inline code).
20
+ * - AND HARD NEWLINES. Every run of whitespace becomes one space, so a
21
+ * paragraph break inside the value is not a gap in a one-line slot.
22
+ * - NOT SANITISED. "Plain text" means text to render AS text. HTML tags,
23
+ * entities and link syntax (`<script>`, `&lt;`, `[a](javascript:…)`) pass
24
+ * through unchanged, and removing markers can join fragments into a tag
25
+ * (`<scr**i**pt>` becomes `<script>`). Render it as a text node, never as
26
+ * HTML or markdown.
27
+ *
28
+ * Two refinements over the kasu-ui original, neither reachable by any live
29
+ * row: the cleaned text is trimmed (a CRLF value no longer ends in a space),
30
+ * and a `liteDescription` that cleans to nothing (`** **`) counts as missing,
31
+ * so the result is never a blank string.
32
+ *
33
+ * This authors no string of its own. It selects and cleans editorial the CMS
34
+ * already holds, and an absent blurb is `undefined`, never a fallback sentence:
35
+ * what "no blurb" means is the render site's decision.
36
+ *
37
+ * Pure. A value that is not a string reads as missing.
38
+ */
39
+ export function pickShortDescription(
40
+ source: ShortDescriptionSource,
41
+ ): string | undefined {
42
+ const lite = asTrimmed(source.liteDescription);
43
+ if (lite && !NOT_AVAILABLE.test(lite)) {
44
+ const summary = toOneLine(lite);
45
+ if (summary) return summary;
46
+ }
47
+ const long = asTrimmed(source.description);
48
+ if (long) {
49
+ const firstParagraph = long.split(PARAGRAPH_BREAK, 1)[0] ?? long;
50
+ return toOneLine(firstParagraph) || undefined;
51
+ }
52
+ return undefined;
53
+ }
54
+
55
+ /**
56
+ * The two CMS fields `pickShortDescription` reads. A `PoolOverview` and a
57
+ * facade `Strategy` both satisfy it.
58
+ */
59
+ export interface ShortDescriptionSource {
60
+ liteDescription?: string | null;
61
+ description?: string | null;
62
+ }
63
+
64
+ const NOT_AVAILABLE = /^not available$/i;
65
+ const PARAGRAPH_BREAK = /\n\s*\n/;
66
+
67
+ function asTrimmed(value: unknown): string {
68
+ return typeof value === 'string' ? value.trim() : '';
69
+ }
70
+
71
+ /** Markers off, whitespace runs to one space, ends trimmed. `''` when nothing is left. */
72
+ function toOneLine(text: string): string {
73
+ return stripInlineMarkdown(text).replace(/\s+/gu, ' ').trim();
74
+ }
75
+
76
+ /**
77
+ * Inline markdown markers off, in the order bold → italic → code. The bold
78
+ * passes consume every `**` / `__` pair first, so the italic patterns can match
79
+ * a lone `*` / `_` without lookarounds.
80
+ */
81
+ function stripInlineMarkdown(input: string): string {
82
+ return input
83
+ .replace(/\*\*(.+?)\*\*/g, '$1')
84
+ .replace(/__(.+?)__/g, '$1')
85
+ .replace(/\*(.+?)\*/g, '$1')
86
+ .replace(/_(.+?)_/g, '$1')
87
+ .replace(/`([^`]+)`/g, '$1');
88
+ }
@@ -1,4 +1,5 @@
1
1
  import { selectVisiblePools } from '../domain/pools';
2
+ import { pickShortDescription } from '../domain/strategy-summary';
2
3
  import { DataService } from '../services/DataService/data-service';
3
4
  import {
4
5
  PoolDelegateProfileAndHistory,
@@ -218,6 +219,7 @@ export class StrategiesFacade {
218
219
  subheading: nonEmptyOrUndefined(pool.subheading),
219
220
  description: pool.description,
220
221
  liteDescription: nonEmptyOrUndefined(pool.liteDescription),
222
+ summary: pickShortDescription(pool),
221
223
  isActive: pool.isActive,
222
224
  apy: pool.apy,
223
225
  tvl: pool.totalValueLocked,
@@ -121,6 +121,19 @@ export interface Strategy {
121
121
  * Absent when the record has none, or an empty one.
122
122
  */
123
123
  liteDescription?: string;
124
+ /**
125
+ * The strategy's short blurb as ONE line of plain text, for cards and
126
+ * compact surfaces: `liteDescription` when it is usable, else the first
127
+ * paragraph of `description`, with inline markdown markers stripped and
128
+ * every run of whitespace collapsed to one space. The `"Not Available"`
129
+ * placeholder, an empty or blank value, and a missing one all count as
130
+ * absent. `undefined` when neither field yields a blurb; the SDK never
131
+ * substitutes a sentence of its own. See `pickShortDescription`.
132
+ *
133
+ * Not sanitised: HTML tags and link syntax pass through unchanged. Render
134
+ * it as text, never as HTML or markdown.
135
+ */
136
+ summary?: string;
124
137
  isActive: boolean;
125
138
  /** Weighted-average APY across tranches (decimal, e.g. 0.08 = 8 %). */
126
139
  apy: number;