diff --git a/src/pages/_borrow/BorrowMobileCard.tsx b/src/pages/_borrow/BorrowMobileCard.tsx
new file mode 100644
index 00000000..215eaea0
--- /dev/null
+++ b/src/pages/_borrow/BorrowMobileCard.tsx
@@ -0,0 +1,85 @@
+import { useMemo } from 'react';
+
+import { Button } from '@components/Button';
+import { Loading } from '@components/Loading';
+import { usePools } from '@contexts/pool-context';
+import { useWallet } from '@contexts/wallet-context';
+import { isBalanceZero } from '@lib/converters';
+import { formatAPR, formatAmount, toDollarsFormatted } from '@lib/formatting';
+import { isNil } from 'ramda';
+import type { CurrencyBinding } from 'src/currency-bindings';
+
+export interface BorrowMobileCardProps {
+ currency: CurrencyBinding;
+ onBorrowClicked: VoidFunction;
+}
+
+export const BorrowMobileCard = ({ currency, onBorrowClicked }: BorrowMobileCardProps) => {
+ const { icon, name, ticker, issuerName } = currency;
+
+ const { wallet, walletBalances } = useWallet();
+ const { prices, pools } = usePools();
+ const pool = pools?.[ticker];
+ const price = prices?.[ticker];
+
+ // Does the user have some other token in their wallet to use as a collateral?
+ const isCollateral = !walletBalances
+ ? false
+ : Object.entries(walletBalances)
+ .filter(([t, _b]) => t !== ticker)
+ .some(([_t, b]) => b.trustLine && !isBalanceZero(b.balanceLine.balance));
+
+ const borrowDisabled = !wallet || !isCollateral || !pool || pool.availableBalanceTokens === 0n;
+
+ const tooltip = useMemo(() => {
+ if (!pool) return 'The pool is loading';
+ if (pool.availableBalanceTokens === 0n) return 'the pool has no assets to borrow';
+ if (!wallet) return 'Connect a wallet first';
+ if (!isCollateral) return 'Another token needed for the collateral';
+ return 'Something odd happened.';
+ }, [pool, wallet, isCollateral]);
+
+ return (
+
+
+

+
+
{name}
+
+ {ticker} • {issuerName}
+
+
+
+
+
+
+
Available
+
+ {pool ? formatAmount(pool.availableBalanceTokens) : }
+
+
+ {!isNil(price) && !isNil(pool) && toDollarsFormatted(price, pool.availableBalanceTokens)}
+
+
+
+
Borrow APY
+
{pool ? formatAPR(pool.annualInterestRate) : }
+
+
+
+
+ {borrowDisabled ? (
+
+
+
+ ) : (
+
+ )}
+
+
+ );
+};
diff --git a/src/pages/_borrow/BorrowPage.tsx b/src/pages/_borrow/BorrowPage.tsx
index 964a4f2f..8d01c31f 100644
--- a/src/pages/_borrow/BorrowPage.tsx
+++ b/src/pages/_borrow/BorrowPage.tsx
@@ -8,6 +8,7 @@ import { usePools } from '@contexts/pool-context';
import { useWallet } from '@contexts/wallet-context';
import { contractId } from '@contracts/loan_manager';
import { CURRENCY_BINDINGS_ARR, type CurrencyBinding } from 'src/currency-bindings';
+import { BorrowMobileCard } from './BorrowMobileCard';
import { BorrowModal } from './BorrowModal/BorrowModal';
import { BorrowableAsset } from './BorrowableAsset';
@@ -44,15 +45,26 @@ const BorrowPage = () => {
Borrow Assets
-
+
{CURRENCY_BINDINGS_ARR.map((currency) => (
- openBorrowModal(currency)}
/>
))}
-
+
+
+
+ {CURRENCY_BINDINGS_ARR.map((currency) => (
+ openBorrowModal(currency)}
+ />
+ ))}
+
+
diff --git a/src/pages/_lend/LendMobileCard.tsx b/src/pages/_lend/LendMobileCard.tsx
new file mode 100644
index 00000000..73e7b7f4
--- /dev/null
+++ b/src/pages/_lend/LendMobileCard.tsx
@@ -0,0 +1,69 @@
+import { Button } from '@components/Button';
+import { Loading } from '@components/Loading';
+import { usePools } from '@contexts/pool-context';
+import { type Balance, useWallet } from '@contexts/wallet-context';
+import { isBalanceZero } from '@lib/converters';
+import { formatAPY, formatAmount, toDollarsFormatted } from '@lib/formatting';
+import { isNil } from 'ramda';
+import type { CurrencyBinding } from 'src/currency-bindings';
+
+export interface LendMobileCardProps {
+ currency: CurrencyBinding;
+ onDepositClicked: VoidFunction;
+}
+
+export const LendMobileCard = ({ currency, onDepositClicked }: LendMobileCardProps) => {
+ const { icon, name, ticker, issuerName } = currency;
+
+ const { wallet, walletBalances } = useWallet();
+ const { prices, pools } = usePools();
+ const pool = pools?.[ticker];
+ const price = prices?.[ticker];
+ const balance: Balance | undefined = walletBalances?.[ticker];
+
+ const isPoor = !balance?.trustLine || isBalanceZero(balance.balanceLine.balance);
+
+ return (
+
+
+

+
+
{name}
+
+ {ticker} • {issuerName}
+
+
+
+
+
+
+
Balance
+
+ {pool ? formatAmount(pool.totalBalanceTokens) : }
+
+
+ {!isNil(price) && !isNil(pool) && toDollarsFormatted(price, pool.totalBalanceTokens)}
+
+
+
+
Supply APY
+
{pool ? formatAPY(pool.annualInterestRate) : }
+
+
+
+
+ {isPoor ? (
+
+
+
+ ) : (
+
+ )}
+
+
+ );
+};
diff --git a/src/pages/_lend/LendPage.tsx b/src/pages/_lend/LendPage.tsx
index ba787418..ee5f83d3 100644
--- a/src/pages/_lend/LendPage.tsx
+++ b/src/pages/_lend/LendPage.tsx
@@ -8,6 +8,7 @@ import { usePools } from '@contexts/pool-context';
import { contractId } from '@contracts/loan_manager';
import { CURRENCY_BINDINGS_ARR, type CurrencyBinding } from 'src/currency-bindings';
import { DepositModal } from './DepositModal';
+import { LendMobileCard } from './LendMobileCard';
import { LendableAsset } from './LendableAsset';
const links = [
@@ -41,15 +42,26 @@ const LendPage = () => {
Lend Assets
-
+
{CURRENCY_BINDINGS_ARR.map((currency) => (
- openDepositModal(currency)}
/>
))}
-
+
+
+
+ {CURRENCY_BINDINGS_ARR.map((currency) => (
+ openDepositModal(currency)}
+ />
+ ))}
+
+