שילוב Aave, Uniswap ו-Curve בלוח מחוונים אחד ל-DeFi

ניהול נכסים בפרוטוקולי DeFi מרובים דורש מעבר מתמיד בין ממשקים וחישובי תשואה ידניים. אנו מפתחים לוח מחוונים מאוחד ל-DeFi המשלב עמדות Aave, Uniswap ו-Curve בחלון אחד עם נתונים בזמן אמת. הצוות שלנו מספק את הפרויקט במפתח מלא, תוך הבטחת אינטגרציה אמינה ותמיכה מתמשכת.

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
שילוב Aave, Uniswap ו-Curve בלוח מחוונים אחד ל-DeFi
מורכב
~2-4 שבועות

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1365
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113
  • פיתוח אתר עבור SBH Partners
    פיתוח אתר עבור SBH Partners
    1201
  • פיתוח אתר עבור Red Pear
    פיתוח אתר עבור Red Pear
    619

שילוב Aave, Uniswap ו-Curve בלוח מחוונים אחד ל-DeFi

תארו לעצמכם: יש לכם נכסים בעשרות פרוטוקולי DeFi. כדי לבדוק את התשואה הכוללת, אתם פותחים שלושה ממשקים שונים, ממירים ידנית פוזיציות לדולרים, ועוקבים אחר שינויי APY. זה שעות כל שבוע. אנחנו בונים לוח מחוונים מאוחד: כל הפוזיציות, ערך בדולרים, רווח והפסד, והיסטוריה על מסך אחד, מתעדכן בזמן אמת. למהנדסים שלנו יש ניסיון של 10+ שנים בפיתוח בלוקצ'יין והם מוסמכים ב-Ethereum.

האתגר אינו הווידג'טים— אלא האינטגרציה: לכל פרוטוקול יש API משלו, פורמטים של נתונים ורשתות. בנוסף, יש עדכוני מחירים. אנחנו פותרים את זה ומספקים לוח מחוונים מוכן לשימוש.

אילו פרוטוקולים אנחנו משלבים

פרוטוקול סוג נתונים שיטת שליפה תדירות עדכון
Aave v3 הפקדות, הלוואות, APR Subgraph 30 שניות
Uniswap v3 פוזיציות LP, עמלות Subgraph 30 שניות
Curve סטייקינג, אסימוני LP Curve API דקה אחת
CoinGecko מחירי אסימונים REST API דקה אחת (מטמון)
Ethereum יתרות, אסימונים Multicall באצווה RPC 12 שניות (בלוק אחד)

אינטגרציית פרוטוקולים ואיסוף נתונים

למה Subgraph מהיר יותר משאילתות RPC ישירות?

Subgraph מ-The Graph מאנדקס אירועי חוזה—שאילתה אחת מחליפה אלפי קריאות RPC. עבור Aave v3, אנחנו מרכיבים שאילתת GraphQL, שולפים // lib/protocols/aave.ts — полный листинг const AAVE_SUBGRAPH = 'https://api.thegraph.com/subgraphs/name/aave/protocol-v3'; interface AavePosition { reserve: { symbol: string; underlyingAsset: string; decimals: number }; currentATokenBalance: string; currentVariableDebt: string; currentStableDebt: string; reserveLiquidationThreshold: string; } export async function getAavePositions(userAddress: string): Promise<AavePosition[]> { const query = `{ userReserves( where: { user: "${userAddress.toLowerCase()}", currentATokenBalance_gt: "0" } ) { reserve { symbol underlyingAsset decimals liquidityRate } currentATokenBalance currentVariableDebt currentStableDebt } }`; const res = await fetch(AAVE_SUBGRAPH, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query }), next: { revalidate: 30 }, }); const { data } = await res.json(); return data.userReserves; } , מנתחים אותם, וממפים לממשק // lib/protocols/uniswap-v3.ts const UNISWAP_SUBGRAPH = 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3'; export async function getUniswapPositions(ownerAddress: string) { const query = `{ positions( where: { owner: "${ownerAddress.toLowerCase()}", liquidity_gt: "0" } orderBy: id orderDirection: desc first: 20 ) { id liquidity token0 { symbol decimals } token1 { symbol decimals } pool { feeTier sqrtPrice tick token0Price token1Price } depositedToken0 depositedToken1 collectedFeesToken0 collectedFeesToken1 tickLower { tickIdx } tickUpper { tickIdx } } }`; const res = await fetch(UNISWAP_SUBGRAPH, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query }), }); const { data } = await res.json(); return data.positions; } . שאילתות Subgraph מהירות פי 10 לעיבוד אצווה.

