fix(rwallet): populate yield APY stats, hide top tabs on yield view
- Fix DeFi Llama field mapping: use apyMean30d + apyPct7D (apyMean7d doesn't exist in their API) - Add apyBase, apy30d fields to YieldOpportunity type - Deduplicate rates table (best APY per protocol+chain+asset) - Hide "My Wallets / Wallet Visualizer" top tab bar on yield page - Color-code APY values, better TVL formatting (B/M) - Bump JS cache to v=11 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f9d4164f28
commit
fdf2a429f5
|
|
@ -90,7 +90,9 @@ interface YieldRate {
|
|||
assetAddress: string;
|
||||
vaultAddress: string;
|
||||
apy: number;
|
||||
apyBase?: number;
|
||||
apy7d?: number;
|
||||
apy30d?: number;
|
||||
tvl?: number;
|
||||
vaultName?: string;
|
||||
}
|
||||
|
|
@ -2043,6 +2045,15 @@ class FolkWalletViewer extends HTMLElement {
|
|||
|
||||
// ── Rates table ──
|
||||
if (this.yieldRates.length > 0) {
|
||||
// Deduplicate: keep highest-APY entry per protocol+chain+asset
|
||||
const deduped = new Map<string, YieldRate>();
|
||||
const sorted = [...this.yieldRates].sort((a, b) => b.apy - a.apy);
|
||||
for (const r of sorted) {
|
||||
const key = `${r.protocol}:${r.chainId}:${r.asset}`;
|
||||
if (!deduped.has(key)) deduped.set(key, r);
|
||||
}
|
||||
const rates = [...deduped.values()];
|
||||
|
||||
html += `<div class="yield-section">
|
||||
<h3 class="yield-section-title">Available Rates</h3>
|
||||
<table class="balance-table">
|
||||
|
|
@ -2051,20 +2062,21 @@ class FolkWalletViewer extends HTMLElement {
|
|||
<th>Chain</th>
|
||||
<th>Asset</th>
|
||||
<th class="amount-cell">APY</th>
|
||||
<th class="amount-cell">7d Avg</th>
|
||||
<th class="amount-cell">30d Avg</th>
|
||||
<th class="amount-cell">TVL</th>
|
||||
</tr></thead>
|
||||
<tbody>`;
|
||||
const sorted = [...this.yieldRates].sort((a, b) => b.apy - a.apy);
|
||||
for (const r of sorted) {
|
||||
for (const r of rates) {
|
||||
const protocolLabel = r.protocol === "aave-v3" ? "Aave V3" : (r.vaultName || "Morpho");
|
||||
const chainColor = r.chainId === "1" ? "#627eea" : "#0052ff";
|
||||
const apyColor = r.apy >= 3 ? "var(--rs-success)" : r.apy >= 1.5 ? "#ffa726" : "var(--rs-text-secondary)";
|
||||
html += `<tr>
|
||||
<td><span class="yield-protocol-badge ${r.protocol}">${protocolLabel}</span></td>
|
||||
<td>${chainNames[r.chainId] || r.chainId}</td>
|
||||
<td><span class="yield-chain-badge" style="background:${chainColor}22;color:${chainColor}">${chainNames[r.chainId] || r.chainId}</span></td>
|
||||
<td><span class="token-symbol">${this.esc(r.asset)}</span></td>
|
||||
<td class="amount-cell" style="color:var(--rs-success);font-weight:600">${r.apy.toFixed(2)}%</td>
|
||||
<td class="amount-cell">${r.apy7d ? r.apy7d.toFixed(2) + "%" : "-"}</td>
|
||||
<td class="amount-cell">${r.tvl ? "$" + (r.tvl / 1e6).toFixed(1) + "M" : "-"}</td>
|
||||
<td class="amount-cell" style="color:${apyColor};font-weight:700">${r.apy.toFixed(2)}%</td>
|
||||
<td class="amount-cell">${r.apy30d != null ? r.apy30d.toFixed(2) + "%" : "-"}</td>
|
||||
<td class="amount-cell">${r.tvl ? "$" + (r.tvl >= 1e9 ? (r.tvl / 1e9).toFixed(1) + "B" : (r.tvl / 1e6).toFixed(0) + "M") : "-"}</td>
|
||||
</tr>`;
|
||||
}
|
||||
html += `</tbody></table></div>`;
|
||||
|
|
@ -2329,11 +2341,12 @@ class FolkWalletViewer extends HTMLElement {
|
|||
|
||||
private render() {
|
||||
const isMyWallets = this.topTab === "my-wallets" && this.isAuthenticated;
|
||||
const isYield = this.activeView === "yield";
|
||||
|
||||
this.shadow.innerHTML = `
|
||||
${this.renderStyles()}
|
||||
${this.isAuthenticated ? this.renderTopTabBar() : ''}
|
||||
${isMyWallets ? this.renderMyWalletsTab() : this.renderVisualizerTab()}
|
||||
${this.isAuthenticated && !isYield ? this.renderTopTabBar() : ''}
|
||||
${isMyWallets && !isYield ? this.renderMyWalletsTab() : this.renderVisualizerTab()}
|
||||
`;
|
||||
|
||||
// Top tab listeners
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ export interface YieldOpportunity {
|
|||
vaultAddress: string; // aToken for Aave, vault for Morpho
|
||||
apy: number;
|
||||
apy7d?: number;
|
||||
apy30d?: number;
|
||||
apyBase?: number;
|
||||
tvl?: number;
|
||||
poolId?: string; // DeFi Llama pool ID
|
||||
vaultName?: string;
|
||||
|
|
|
|||
|
|
@ -63,7 +63,10 @@ interface LlamaPool {
|
|||
symbol: string;
|
||||
tvlUsd: number;
|
||||
apy: number;
|
||||
apyMean7d?: number;
|
||||
apyBase?: number;
|
||||
apyReward?: number | null;
|
||||
apyPct7D?: number;
|
||||
apyMean30d?: number;
|
||||
underlyingTokens?: string[];
|
||||
}
|
||||
|
||||
|
|
@ -119,7 +122,9 @@ async function fetchDefiLlamaRates(): Promise<YieldOpportunity[]> {
|
|||
assetAddress,
|
||||
vaultAddress,
|
||||
apy: pool.apy || 0,
|
||||
apy7d: pool.apyMean7d,
|
||||
apyBase: pool.apyBase ?? undefined,
|
||||
apy7d: pool.apyPct7D != null ? pool.apy + pool.apyPct7D : undefined,
|
||||
apy30d: pool.apyMean30d ?? undefined,
|
||||
tvl: pool.tvlUsd,
|
||||
poolId: pool.pool,
|
||||
vaultName: protocol === "morpho-blue"
|
||||
|
|
|
|||
|
|
@ -1014,7 +1014,7 @@ function renderWallet(spaceSlug: string, initialView?: string) {
|
|||
modules: getModuleInfoList(),
|
||||
theme: "dark",
|
||||
body: `<folk-wallet-viewer${viewAttr}></folk-wallet-viewer>`,
|
||||
scripts: `<script type="module" src="/modules/rwallet/folk-wallet-viewer.js?v=10"></script>`,
|
||||
scripts: `<script type="module" src="/modules/rwallet/folk-wallet-viewer.js?v=11"></script>`,
|
||||
styles: `<link rel="stylesheet" href="/modules/rwallet/wallet.css">`,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue