> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Staking Solana theo chương trình với Helius SDK

> Xây dựng trải nghiệm staking Solana liền mạch với Helius SDK. Hướng dẫn đầy đủ từ thiết lập đến rút tiền, tích hợp trình xác thực có mức hoa hồng 0%.

<Info>
  **Trình xác thực không thu hoa hồng**: Stake với trình xác thực Helius và giữ lại 100% phần thưởng staking nhờ mức hoa hồng 0% của chúng tôi.
</Info>

## Tổng quan nhanh

Helius SDK cung cấp các phương thức đơn giản để xử lý toàn bộ vòng đời staking SOL theo chương trình. Hoàn hảo để xây dựng giao diện staking, giao thức DeFi hoặc chiến lược staking tự động.

<CardGroup cols={3}>
  <Card title="Create & Delegate" icon="plus">
    Thiết lập tài khoản stake mới và ủy quyền cho trình xác thực trong một giao dịch
  </Card>

  <Card title="Monitor & Manage" icon="chart-line">
    Theo dõi phần thưởng, kiểm tra trạng thái và quản lý các tài khoản stake hiện có
  </Card>

  <Card title="Withdraw & Redeem" icon="money-bill">
    Hủy kích hoạt stake và rút SOL sau thời gian chờ
  </Card>
</CardGroup>

## Cài đặt và thiết lập

<CodeGroup>
  ```bash npm theme={"system"}
  npm install helius-sdk @solana/web3.js bs58
  ```

  ```bash yarn   theme={"system"}
  yarn add helius-sdk @solana/web3.js bs58
  ```

  ```bash pnpm theme={"system"}
  pnpm add helius-sdk @solana/web3.js bs58
  ```
</CodeGroup>

<CodeGroup>
  ```typescript Setup theme={"system"}
  import { Helius } from 'helius-sdk';
  import { Keypair, Transaction } from '@solana/web3.js';
  import bs58 from 'bs58';

  // Initialize Helius client
  const helius = new Helius('YOUR_API_KEY');

  // Your wallet keypair (load from your secure storage)
  const payer = Keypair.fromSecretKey(/* your secret key */);
  ```
</CodeGroup>

## Kiến thức cơ bản về staking

<AccordionGroup>
  <Accordion title="How Solana Staking Works">
    **Tài khoản stake**: Một tài khoản đặc biệt khóa SOL và ủy quyền SOL đó cho một trình xác thực. Mỗi tài khoản stake chỉ trỏ đến đúng một trình xác thực.

    **Phần thưởng**: Các trình xác thực nhận phần thưởng khi bảo mật mạng. Những phần thưởng này được phân phối cho tất cả tài khoản stake đã ủy quyền cho trình xác thực đó.

    **Vòng đời**: Tạo → Ủy quyền → Nhận phần thưởng → Hủy kích hoạt → Rút
  </Accordion>

  <Accordion title="Why Choose Helius Validator">
    * **Hoa hồng 0%**: Giữ lại 100% phần thưởng staking
    * **Hiệu suất cao**: Sản xuất khối ổn định và thời gian ngừng hoạt động tối thiểu
    * **Dễ tích hợp**: Được tối ưu hóa cho Helius SDK với các trình trợ giúp tích hợp sẵn
  </Accordion>

  <Accordion title="Timing & Epochs">
    * **Kích hoạt**: Stake bắt đầu hoạt động vào đầu epoch tiếp theo (\~2 ngày)
    * **Hủy kích hoạt**: Có hiệu lực vào cuối epoch hiện tại
    * **Thời gian chờ**: Có thể rút stake đã hủy kích hoạt ngay sau khi epoch kết thúc
  </Accordion>
</AccordionGroup>

## Bắt đầu