// lib/protocols/aave.ts — полный листинг
const AAVE_SUBGRAPH = 'https://api.thegraph.com/subgraphs/name/aave/protocol-v3';

interface AavePosition {
  reserve: {
    symbol: string;
    underlyingAsset: string;
    decimals: number;
  };
  currentATokenBalance: string;
  currentVariableDebt: string;
  currentStableDebt: string;
  reserveLiquidationThreshold: string;
}

export async function getAavePositions(userAddress: string): Promise<AavePosition[]> {
  const query = `{
    userReserves(
      where: {
        user: "${userAddress.toLowerCase()}",
        currentATokenBalance_gt: "0"
      }
    ) {
      reserve {
        symbol
        underlyingAsset
        decimals
        liquidityRate
      }
      currentATokenBalance
      currentVariableDebt
      currentStableDebt
    }
  }`;

  const res = await fetch(AAVE_SUBGRAPH, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ query }),
    next: { revalidate: 30 },
  });

  const { data } = await res.json();
  return data.userReserves;
}

פוזיציות LP של Uniswap v3 — NFTs ו-Subgraph

פוזיציות Uniswap v3 הן אסימוני ERC-721 ב-NonfungiblePositionManager. דרך ה-Subgraph, אנחנו שולפים פרטים: אסימונים, טווחי tick, עמלות שנאספו. זה מאפשר חישוב ערך נוכחי ורווח לא ממומש.

// lib/protocols/uniswap-v3.ts
const UNISWAP_SUBGRAPH = 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3';

export async function getUniswapPositions(ownerAddress: string) {
  const query = `{
    positions(
      where: { owner: "${ownerAddress.toLowerCase()}", liquidity_gt: "0" }
      orderBy: id
      orderDirection: desc
      first: 20
    ) {
      id
      liquidity
      token0 { symbol decimals }
      token1 { symbol decimals }
      pool { feeTier sqrtPrice tick token0Price token1Price }
      depositedToken0
      depositedToken1
      collectedFeesToken0
      collectedFeesToken1
      tickLower { tickIdx }
      tickUpper { tickIdx }
    }
  }`;

  const res = await fetch(UNISWAP_SUBGRAPH, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ query }),
  });

  const { data } = await res.json();
  return data.positions;
}

איך לאגד נתונים בזמן אמת?

אנחנו משתמשים ב-hook usePortfolio הבנוי על TanStack Query + Wagmi. הוא טוען פוזיציות מ-Aave ו-Uniswap במקביל, מביא מחירים, וממזג לאובייקט אחד. // hooks/usePortfolio.ts import { useQuery } from '@tanstack/react-query'; import { useAccount } from 'wagmi'; import { getAavePositions } from '@/lib/protocols/aave'; import { getUniswapPositions } from '@/lib/protocols/uniswap-v3'; import { getTokenPrices } from '@/lib/prices'; export function usePortfolio() { const { address } = useAccount(); return useQuery({ queryKey: ['portfolio', address], queryFn: async () => { if (!address) return null; const [aavePositions, uniswapPositions] = await Promise.all([ getAavePositions(address), getUniswapPositions(address), ]); const tokenIds = [ ...new Set([ ...aavePositions.map(p => p.reserve.symbol.toLowerCase()), 'ethereum', ]), ]; const prices = await getTokenPrices(tokenIds); const aaveUSD = aavePositions.reduce((sum, pos) => { const balance = Number(pos.currentATokenBalance) / 10 ** pos.reserve.decimals; const price = prices[pos.reserve.symbol.toLowerCase()] ?? 0; return sum + balance * price; }, 0); return { aavePositions, uniswapPositions, aaveUSD, prices, }; }, enabled: !!address, refetchInterval: 60_000, }); } של 60 שניות מבטיח רעננות, בעוד מטמון בצד הלקוח מספק תגובה מיידית בעת מעבר בין טאבים.

// hooks/usePortfolio.ts
import { useQuery } from '@tanstack/react-query';
import { useAccount } from 'wagmi';
import { getAavePositions } from '@/lib/protocols/aave';
import { getUniswapPositions } from '@/lib/protocols/uniswap-v3';
import { getTokenPrices } from '@/lib/prices';

export function usePortfolio() {
  const { address } = useAccount();

  return useQuery({
    queryKey: ['portfolio', address],
    queryFn: async () => {
      if (!address) return null;

      const [aavePositions, uniswapPositions] = await Promise.all([
        getAavePositions(address),
        getUniswapPositions(address),
      ]);

      const tokenIds = [
        ...new Set([
          ...aavePositions.map(p => p.reserve.symbol.toLowerCase()),
          'ethereum',
        ]),
      ];

      const prices = await getTokenPrices(tokenIds);

      const aaveUSD = aavePositions.reduce((sum, pos) => {
        const balance = Number(pos.currentATokenBalance) / 10 ** pos.reserve.decimals;
        const price = prices[pos.reserve.symbol.toLowerCase()] ?? 0;
        return sum + balance * price;
      }, 0);

      return {
        aavePositions,
        uniswapPositions,
        aaveUSD,
        prices,
      };
    },
    enabled: !!address,
    refetchInterval: 60_000,
  });
}

איך מטמון נתונים חוסך כסף ומשאבים?

ללא מטמון, כל רינדור מפעיל קריאת API חדשה. יישמנו מטמון מחירים עם TTL של 60 שניות, מה שמפחית את העומס על CoinGecko פי 20. חיסכון במגבלות API מגיע ל-95%, שהם כ-200 דולר בחודש בשימוש כבד. מטמון דומה ל-Subgraph: נתונים נשלפים מחדש לא יותר מפעם בכל 30 שניות.

// lib/prices.ts — кэш цен с TTL
const COINGECKO_BASE = 'https://api.coingecko.com/api/v3';
const priceCache = new Map<string, { price: number; ts: number }>();
const CACHE_TTL = 60_000;

export async function getTokenPrices(
  tokenIds: string[],
  vsCurrency = 'usd',
): Promise<Record<string, number>> {
  const stale = tokenIds.filter(id => {
    const cached = priceCache.get(id);
    return !cached || Date.now() - cached.ts > CACHE_TTL;
  });

  if (stale.length > 0) {
    const res = await fetch(
      `${COINGECKO_BASE}/simple/price?ids=${stale.join(',')}&vs_currencies=${vsCurrency}`,
    );
    const data = await res.json();
    for (const [id, price] of Object.entries(data)) {
      priceCache.set(id, {
        price: (price as Record<string, number>)[vsCurrency],
        ts: Date.now(),
      });
    }
  }

  return Object.fromEntries(
    tokenIds.map(id => [id, priceCache.get(id)?.price ?? 0]),
  );
}

רכיבי לוח המחוונים

// components/NetWorthCard.tsx
export function NetWorthCard() {
  const { data, isLoading } = usePortfolio();
  if (isLoading) return <Skeleton className="h-32" />;
  const total = (data?.aaveUSD ?? 0) + (data?.uniswapUSD ?? 0);
  return (
    <div className="rounded-2xl border border-white/10 bg-gradient-to-br from-neutral-900 to-neutral-800 p-6">
      <p className="text-sm text-neutral-400">Чистая стоимость</p>
      <p className="mt-1 text-4xl font-bold">
        ${total.toLocaleString('en-US', { maximumFractionDigits: 2 })}
      </p>
      <div className="mt-4 flex gap-6 text-sm">
        <Metric label="Aave" value={data?.aaveUSD} />
        <Metric label="Uniswap LP" value={data?.uniswapUSD} />
      </div>
    </div>
  );
}

עדכונים בזמן אמת: מחירים מתעדכנים כל דקה דרך react-query // lib/prices.ts — кэш цен с TTL const COINGECKO_BASE = 'https://api.coingecko.com/api/v3'; const priceCache = new Map<string, { price: number; ts: number }>(); const CACHE_TTL = 60_000; export async function getTokenPrices( tokenIds: string[], vsCurrency = 'usd', ): Promise<Record<string, number>> { const stale = tokenIds.filter(id => { const cached = priceCache.get(id); return !cached || Date.now() - cached.ts > CACHE_TTL; }); if (stale.length > 0) { const res = await fetch( `${COINGECKO_BASE}/simple/price?ids=${stale.join(',')}&vs_currencies=${vsCurrency}`, ); const data = await res.json(); for (const [id, price] of Object.entries(data)) { priceCache.set(id, { price: (price as Record<string, number>)[vsCurrency], ts: Date.now() }); } } return Object.fromEntries( tokenIds.map(id => [id, priceCache.get(id)?.price ?? 0]), ); } , נתוני on-chain כל 12 שניות (בלוק Ethereum אחד), נתוני Subgraph כל 30 שניות (עיכוב אינדוקס ~15 שניות).

תהליך הפיתוח

שלב משך תוצאה
ניתוח ובריף יום אחד רשימת פרוטוקולים, מפרט
אינטגרציית Subgraph 2–3 ימים שליפת נתונים לכל פרוטוקול
פיתוח ממשק משתמש 2–4 ימים רכיבים: NetWorth, Positions, History
מטמון וזמן אמת יום אחד הגדרת react-query, מטמון מחירים
בדיקות ופריסה 1–2 ימים לוח מחוונים עובד על Vercel או השרת שלכם

מלכודות נפוצות ואיך להימנע מהן

  • שאילתת N+1: שליפת נתונים לכל בריכה עם קריאת RPC נפרדת. פתרון: Multicall או Subgraph עם שאילתות אצווה.
  • אי-התאמה ב-Hydration ב-Next.js: נתונים שמתקבלים בשרת לא תואמים לנתוני הלקוח בגלל זמני בקשה שונים. תיקון: דחיית שאילתות ללקוח באמצעות Wagmi.
  • נתונים מיושנים: ללא מטמון, משתמשים רואים מחירים לא מעודכנים. השתמשו ב-TTL של 60 שניות וב-// components/NetWorthCard.tsx export function NetWorthCard() { const { data, isLoading } = usePortfolio(); if (isLoading) return <Skeleton className="h-32" />; const total = (data?.aaveUSD ?? 0) + (data?.uniswapUSD ?? 0); return ( <div className="rounded-2xl border border-white/10 bg-gradient-to-br from-neutral-900 to-neutral-800 p-6"> <p className="text-sm text-neutral-400">Чистая стоимость</p> <p className="mt-1 text-4xl font-bold"> ${total.toLocaleString('en-US', { maximumFractionDigits: 2 })} </p> <div className="mt-4 flex gap-6 text-sm"> <Metric label="Aave" value={data?.aaveUSD} /> <Metric label="Uniswap LP" value={data?.uniswapUSD} /> </div> </div> ); } כדי לשמור על רעננות הנתונים.

אחד הלקוחות שלנו צמצם את זמן הניטור הידני מ-10 שעות בשבוע ל-15 דקות לאחר יישום לוח המחוונים—חיסכון של מעל 2,000 דולר בשנה בעלויות עבודה.

מה כלול במשלוח

אנחנו מוסרים פתרון מלא ומוכן:

  • אינטגרציה של פרוטוקולים נבחרים (עד 5)
  • ארכיטקטורה הבנויה על Next.js + TypeScript + Wagmi + TanStack Query
  • מטמון למחירים ולנתוני Subgraph
  • ממשק משתמש רספונסיבי באמצעות Tailwind CSS
  • תיעוד לפריסה ולהוספת פרוטוקולים חדשים
  • תמיכה חינמית לחודש אחד לאחר המסירה

לוחות זמנים

  • MVP עם פרוטוקול אחד (Aave) — 3-4 ימים
  • לוח מחוונים רב-פרוטוקולי (3-4 פרוטוקולים + גרפים + היסטוריה) — 1.5-2 שבועות
  • לוחות זמנים מדויקים מוערכים לאחר הבריף

הזמינו לוח מחוונים לתיק ההשקעות שלכם. קבלו ייעוץ: צרו קשר, ואנחנו נכין הצעה מותאמת לפרוטוקולים ולדרישות שלכם. למהנדסים שלנו יש ניסיון של 5+ שנים ב-DeFi והם מבטיחים פעילות יציבה של לוח המחוונים.