useStake()

Locks tokens in a staking contract to earn rewards. Requires prior approval of the staking contract.

Parameters

  • encryptKey (string): User’s decryption PIN
  • wallet (WalletData): Wallet credentials
  • contractAddress (string): Staking contract address
  • amount (string | number): Tokens to stake
  • recipient (string): Benefit recipient (usually user’s address)
  • decimals (number): Token decimals (default: 18)

Example Implementation

'use client'

import { useStake } from "@chipi-pay/chipi-sdk";
import { useState } from "react";

const VESU_CONTRACT = "0x037ae3f583c8d644b7556c93a04b83b52fa96159b2b0cbd83c14d3122aef80a2";

// Sample wallet data - replace with your wallet in production
const sampleWallet = {
  publicKey: "0x123...yourPublicKeyHere",
  privateKey: "encrypted:key:data" // This would be encrypted data in production
};

export function StakeForm() {
  const { stakeAsync, stakeData, isLoading, error } = useStake();
  const [form, setForm] = useState({
    pin: '',
    amount: ''
  });

  const handleStake = async (e: React.FormEvent) => {
    e.preventDefault();

    try {
      await stakeAsync({
        encryptKey: form.pin,
        wallet: {
          publicKey: sampleWallet.publicKey,
          encryptedPrivateKey: sampleWallet.privateKey
        },
        contractAddress: VESU_CONTRACT,
        amount: form.amount,
        recipient: sampleWallet.publicKey, // Staking to self
        decimals: 18
      });
    } 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 Tokens</h2>
      
      <div className="mb-4 p-3 bg-yellow-50 text-yellow-700 rounded-md">
        You must first <a href="/actions/approve.mdx" className="text-blue-600 hover:underline">approve the staking contract</a> before depositing.
      </div>

      <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>

        <button 
          type="submit" 
          disabled={isLoading}
          className="w-full bg-purple-600 text-white py-2 px-4 rounded-md hover:bg-purple-700 disabled:bg-gray-400"
        >
          {isLoading ? 'Staking...' : 'Deposit Tokens'}
        </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>
      )}

      {error && (
        <div className="mt-4 p-3 bg-red-50 text-red-700 rounded-md">
          Error: {error.message}
        </div>
      )}
    </div>
  );
}

:::info
Staked tokens are locked until the contract's withdrawal period. Check the staking contract's terms.
:::

## Related Actions

- **[Approve](approve.mdx)** - Required before first stake
- **[Withdraw](withdraw.mdx)** - To retrieve staked tokens
- **[Call Any Contract](#call-any-contract.mdx)** - For custom staking logic