<Tabs>
  <Tab title="Quick Start">
    Stake SOL chỉ với 3 dòng mã:

    ```typescript theme={"system"}
    // 1. Create the staking transaction
    const { serializedTx, stakeAccountPubkey } = 
      await helius.rpc.createStakeTransaction(payer.publicKey, 1.5);

    // 2. Sign and send
    const tx = Transaction.from(bs58.decode(serializedTx));
    tx.partialSign(payer);
    const signature = await helius.connection.sendRawTransaction(tx.serialize());

    console.log(`Staked! Transaction: ${signature}`);
    console.log(`Stake Account: ${stakeAccountPubkey}`);
    ```

    <Info>
      SDK tự động xử lý việc tính phí thuê và tạo tài khoản stake. Tham số `1.5` là số lượng SOL bạn muốn stake.
    </Info>
  </Tab>

  <Tab title="Complete Example">
    Triển khai staking đầy đủ với cơ chế xử lý lỗi:

    ```typescript theme={"system"}
    async function stakeSOL(amountInSol: number) {
      try {
        // Create staking transaction
        const { serializedTx, stakeAccountPubkey } = 
          await helius.rpc.createStakeTransaction(payer.publicKey, amountInSol);
        
        // Deserialize and sign transaction
        const transaction = Transaction.from(bs58.decode(serializedTx));
        transaction.partialSign(payer);
        
        // Send transaction
        const signature = await helius.connection.sendRawTransaction(
          transaction.serialize(),
          { 
            skipPreflight: false,
            preflightCommitment: 'confirmed'
          }
        );
        
        // Wait for confirmation
        await helius.connection.confirmTransaction(signature, 'confirmed');
        
        return {
          signature,
          stakeAccount: stakeAccountPubkey,
          amount: amountInSol
        };
        
      } catch (error) {
        console.error('Staking failed:', error);
        throw error;
      }
    }

    // Usage
    const result = await stakeSOL(2.5);
    console.log(`Successfully staked ${result.amount} SOL`);
    ```
  </Tab>
</Tabs>

## Tham chiếu các phương thức SDK

<AccordionGroup>
  <Accordion title="createStakeTransaction(owner, amount)">
    Tạo một giao dịch staking hoàn chỉnh có thể được ký và gửi.

    **Tham số:**

    * `owner` (PublicKey): Ví sẽ sở hữu tài khoản stake
    * `amount` (number): Số lượng SOL cần stake

    **Trả về:**

    ```typescript theme={"system"}
    {
      serializedTx: string,        // Base58 encoded transaction
      stakeAccountPubkey: string   // New stake account address
    }
    ```

    **Ví dụ:**

    ```typescript theme={"system"}
    const result = await helius.rpc.createStakeTransaction(
      payer.publicKey, 
      1.5  // 1.5 SOL
    );
    ```
  </Accordion>

  <Accordion title="getStakeInstructions(owner, amount)">
    Chỉ trả về các lệnh staking (hữu ích khi tự tạo giao dịch tùy chỉnh).

    **Trả về:**

    ```typescript theme={"system"}
    {
      instructions: TransactionInstruction[],
      stakeAccount: Keypair
    }
    ```

    **Ví dụ:**

    ```typescript theme={"system"}
    const { instructions } = await helius.rpc.getStakeInstructions(
      payer.publicKey, 
      1.5
    );

    // Use with Smart Transactions
    const signature = await helius.rpc.sendSmartTransaction(
      instructions, 
      [payer]
    );
    ```
  </Accordion>

  <Accordion title="getHeliusStakeAccounts(wallet)">
    Truy xuất tất cả tài khoản stake của một ví đã ủy quyền cho trình xác thực Helius.

    **Ví dụ:**

    ```typescript theme={"system"}
    const accounts = await helius.rpc.getHeliusStakeAccounts(
      payer.publicKey.toBase58()
    );

    accounts.forEach(account => {
      const delegation = account.account.data.parsed.info.stake.delegation;
      console.log(`Account: ${account.pubkey}`);
      console.log(`Stake: ${delegation.stake / LAMPORTS_PER_SOL} SOL`);
    });
    ```
  </Accordion>

  <Accordion title="createUnstakeTransaction(owner, stakeAccount)">
    Tạo giao dịch để hủy kích hoạt (bắt đầu unstake) một tài khoản stake.

    **Ví dụ:**

    ```typescript theme={"system"}
    const tx = await helius.rpc.createUnstakeTransaction(
      payer.publicKey,
      stakeAccountPubkey
    );

    const transaction = Transaction.from(bs58.decode(tx));
    transaction.partialSign(payer);
    await helius.connection.sendRawTransaction(transaction.serialize());
    ```
  </Accordion>

  <Accordion title="getWithdrawableAmount(stakeAccount, includeRent?)">
    Kiểm tra số lượng SOL có thể rút từ một tài khoản stake đã hủy kích hoạt.

    **Tham số:**

    * `includeRent` (boolean): Có bao gồm số tiền được miễn phí thuê hay không

    **Ví dụ:**

    ```typescript theme={"system"}
    const available = await helius.rpc.getWithdrawableAmount(stakeAccountPubkey);
    const total = await helius.rpc.getWithdrawableAmount(stakeAccountPubkey, true);

    console.log(`Available now: ${available / LAMPORTS_PER_SOL} SOL`);
    console.log(`Total balance: ${total / LAMPORTS_PER_SOL} SOL`);
    ```
  </Accordion>

  <Accordion title="createWithdrawTransaction(owner, stakeAccount, destination, amount)">
    Tạo giao dịch để rút SOL từ một tài khoản stake đã hủy kích hoạt.

    **Ví dụ:**

    ```typescript theme={"system"}
    const tx = await helius.rpc.createWithdrawTransaction(
      payer.publicKey,
      stakeAccountPubkey,
      destinationPubkey,
      withdrawAmount  // in lamports
    );
    ```
  </Accordion>
</AccordionGroup>

## Quy trình staking hoàn chỉnh

<Steps>
  <Step title="Create and Delegate">
    ```typescript theme={"system"}
    // Stake 2 SOL to Helius validator
    const { serializedTx, stakeAccountPubkey } = 
      await helius.rpc.createStakeTransaction(payer.publicKey, 2.0);

    const tx = Transaction.from(bs58.decode(serializedTx));
    tx.partialSign(payer);

    const signature = await helius.connection.sendRawTransaction(tx.serialize());
    console.log(`Stake created: ${stakeAccountPubkey}`);
    ```
  </Step>

  <Step title="Monitor Your Stakes">
    ```typescript theme={"system"}
    // Get all your Helius stake accounts
    const accounts = await helius.rpc.getHeliusStakeAccounts(
      payer.publicKey.toBase58()
    );

    console.log(`You have ${accounts.length} active stake accounts`);

    accounts.forEach((account, index) => {
      const info = account.account.data.parsed.info;
      const delegation = info.stake.delegation;
      
      console.log(`Stake ${index + 1}:`);
      console.log(`  Amount: ${delegation.stake / LAMPORTS_PER_SOL} SOL`);
      console.log(`  Activated: Epoch ${delegation.activationEpoch}`);
      console.log(`  Status: ${info.meta.lockup.unixTimestamp === 0 ? 'Active' : 'Locked'}`);
    });
    ```
  </Step>

  <Step title="Deactivate (Start Unstaking)">
    ```typescript theme={"system"}
    // Begin the unstaking process
    const unstakeTx = await helius.rpc.createUnstakeTransaction(
      payer.publicKey,
      stakeAccountPubkey
    );

    const tx = Transaction.from(bs58.decode(unstakeTx));
    tx.partialSign(payer);

    await helius.connection.sendRawTransaction(tx.serialize());
    console.log('Deactivation started. Will be withdrawable next epoch.');
    ```
  </Step>

  <Step title="Withdraw SOL">
    ```typescript theme={"system"}
    // Check withdrawable amount
    const withdrawable = await helius.rpc.getWithdrawableAmount(
      stakeAccountPubkey, 
      true  // include rent
    );

    if (withdrawable > 0) {
      // Create withdrawal instruction
      const withdrawInstruction = helius.rpc.getWithdrawInstruction(
        payer.publicKey,
        stakeAccountPubkey,
        payer.publicKey,  // withdraw to same wallet
        withdrawable
      );
      
      // Send using Smart Transactions for better reliability
      const signature = await helius.rpc.sendSmartTransaction(
        [withdrawInstruction], 
        [payer]
      );
      
      console.log(`Withdrawn ${withdrawable / LAMPORTS_PER_SOL} SOL`);
    }
    ```
  </Step>
</Steps>

## Mẫu nâng cao

