### Clone and Install Project Dependencies Source: https://github.com/brunomuler/smoothie/blob/main/README.md This snippet demonstrates how to clone the Smoothie project repository and install its necessary dependencies using npm. Ensure Node.js and npm are installed on your system before running these commands. ```bash git clone https://github.com/your-username/smoothie.git cd smoothie npm install ``` -------------------------------- ### Get Balance History Source: https://github.com/brunomuler/smoothie/blob/main/README_DATABASE.md Retrieves balance history data for user positions, which can be used to populate charts. ```APIDOC ## GET /api/balance-history ### Description Returns balance history for charts. This endpoint requires user, asset, and number of days as query parameters. ### Method GET ### Endpoint /api/balance-history ### Parameters #### Query Parameters - **user** (string) - Required - The user's address. - **asset** (string) - Required - The asset's address. - **days** (number) - Required - The number of past days for which to retrieve balance history. ### Request Example ``` GET /api/balance-history?user=stellar_user_address&asset=stellar_asset_address&days=30 ``` ### Response #### Success Response (200) - **balance_history** (array) - An array of objects, where each object represents a daily balance snapshot. - **date** (string) - The date of the snapshot (YYYY-MM-DD). - **balance** (number) - The balance amount for that day. #### Response Example ```json { "balance_history": [ { "date": "2023-10-26", "balance": 100.50 }, { "date": "2023-10-27", "balance": 102.75 } ] } ``` ``` -------------------------------- ### Run Smoothie Development Server Source: https://github.com/brunomuler/smoothie/blob/main/README.md This snippet provides the command to start the Smoothie development server using npm. After running, you can access the dashboard at the specified local URL. This command is typically used during development for local testing. ```bash npm run dev # Then open http://localhost:3000 ``` -------------------------------- ### Configure PostgreSQL Connection URL Source: https://github.com/brunomuler/smoothie/blob/main/README_DATABASE.md This snippet shows how to set the DATABASE_URL environment variable for connecting to a PostgreSQL database. It includes placeholders for user, password, host, port, database name, and SSL mode. ```bash DATABASE_URL=postgresql://user:password@host:5432/database?sslmode=require ``` -------------------------------- ### Configure Environment Variables for Smoothie Source: https://github.com/brunomuler/smoothie/blob/main/README.md This snippet shows how to copy the example environment file and edit it to configure network settings, Stellar endpoints, and optional database connection strings for the Smoothie application. Ensure you replace placeholder values with your actual credentials. ```bash cp .env.local.example .env.local # Network: 'testnet' or 'public' NEXT_PUBLIC_STELLAR_NETWORK=public # Stellar endpoints NEXT_PUBLIC_STELLAR_HORIZON_URL=https://horizon.stellar.org NEXT_PUBLIC_RPC_URL=https://mainnet.sorobanrpc.com # Database (optional - for balance history) DATABASE_URL=postgresql://... ``` -------------------------------- ### SQL Schema for pool_snapshots Table Source: https://github.com/brunomuler/smoothie/blob/main/README_DATABASE.md Defines the schema for the `pool_snapshots` table in PostgreSQL. This table stores daily pool rates for token to value conversions, including pool ID, asset ID, rates, and snapshot date. An index is provided for optimized data retrieval. ```sql CREATE TABLE pool_snapshots ( id SERIAL PRIMARY KEY, pool_id VARCHAR(56) NOT NULL, asset_id VARCHAR(56) NOT NULL, b_rate NUMERIC, d_rate NUMERIC, snapshot_date DATE NOT NULL, created_at TIMESTAMP DEFAULT NOW() ); CREATE INDEX idx_pool_snapshots_lookup ON pool_snapshots(pool_id, asset_id, snapshot_date); ``` -------------------------------- ### SQL Schema for user_positions Table Source: https://github.com/brunomuler/smoothie/blob/main/README_DATABASE.md Defines the schema for the `user_positions` table in PostgreSQL. This table stores daily snapshots of user positions per pool/asset, including user address, pool ID, asset ID, token amounts, collateral, and snapshot date. It also includes an index for efficient lookups. ```sql CREATE TABLE user_positions ( id SERIAL PRIMARY KEY, user_address VARCHAR(56) NOT NULL, pool_id VARCHAR(56) NOT NULL, asset_id VARCHAR(56) NOT NULL, b_tokens NUMERIC, d_tokens NUMERIC, collateral NUMERIC, snapshot_date DATE NOT NULL, created_at TIMESTAMP DEFAULT NOW() ); CREATE INDEX idx_user_positions_lookup ON user_positions(user_address, asset_id, snapshot_date); ``` -------------------------------- ### GET /api/balance-history Source: https://context7.com/brunomuler/smoothie/llms.txt Retrieves historical balance data for a user's positions in a specific asset. The data is computed from on-chain events and daily interest rates. ```APIDOC ## GET /api/balance-history ### Description Retrieves historical balance data for a user's positions in a specific asset, computed from on-chain events and daily interest rates. ### Method GET ### Endpoint /api/balance-history ### Parameters #### Query Parameters - **user** (string) - Required - The wallet address of the user. - **asset** (string) - Required - The asset address for which to retrieve balance history. - **days** (number) - Optional - The number of past days to include in the history (default: 30). - **timezone** (string) - Optional - The timezone to use for date calculations (default: UTC). ### Response #### Success Response (200) - **user_address** (string) - The user's wallet address. - **asset_address** (string) - The asset address. - **days** (number) - The number of days requested for the history. - **count** (number) - The number of historical snapshots returned. - **history** (Array) - An array of historical balance snapshots. - **pool_id** (string) - The ID of the pool. - **snapshot_date** (string) - The date of the snapshot. - **supply_balance** (number) - The user's supply balance at the snapshot date. - **collateral_balance** (number) - The user's collateral balance at the snapshot date. - **debt_balance** (number) - The user's debt balance at the snapshot date. - **net_balance** (number) - The user's net balance (supply - debt) at the snapshot date. - **b_rate** (number) - The borrow rate at the snapshot date. - **d_rate** (number) - The deposit rate at the snapshot date. - **total_cost_basis** (number) - The total cost basis. - **total_yield** (number) - The total yield earned. - **firstEventDate** (string | null) - The date of the first recorded event for the user/asset. - **source** (string) - The data source (e.g., 'database'). #### Response Example ```json { "user_address": "GD64X5V6A3N7O43P4D76X4K3K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K43K4 ``` -------------------------------- ### GET /api/export/transactions Source: https://context7.com/brunomuler/smoothie/llms.txt Generates and exports a CSV file containing a user's transaction history, enriched with historical pricing data, suitable for tax reporting purposes. ```APIDOC ## GET /api/export/transactions ### Description Generates a CSV export of user transactions with historical pricing data for tax reporting. ### Method GET ### Endpoint /api/export/transactions ### Parameters #### Query Parameters - **user** (string) - Required - The wallet address of the user whose transactions are to be exported. - **startDate** (string) - Optional - The start date for the transaction history (YYYY-MM-DD format). - **endDate** (string) - Optional - The end date for the transaction history (YYYY-MM-DD format). ### Request Example ```javascript const walletAddress = "your_wallet_address"; const response = await fetch( `/api/export/transactions?user=${encodeURIComponent(walletAddress)}&startDate=2024-01-01&endDate=2024-12-31` ); ``` ### Response #### Success Response (200) The response body is a CSV file containing transaction data. #### Response Example ```csv Date,Action,Pool,Asset,Amount,Price USD,Value USD,Transaction Hash 2024-12-15,supply,Pool Name,USDC,1000.00,1.00,1000.00,abc123... 2024-12-16,withdraw,Pool Name,USDC,500.00,1.00,500.00,def456... ``` ``` -------------------------------- ### GET /api/backstop-cost-basis Source: https://context7.com/brunomuler/smoothie/llms.txt Retrieves cost basis information for backstop Liquidity Provider (LP) token positions. It calculates this by subtracting withdrawals from deposits for a given user, optionally filtered by a specific pool. ```APIDOC ## GET /api/backstop-cost-basis ### Description Retrieves cost basis information for backstop LP token positions (deposits minus withdrawals). ### Method GET ### Endpoint /api/backstop-cost-basis ### Parameters #### Query Parameters - **user** (string) - Required - The wallet address of the user. - **pool** (string) - Optional - The identifier for the pool to filter by. ### Request Example ```javascript const walletAddress = "your_wallet_address"; const response = await fetch( `/api/backstop-cost-basis?user=${encodeURIComponent(walletAddress)}` ); ``` ### Response #### Success Response (200) - **user_address** (string) - The wallet address of the user. - **count** (number) - The number of cost basis records found. - **cost_bases** (Array) - An array of cost basis details for each pool. - **pool_address** (string) - The address of the pool. - **user_address** (string) - The user's wallet address. - **total_deposited_lp** (number) - Total LP tokens deposited. - **total_withdrawn_lp** (number) - Total LP tokens withdrawn. - **cost_basis_lp** (number) - The calculated cost basis in LP tokens. - **first_deposit_date** (string) - The date of the first deposit. - **last_activity_date** (string) - The date of the last activity. #### Response Example ```json { "user_address": "your_wallet_address", "count": 1, "cost_bases": [ { "pool_address": "pool_address_123", "user_address": "your_wallet_address", "total_deposited_lp": 1500.50, "total_withdrawn_lp": 500.25, "cost_basis_lp": 1000.25, "first_deposit_date": "2024-01-10", "last_activity_date": "2024-03-15" } ] } ``` ``` -------------------------------- ### Fetch Paginated User Actions with Filtering Source: https://context7.com/brunomuler/smoothie/llms.txt The useUserActions hook fetches a paginated list of user actions, allowing filtering by action type, pool, asset, and date range. This example demonstrates its use in a TransactionHistory component, displaying actions in a table and providing pagination controls. It utilizes React's useState for managing filters and page state. ```typescript import { useUserActions } from '@/hooks/use-user-actions'; import { useState } from 'react'; function TransactionHistory({ userAddress }: { userAddress: string }) { const [filters, setFilters] = useState({ actionTypes: ['supply', 'withdraw', 'borrow', 'repay'], poolId: undefined as string | undefined, startDate: undefined as string | undefined, endDate: undefined as string | undefined }); const [page, setPage] = useState(0); const pageSize = 20; const { data, isLoading, isError, error } = useUserActions({ userAddress, limit: pageSize, offset: page * pageSize, actionTypes: filters.actionTypes, poolId: filters.poolId, startDate: filters.startDate, endDate: filters.endDate }); if (isLoading) return
Loading transactions...
; if (isError) return
Error: {error?.message}
; return (

Transaction History

{data?.actions.map(action => ( ))}
Date Action Pool Asset Amount Transaction
{new Date(action.ledger_closed_at).toLocaleString()} {action.action_type} {action.pool_name} {action.asset_symbol} {action.amount_underlying?.toFixed(4)} View
Page {page + 1}
); } ``` -------------------------------- ### Get Backstop Cost Basis for User Source: https://context7.com/brunomuler/smoothie/llms.txt Retrieves the cost basis for a user's backstop LP token positions. It requires the user's wallet address and optionally accepts a pool address. The output details deposited and withdrawn LP tokens, cost basis, and activity dates. ```typescript // GET /api/backstop-cost-basis // Query parameters: user (required), pool (optional) const response = await fetch( `/api/backstop-cost-basis?user=${encodeURIComponent(walletAddress)}` ); if (!response.ok) { throw new Error('Failed to fetch backstop cost basis'); } const data = await response.json(); // Response structure: // { // user_address: string // count: number // cost_bases: Array<{ // pool_address: string // user_address: string // total_deposited_lp: number // total_withdrawn_lp: number // cost_basis_lp: number // first_deposit_date: string // last_activity_date: string // }> // } data.cost_bases.forEach(basis => { const yieldLp = currentLpTokens - basis.cost_basis_lp; const yieldPercent = (yieldLp / basis.cost_basis_lp) * 100; console.log(`Pool: ${basis.pool_address}, Yield: ${yieldPercent.toFixed(2)}%`); }); ``` -------------------------------- ### GET /api/apy-history Source: https://context7.com/brunomuler/smoothie/llms.txt Retrieves historical APY data based on daily b_rate changes for a specified asset within a pool. It allows for specifying the number of past days to include in the history. ```APIDOC ## GET /api/apy-history ### Description Returns historical APY data calculated from daily b_rate changes for a specific asset in a pool. ### Method GET ### Endpoint /api/apy-history ### Parameters #### Query Parameters - **pool** (string) - Required - The identifier for the pool. - **asset** (string) - Required - The address of the asset. - **days** (number) - Optional - The number of past days to retrieve history for. Defaults to 180. ### Request Example ```javascript const poolId = "your_pool_id"; const assetAddress = "your_asset_address"; const response = await fetch( `/api/apy-history?pool=${encodeURIComponent(poolId)}&asset=${encodeURIComponent(assetAddress)}&days=90` ); ``` ### Response #### Success Response (200) - **pool_id** (string) - The ID of the pool. - **asset_address** (string) - The address of the asset. - **days** (number) - The number of days the history covers. - **count** (number) - The number of historical data points. - **history** (Array<{date: string (YYYY-MM-DD), apy: number}>) - An array of historical APY data points. #### Response Example ```json { "pool_id": "your_pool_id", "asset_address": "your_asset_address", "days": 90, "count": 90, "history": [ { "date": "2023-10-27", "apy": 5.25 }, { "date": "2023-10-28", "apy": 5.30 } ] } ``` ``` -------------------------------- ### Export User Transactions to CSV Source: https://context7.com/brunomuler/smoothie/llms.txt Generates a CSV file containing a user's transaction history, enriched with historical pricing data for tax reporting. This endpoint requires the user's wallet address and supports optional start and end dates for filtering. The response is a downloadable CSV file. ```typescript // GET /api/export/transactions // Query parameters: user (required), startDate (optional), endDate (optional) const response = await fetch( `/api/export/transactions?user=${encodeURIComponent(walletAddress)}&startDate=2024-01-01&endDate=2024-12-31` ); if (!response.ok) { throw new Error('Failed to export transactions'); } // Response is a CSV file download const csvBlob = await response.blob(); const url = window.URL.createObjectURL(csvBlob); const a = document.createElement('a'); a.href = url; a.download = `transactions-${walletAddress}-${Date.now()}.csv`; document.body.appendChild(a); a.click(); a.remove(); window.URL.revokeObjectURL(url); // CSV format: // Date,Action,Pool,Asset,Amount,Price USD,Value USD,Transaction Hash // 2024-12-15,supply,Pool Name,USDC,1000.00,1.00,1000.00,abc123... // 2024-12-16,withdraw,Pool Name,USDC,500.00,1.00,500.00,def456... ``` -------------------------------- ### Fetch Wallet Blend Snapshot with Positions and Emissions - TypeScript Source: https://context7.com/brunomuler/smoothie/llms.txt Loads a complete wallet snapshot from the Blend Protocol SDK, including positions, yields, and emissions data. This function automatically handles request deduplication and multi-level caching for efficiency. It takes a wallet address and an array of pools as input and returns a snapshot object containing detailed financial information. ```typescript import { fetchWalletBlendSnapshot } from '@/lib/blend/positions'; import { toTrackedPools } from '@/lib/blend/pools'; import type { Pool } from '@/lib/db/types'; async function loadUserPositions(walletAddress: string, pools: Pool[]) { try { // Convert database pool metadata to TrackedPool format const trackedPools = toTrackedPools(pools); // Fetch snapshot with automatic caching and deduplication const snapshot = await fetchWalletBlendSnapshot(walletAddress, trackedPools); // Process positions console.log(`Total Supply: $${snapshot.totalSupplyUsd.toFixed(2)}`); console.log(`Total Borrow: $${snapshot.totalBorrowUsd.toFixed(2)}`); console.log(`Net Position: $${snapshot.netPositionUsd.toFixed(2)}`); console.log(`Weighted Supply APY: ${snapshot.weightedSupplyApy?.toFixed(2)}%`); console.log(`Net APY: ${snapshot.netApy?.toFixed(2)}%`); // Individual positions snapshot.positions.forEach(pos => { console.log(`${pos.symbol}: Supply ${pos.supplyAmount.toFixed(4)}, Borrow ${pos.borrowAmount.toFixed(4)}`); console.log(` Supply APY: ${pos.supplyApy.toFixed(2)}%, Borrow APY: ${pos.borrowApy.toFixed(2)}%`); console.log(` BLND Emissions: ${pos.claimableBlnd.toFixed(4)} BLND`); console.log(` B-Rate: ${pos.bRate}, D-Rate: ${pos.dRate}`); }); // Backstop positions snapshot.backstopPositions.forEach(pos => { console.log(`Backstop ${pos.poolName}:`); console.log(` LP Tokens: ${pos.lpTokens.toFixed(4)} ($${pos.lpTokensUsd.toFixed(2)})`); console.log(` Interest APR: ${pos.interestApr.toFixed(2)}%`); console.log(` Emission APY: ${pos.emissionApy.toFixed(2)}%`); console.log(` BLND/USDC: ${pos.blndAmount.toFixed(2)} / ${pos.usdcAmount.toFixed(2)}`); console.log(` Q4W: ${pos.q4wLpTokens.toFixed(4)} LP (${pos.q4wChunks.length} chunks)`); if (pos.q4wExpiration) { console.log(` Next unlock: ${new Date(pos.q4wExpiration * 1000).toLocaleString()}`); } }); // Emissions summary console.log(`Total Claimable BLND: ${snapshot.totalEmissions.toFixed(4)}`); console.log(`BLND Price: $${snapshot.blndPrice?.toFixed(4)}`); console.log(`LP Token Price: $${snapshot.lpTokenPrice?.toFixed(4)}`); return snapshot; } catch (error) { console.error('Failed to load positions:', error); throw error; } } ``` -------------------------------- ### Fetch User Action History API (TypeScript) Source: https://context7.com/brunomuler/smoothie/llms.txt Fetches paginated transaction history for a user, detailing events like deposits, withdrawals, borrows, repays, and liquidations. This API requires the user's wallet address and supports filtering by limit, offset, pool, asset, action types, and date range. The response includes transaction details such as ID, pool, hash, timestamp, action type, asset symbol, and amounts. ```typescript // GET /api/user-actions // Query parameters: user (required), limit, offset, pool, asset, actionTypes, startDate, endDate const response = await fetch( `/api/user-actions?user=${encodeURIComponent(walletAddress)}&limit=50&offset=0&actionTypes=supply,withdraw,borrow,repay` ); if (!response.ok) { throw new Error('Failed to fetch user actions'); } const data = await response.json(); // Response structure: // { // user_address: string // count: number // limit: number // offset: number // actions: Array<{ // id: number // pool_id: string // transaction_hash: string // ledger_closed_at: string (ISO 8601) // action_type: string // asset_symbol: string // amount_underlying: number | null // amount_tokens: number | null // implied_rate: number | null // }> // } data.actions.forEach(action => { console.log(`${action.ledger_closed_at}: ${action.action_type} ${action.amount_underlying} ${action.asset_symbol}`); }); ```