@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 +17 -0
- package/dist/bundle.cjs.js +78 -0
- package/dist/bundle.esm.js +78 -1
- package/dist/domain/index.d.ts +6 -0
- package/dist/domain/index.js +5 -0
- package/dist/domain/index.js.map +1 -1
- package/dist/domain/strategy-summary.d.ts +47 -0
- package/dist/domain/strategy-summary.js +76 -0
- package/dist/domain/strategy-summary.js.map +1 -0
- package/dist/facade/strategies.js +2 -0
- package/dist/facade/strategies.js.map +1 -1
- package/dist/facade/types.d.ts +13 -0
- package/package.json +2 -1
- package/src/domain/index.ts +7 -0
- package/src/domain/strategy-summary.ts +88 -0
- package/src/facade/strategies.ts +2 -0
- package/src/facade/types.ts +13 -0
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
|
package/dist/bundle.cjs.js
CHANGED
|
@@ -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>`, `<`, `[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;
|
package/dist/bundle.esm.js
CHANGED
|
@@ -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>`, `<`, `[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 };
|
package/dist/domain/index.d.ts
CHANGED
|
@@ -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';
|
package/dist/domain/index.js
CHANGED
|
@@ -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';
|
package/dist/domain/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/domain/index.ts"],"names":[],"mappings":"AAAA
|
|
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>`, `<`, `[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>`, `<`, `[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":";;;;;;;;;AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"strategies.js","sourceRoot":"","sources":["../../src/facade/strategies.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAiBlE;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IACzB,YACY,YAAyB,EACzB,YAAyB;IACjC;;;OAGG;IACK,uBAA+C,EAAE;QANjD,iBAAY,GAAZ,YAAY,CAAa;QACzB,iBAAY,GAAZ,YAAY,CAAa;QAKzB,yBAAoB,GAApB,oBAAoB,CAA6B;IAC1D,CAAC;IAEJ;;;;;;;;;;;;OAYG;IACG,kBAAkB,CACpB,MAAc;;YAEd,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC9C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,iBAAiB,EAAE,CAAC;YAC5D,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CACvB,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,KAAK,UAAU,CACzD,CAAC;YACF,IAAI,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC;YACzB,MAAM,WAAW,GAAG,MAAM,CAAC,eAGZ,CAAC;YAChB,OAAO;gBACH,YAAY,EAAE,YAAY,CAAC,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,YAAY,CAAC;gBACrD,gBAAgB,EAAE,YAAY,CAAC,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,gBAAgB,CAAC;aAChE,CAAC;QACN,CAAC;KAAA;IAED;;;;;;;;;;;;;OAaG;IACG,aAAa,CACf,MAAc;;;YAEd,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;gBACvB,MAAM,CAAC,WAAW,EAAE;gBACpB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;aAC7B,CAAC,CAAC;YACH,MAAM,QAAQ,GACV,MAAM,IAAI,CAAC,YAAY,CAAC,gCAAgC,EAAE,CAAC;YAC/D,OAAO,CACH,MAAA,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CACtB,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CACjC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAChD,CACJ,mCAAI,IAAI,CACZ,CAAC;QACN,CAAC;KAAA;IAEO,aAAa,CAAC,MAAc;;QAChC,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;QACnC,OAAO,CAAC,MAAA,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,mCAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;IACrE,CAAC;IAED;;;;;;OAMG;IACG,MAAM,CAAC,OAAkB;;YAC3B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,CAAC;YAC1D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACxE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7D,CAAC;KAAA;IAED;;;;;;;;OAQG;IACG,UAAU,CAAC,OAAkB;;YAC/B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,CAAC;YAC1D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACxE,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAC1C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAC/B,CAAC;QACN,CAAC;KAAA;IAED;;;;;;;;;;;;;OAaG;IACG,wBAAwB;;YAC1B,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,iBAAiB,EAAE,CAAC;QACvD,CAAC;KAAA;IAED;;OAEG;IACG,OAAO,CAAC,MAAc;;;YACxB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YAC5C,OAAO,MAAA,OAAO,CAAC,CAAC,CAAC,mCAAI,IAAI,CAAC;QAC9B,CAAC;KAAA;IAED;;OAEG;IACG,gBAAgB;;YAClB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,CAAC;YAC1D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC/D,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC3D,CAAC;KAAA;IAED;;;;;OAKG;IACH,sBAAsB,CAAC,OAAwB;QAC3C,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,MAAM,GAAG,GACL,UAAU,CAAC,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC;QAElE,MAAM,GAAG,GACL,UAAU,CAAC,GAAG,CAAC,cAAc,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC;YACzD,CAAC,CAAC,GAAG,CAAC,YAAY;YAClB,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC;QAE7B,OAAO;YACH,GAAG;YACH,GAAG;YACH,iBAAiB,EAAE,GAAG,CAAC,YAAY;SACtC,CAAC;IACN,CAAC;IAED,qEAAqE;IACrE,kBAAkB;IAClB,qEAAqE;IAE7D,iBAAiB,CAAC,IAAkB;QACxC,MAAM,QAAQ,GAAsB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC1D,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;YACtB,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC;YAC5B,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC;YAC5B,cAAc,EAAE,CAAC,CAAC,cAAc;YAChC,cAAc,EAAE,CAAC,CAAC,cAAc;YAChC,iBAAiB,EAAE,CAAC,CAAC,YAAY;YACjC,gBAAgB,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,CACnC,CAAC,GAAG,EAAmB,EAAE,CAAC,CAAC;gBACvB,QAAQ,EAAE,GAAG,CAAC,QAAQ;gBACtB,GAAG,EAAE,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;gBACxB,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;aAC3C,CAAC,CACL;YACD,IAAI,EAAE,CAAC;SACV,CAAC,CAAC,CAAC;QAEJ,OAAO;YACH,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,QAAQ;YACnB,UAAU,EAAE,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC;YAChD,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,eAAe,EAAE,mBAAmB,CAAC,IAAI,CAAC,eAAe,CAAC;YAC1D,OAAO,EAAE,oBAAoB,CAAC,IAAI,CAAC;YACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,GAAG,EAAE,IAAI,CAAC,gBAAgB;YAC1B,iBAAiB,EAAE,IAAI,CAAC,YAAY;YACpC,mBAAmB,EAAE,IAAI,CAAC,sBAAsB;YAChD,QAAQ;YACR,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,YAAY,EAAE,IAAI,CAAC,gBAAgB;YACnC,YAAY,EAAE,IAAI,CAAC,iBAAiB;YACpC,SAAS,EAAE,IAAI,CAAC,cAAc;YAC9B,IAAI,EAAE,IAAI;SACb,CAAC;IACN,CAAC;CACJ;AAED;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,KAAc;IACvC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;QACvD,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,SAAS,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,KAAc;IAChC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5E,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO,IAAI,CAAC;QACrC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9B,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IACrD,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC"}
|
package/dist/facade/types.d.ts
CHANGED
|
@@ -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.
|
|
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"
|
package/src/domain/index.ts
CHANGED
|
@@ -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>`, `<`, `[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
|
+
}
|
package/src/facade/strategies.ts
CHANGED
|
@@ -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,
|
package/src/facade/types.ts
CHANGED
|
@@ -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;
|