<Tabs>
  <Tab title="Browser Integration">
    Dành cho các ứng dụng trình duyệt sử dụng bộ điều hợp ví:

    ```typescript theme={"system"}
    // Get instructions instead of full transaction
    const { instructions, stakeAccount } = await helius.rpc.getStakeInstructions(
      wallet.publicKey,
      stakeAmount
    );

    // Let the wallet handle transaction building and signing
    const transaction = new Transaction().add(...instructions);

    // Sign with wallet adapter
    const signature = await wallet.sendTransaction(transaction, connection);

    console.log(`Stake account: ${stakeAccount.publicKey.toBase58()}`);
    ```
  </Tab>

  <Tab title="Batch Operations">
    Stake hiệu quả cho nhiều ví:

    ```typescript theme={"system"}
    async function batchStake(wallets: Keypair[], amount: number) {
      const promises = wallets.map(async (wallet) => {
        try {
          const { serializedTx, stakeAccountPubkey } = 
            await helius.rpc.createStakeTransaction(wallet.publicKey, amount);
          
          const tx = Transaction.from(bs58.decode(serializedTx));
          tx.partialSign(wallet);
          
          return helius.connection.sendRawTransaction(tx.serialize());
        } catch (error) {
          console.error(`Failed to stake for ${wallet.publicKey.toBase58()}:`, error);
          return null;
        }
      });
      
      const results = await Promise.allSettled(promises);
      const successful = results.filter(r => r.status === 'fulfilled').length;
      
      console.log(`Successfully staked for ${successful}/${wallets.length} wallets`);
    }
    ```
  </Tab>

  <Tab title="Smart Transactions">
    Sử dụng Smart Transactions để cải thiện độ tin cậy và khả năng tối ưu hóa:

    ```typescript theme={"system"}
    // Get individual instructions
    const { instructions } = await helius.rpc.getStakeInstructions(
      payer.publicKey,
      2.5
    );

    // Send with Smart Transaction features:
    // - Automatic priority fee optimization
    // - Retry logic with backoff
    // - Better error handling
    const signature = await helius.rpc.sendSmartTransaction(
      instructions,
      [payer],
      {
        skipPreflight: false,
        maxRetries: 3
      }
    );

    console.log(`Smart transaction sent: ${signature}`);
    ```
  </Tab>
</Tabs>

## Lưu ý quan trọng

<Warning>
  **Thời gian epoch**: Các epoch của Solana kéo dài khoảng 2 ngày. Stake được kích hoạt khi epoch tiếp theo bắt đầu và việc hủy kích hoạt có hiệu lực khi epoch hiện tại kết thúc.
</Warning>

<Note>
  **Lưu ý về phí thuê**: Tài khoản stake cần khoản dự trữ được miễn phí thuê (\~0.00228 SOL). Rút toàn bộ số dư sẽ đóng tài khoản.
</Note>

<Tip>
  **Ví phần cứng**: Người dùng sẽ thấy hai lời nhắc ký — một cho tài khoản stake (được ký trước) và một cho bên trả phí. Hãy thiết kế UX cho phù hợp.
</Tip>

## Tham chiếu nhanh

Cần xem lại nhanh? Dưới đây là các phương thức thiết yếu:

```typescript theme={"system"}
// Stake SOL
await helius.rpc.createStakeTransaction(owner, amountInSol);

// Check your stakes  
await helius.rpc.getHeliusStakeAccounts(ownerAddress);

// Start unstaking
await helius.rpc.createUnstakeTransaction(owner, stakeAccount);

// Check withdrawable amount
await helius.rpc.getWithdrawableAmount(stakeAccount, includeRent);

// Withdraw SOL
helius.rpc.getWithdrawInstruction(owner, stakeAccount, destination, amount);
```

## Bước tiếp theo

<CardGroup cols={2}>
  <Card title="Helius SDK Documentation" icon="code" href="https://github.com/helius-labs/helius-sdk">
    Tài liệu tham chiếu SDK đầy đủ với tất cả phương thức hiện có
  </Card>

  <Card title="Smart Transactions" icon="bolt" href="/docs/vi/sending-transactions/optimizing-transactions">
    Tối ưu hóa giao dịch bằng phí ưu tiên và logic thử lại
  </Card>

  <Card title="Join Discord" icon="discord" href="https://discord.com/invite/6GXdee3gBj">
    Nhận trợ giúp từ cộng đồng nhà phát triển của chúng tôi
  </Card>

  <Card title="Validator Dashboard" icon="chart-bar" href="https://www.validators.app/validators/EKgWgpJY5BtX7TeJfhKbqcJT7gzLKFFtj7cjX1XY6CxA">
    Theo dõi hiệu suất và phần thưởng của trình xác thực Helius
  </Card>
</CardGroup>
