Usage
const {
stake,
stakeAsync,
stakeData,
isLoading,
isError
} = useStakeVesuUsdc();
Parameters
The hook accepts the following parameters when calling stake
or stakeAsync
:
encryptKey
(string): User’s decryption PIN
wallet
(WalletData): Wallet public/private key pair
amount
(string | number): Amount of USDC to stake
receiverWallet
(string): Address to receive the staked tokens
bearerToken
(string): Authentication token for the API
Return Value
Returns an object containing:
stake
: Function to trigger staking (mutate)
stakeAsync
: Async function to trigger staking (mutateAsync)
stakeData
: Transaction hash of the stake operation
isLoading
: Boolean indicating if the operation is in progress
isError
: Boolean indicating if an error occurred
Example Implementation
'use client'
import { useStakeVesuUsdc } from "@chipi-pay/chipi-sdk";
import { useState } from "react";
export function StakeForm() {
const {
stakeAsync,
stakeData,
isLoading,
isError
} = useStakeVesuUsdc();
const [form, setForm] = useState({
pin: '',
amount: '',
receiverWallet: ''
});
const handleStake = async (e: React.FormEvent) => {
e.preventDefault();
try {
await stakeAsync({
encryptKey: form.pin,
wallet: {
publicKey: "0x123...yourPublicKeyHere",
encryptedPrivateKey: "encrypted:key:data"
},
amount: form.amount,
receiverWallet: form.receiverWallet,
bearerToken: "your-bearer-token"
});
} catch (err) {
console.error('Staking failed:', err);
}
};
return (
<div className="bg-white rounded-xl shadow-lg p-6">
<h2 className="text-2xl font-bold mb-4">Stake USDC</h2>
<form onSubmit={handleStake} className="space-y-4">
<div>
<label className="block text-sm font-medium mb-1">Security PIN</label>
<input
type="password"
value={form.pin}
onChange={(e) => setForm({...form, pin: e.target.value})}
className="w-full p-2 border rounded-md"
required
/>
</div>
<div>
<label className="block text-sm font-medium mb-1">Amount to Stake</label>
<input
type="number"
value={form.amount}
onChange={(e) => setForm({...form, amount: e.target.value})}
className="w-full p-2 border rounded-md"
required
/>
</div>
<div>
<label className="block text-sm font-medium mb-1">Receiver Wallet</label>
<input
type="text"
value={form.receiverWallet}
onChange={(e) => setForm({...form, receiverWallet: e.target.value})}
className="w-full p-2 border rounded-md"
required
placeholder="0x..."
/>
</div>
<button
type="submit"
disabled={isLoading}
className="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 disabled:bg-gray-400"
>
{isLoading ? 'Staking...' : 'Stake USDC'}
</button>
</form>
{stakeData && (
<div className="mt-4 p-3 bg-gray-50 rounded-md">
<p className="text-sm font-mono break-all">
Stake TX: {stakeData}
</p>
</div>
)}
{isError && (
<div className="mt-4 p-3 bg-red-50 text-red-700 rounded-md">
Error: Failed to stake tokens
</div>
)}
</div>
);
}
Implementation Details
The hook performs two transactions in sequence:
-
Approval Transaction
- Contract:
0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8
- Entrypoint:
approve
- Calldata: [spender, amount, 0]
-
Deposit Transaction
- Contract:
0x017f19582c61479f2fe0b6606300e975c0a8f439102f43eeecc1d0e9b3d84350
- Entrypoint:
deposit
- Calldata: [amount, 0, receiverWallet]
Security Considerations
- Ensure proper encryption of private keys
- Validate receiver wallet address
- Implement proper PIN validation
- Use secure storage for wallet data
- Monitor transaction status
Error Handling
- Handle insufficient token balance
- Validate wallet addresses
- Check for existing approvals
- Monitor gas fees
- Implement retry logic for failed transactions
Make sure you have sufficient USDC balance and have approved the VESU contract before staking.