Skip to content

Commit

Permalink
add repay button
Browse files Browse the repository at this point in the history
  • Loading branch information
jazz-cb committed Sep 17, 2024
1 parent bec728e commit 1f2c803
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 7 deletions.
52 changes: 52 additions & 0 deletions app/api/aave/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,58 @@ export async function POST(request: Request) {
}
}

if (action === 'repay') {
try {
const amountToRepay = parseUnits(amount, 6);

// First, approve USDC spend
const approveContract = await wallet.invokeContract({
contractAddress: USDC_ADDRESS,
method: "approve",
args: {
spender: AAVE_POOL_ADDRESS,
value: amountToRepay.toString()
},
abi: usdcAbi,
});

const approveTx = await approveContract.wait();
if (!approveTx) {
throw new Error('Failed to approve USDC spend');
}

console.log('USDC spend approved for repayment:', approveTx);

// Now, repay the loan
const repayContract = await wallet.invokeContract({
contractAddress: AAVE_POOL_ADDRESS,
method: "repay",
args: {
asset: USDC_ADDRESS,
amount: amountToRepay.toString(),
interestRateMode: "2",
onBehalfOf: address.getId()
},
abi: aaveAbi,
});

const repayTx = await repayContract.wait();
if (!repayTx) {
throw new Error('Failed to repay USDC to Aave');
}

console.log('USDC repaid to Aave:', repayTx);

return NextResponse.json({success: true, txHash: repayTx.getTransactionHash()});
} catch (error) {
console.error('Failed to repay loan:', error);
return NextResponse.json({
error: 'Failed to repay loan',
details: error instanceof Error ? error.message : String(error)
}, {status: 500});
}
}

return NextResponse.json({ error: 'Invalid action' }, { status: 400 });
}

Expand Down
68 changes: 62 additions & 6 deletions app/usdcflow/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,21 @@ export default function AaveInteraction() {
const [accountData, setAccountData] = useState<any>(null);
const [supplyAmount, setSupplyAmount] = useState<string>('');
const [borrowAmount, setBorrowAmount] = useState<string>('');
const [repayAmount, setRepayAmount] = useState<string>('');
const [isLoading, setIsLoading] = useState<boolean>(true);
const [isSupplying, setIsSupplying] = useState<boolean>(false);
const [isBorrowing, setIsBorrowing] = useState<boolean>(false);
const [isRepaying, setIsRepaying] = useState<boolean>(false);
const [error, setError] = useState<string>('');

const [supplyOutput, setSupplyOutput] = useState<{ amount: string, txHash: string } | null>(null);
const [borrowOutput, setBorrowOutput] = useState<{ amount: string, txHash: string } | null>(null);
const [repayOutput, setRepayOutput] = useState<{ amount: string, txHash: string } | null>(null);

const clearTransactionData = () => {
setSupplyOutput(null);
setBorrowOutput(null);
setRepayOutput(null);
setError('');
};

Expand Down Expand Up @@ -85,6 +89,28 @@ export default function AaveInteraction() {
}
};

const repayToAave = async () => {
if (!repayAmount) return;
clearTransactionData();
setIsRepaying(true);
try {
const response = await fetch('/api/aave', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({action: 'repay', amount: repayAmount}),
});
if (!response.ok) throw new Error('Failed to repay loan');
const data = await response.json();
setRepayOutput({ amount: repayAmount, txHash: data.txHash });
getUserAccountData();
} catch (err) {
console.error('Failed to repay loan:', err);
setError('Failed to repay loan. Please try again.');
} finally {
setIsRepaying(false);
}
};

const closeIntro = () => {
setShowIntro(false);
};
Expand Down Expand Up @@ -164,15 +190,15 @@ export default function AaveInteraction() {
<AlertDescription>{error}</AlertDescription>
</Alert>
)}
<Button onClick={getUserAccountData} className="mb-4 bg-blue-600 hover:bg-blue-700 text-white">
Refresh Account Data
<Button onClick={getUserAccountData} className="mb-4 bg-gradient-to-r from-lavender-400 to-blue-500 hover:from-lavender-500 hover:to-blue-600 text-white transition-all duration-300">
Refresh Account Data
</Button>
{accountData && (
<div className="bg-lavender-50 p-4 rounded-lg">
<p className="mb-1">Wallet Address: {accountData.walletAddress}</p>
<p className="mb-1">Wallet Balance: {parseFloat(accountData.usdcBalance).toFixed(2)} USDC</p>
<p className="mb-1">Total Deposited: {accountData.totalDeposited} USDC</p>
<p className="mb-1">Total Debt: {accountData.totalDebtBase} USDC</p>
<p className="mb-1">Total Supplied: {accountData.totalDeposited} USDC</p>
<p className="mb-1">Total Borrowed: {accountData.totalDebtBase} USDC</p>
<p className="mb-1">Available to borrow: {accountData.availableBorrowsBase} USDC</p>
</div>
)}
Expand All @@ -195,7 +221,7 @@ export default function AaveInteraction() {
}}
className="mb-4"
/>
<Button onClick={supplyToAave} disabled={isSupplying} className="w-full bg-blue-600 hover:bg-blue-700 text-white">
<Button onClick={supplyToAave} disabled={isSupplying} className="w-full bg-gradient-to-r from-lavender-400 to-blue-500 hover:from-lavender-500 hover:to-blue-600 text-white transition-all duration-300">
{isSupplying && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
Supply to Aave
</Button>
Expand All @@ -220,7 +246,7 @@ export default function AaveInteraction() {
onChange={(e) => setBorrowAmount(e.target.value)}
className="mb-4"
/>
<Button onClick={borrowFromAave} disabled={isBorrowing} className="w-full bg-blue-600 hover:bg-blue-700 text-white">
<Button onClick={borrowFromAave} disabled={isBorrowing} className="w-full bg-gradient-to-r from-lavender-400 to-blue-500 hover:from-lavender-500 hover:to-blue-600 text-white transition-all duration-300">
{isBorrowing && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
Borrow from Aave
</Button>
Expand All @@ -232,6 +258,36 @@ export default function AaveInteraction() {
</CardFooter>
)}
</Card>

<Card className="bg-white shadow-lg">
<CardHeader>
<CardTitle className="text-xl text-blue-600">Repay Loan</CardTitle>
</CardHeader>
<CardContent>
<Input
type="number"
placeholder="Amount to repay (USDC)"
value={repayAmount}
onChange={(e) => setRepayAmount(e.target.value)}
className="mb-4"
/>
<Button
onClick={repayToAave}
disabled={isRepaying}
className="w-full bg-gradient-to-r from-lavender-400 to-blue-500 hover:from-lavender-500 hover:to-blue-600 text-white transition-all duration-300"
>
{isRepaying && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
Repay Loan
</Button>
</CardContent>
{repayOutput && (
<CardFooter className="flex flex-col items-start">
<p className="mb-2">Repaid Amount: {repayOutput.amount} USDC</p>
<p>Transaction Hash: {repayOutput.txHash}</p>
</CardFooter>
)}
</Card>

</div>
</>
)}
Expand Down
3 changes: 2 additions & 1 deletion vercel.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"value": "usdcflow.xyz"
}
],
"destination": "/usdcflow/:path*"
"destination": "https://www.cdp-sdk.xyz/usdcflow",
"permanent": false
}
]
}

0 comments on commit 1f2c803

Please sign in to comment.