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

# Ví riêng tư

> Thêm khả năng hỗ trợ quyền riêng tư vào ví Solana hiện có cho Ring bảo mật không cần cấp quyền. Tạo ví riêng tư, nhận và gửi các giao dịch riêng tư.

Ví riêng tư bao gồm một cặp khóa Solana để ký, một khóa nullifier và một khóa xem để mã hóa – các khóa này cùng nhau tạo thành cặp khóa được bảo vệ.
Hệ thống quản lý khóa của bạn lưu giữ cặp khóa được bảo vệ.
Mã ví sử dụng Giao diện Quyền riêng tư và SDK để tạo giao dịch riêng tư.

<img src="https://mintcdn.com/helius/nNv9k5eJvwuxAzBn/images/privacy/stack.svg?fit=max&auto=format&n=nNv9k5eJvwuxAzBn&q=85&s=0e4087582b1d03c3d29d6a21f33149bb" alt="Key management and the Privacy SDK connect through the Privacy Interface. The Privacy SDK calls the Privacy API. The Privacy API submits the transaction to Solana." width="2156" height="270" data-path="images/privacy/stack.svg" />

Tích hợp này cho phép người dùng:

1. Tạo ví riêng tư tự lưu ký
2. Nhận chuyển khoản riêng tư bằng địa chỉ Solana
3. Nạp token vào số dư riêng tư
4. Gửi riêng tư đến một địa chỉ Solana
5. Rút về bất kỳ địa chỉ Solana nào
6. Giải mã cục bộ số dư riêng tư và lịch sử giao dịch

Tích hợp này bao gồm:

1. [**Cặp khóa được bảo vệ**](#tích-hợp-cặp-khóa-được-bảo-vệ) – trong hệ thống quản lý khóa để mã hóa
2. [**Giao diện Quyền riêng tư và SDK**](#tích-hợp-giao-diện-quyền-riêng-tư-và-sdk) – để tạo giao dịch riêng tư
3. [**Luồng người dùng**](#tích-hợp-luồng-người-dùng) – để tích hợp vào ví của bạn

## Ngữ cảnh cho AI của bạn

<Prompt description="Add a Private Wallet to an existing Solana wallet" actions={["copy", "cursor"]}>
  {`---
    description: Thêm Ví riêng tư vào ví Solana hiện có
    allowed-tools: Bash, Read, Write, Edit, Glob, Grep, WebFetch, AskUserQuestion, Task, TaskCreate, TaskGet, TaskList, TaskUpdate, TaskOutput, mcp__deepwiki, mcp__helius-docs
    ---

    ## Thêm Ví riêng tư vào ví Solana hiện có

    Cách diễn đạt:
    - Nêu ý chính. Sau đó giải thích ngắn gọn, đầy đủ bằng một câu hoàn chỉnh.
    - Không dùng từ thừa.

    Trang hiện tại: https://www.helius.dev/docs/privacy/integration/wallet.md

    Triển khai theo trình tự này. Không bỏ qua hoặc sắp xếp lại:
    1. Dẫn xuất cặp khóa được bảo vệ
    2. Privacy Interface trong quản lý khóa
    3. Luồng người dùng.

    Bối cảnh:
    - Mục lục tài liệu: https://www.helius.dev/docs/privacy.md
    - Đặc tả: https://github.com/helius-labs/zolana/blob/main/docs/spec.md
    - MCP: https://www.helius.dev/docs/privacy/ai-tools.md
    - Các gói: @heliuslabs/zolana, @solana/kit · zolana-client, zolana-interface, zolana-program, zolana-keypair, zolana-transaction
    - Ví dụ: https://github.com/helius-labs/zolana-examples/tree/main/typescript-client · https://github.com/helius-labs/zolana-examples/tree/main/rust-client

    Các API chính: ShieldedKeypairLike, ViewingKeyLike, ShieldedKeypairTrait, ViewingKeyTrait, createZolanaClient. API luồng: các trang được liên kết từ mục lục tài liệu.

    ### 1. Lập chỉ mục dự án
    - Dùng Grep để tìm \`ShieldedKeypairLike|ViewingKeyLike|createZolanaClient|@heliuslabs/zolana|zolana-keypair|TSPP/derive\` trong src/
    - Dùng Glob với \`**/*.{ts,tsx,js,rs}\` · đọc package.json / Cargo.toml
    - Xác định: cơ chế quản lý khóa Solana hiện có, seed hay phần cứng/MPC, chỉ mục tài khoản, luồng gửi, giao diện số dư/lịch sử
    - Giao cho tác nhân phụ Task nếu có nhiều gói

    ### 2. Đọc tài liệu tham khảo
    - Dùng WebFetch để tải trang hiện tại — cả hai ngôn ngữ giao diện, cả hai tab dẫn xuất
    - Dùng WebFetch để tải mục lục tài liệu — theo các trang dành cho trình tự ở trên. Chỉ thêm luồng nạp/rút nếu được chọn ở bước 3
    - Dùng WebFetch để tải đặc tả khi hành vi giao thức chưa rõ ràng (registry, giao dịch chi tiêu, mã hóa)
    - Dùng TaskCreate để tạo một việc cần làm cho mỗi giai đoạn bên dưới

    ### 3. Làm rõ mục tiêu
    - AskUserQuestion: Bạn đang sử dụng TypeScript hay Rust?
    - AskUserQuestion: Bạn đang dùng ví dựa trên seed, tạo bài kiểm thử hay dùng ví không dựa trên seed?
    - Ví dựa trên seed → dẫn xuất từ cụm từ seed
    - Bài kiểm thử → dẫn xuất từ một thông điệp cố định
    - Ví không dựa trên seed → dẫn xuất từ một thông điệp cố định
    - AskUserQuestion: Bạn có muốn hỗ trợ luồng nạp/rút không?
    - AskUserQuestion: Localnet hay devnet?
    - Tóm tắt. Chờ xác nhận trước khi lập kế hoạch

    ### 4. Lập kế hoạch
    - Không chỉnh sửa các tệp không liên quan. Không thêm mã chết.
    - Giữ nguyên mã hiện có theo từng byte. Không tự tạo API, tệp hoặc hàm trợ giúp không xuất hiện trên các trang đã tải hoặc trong kho mã.
    - Mọi đường dẫn, ký hiệu và số dòng được đề cập phải đến từ bước 1 hoặc 2. Nếu chưa đọc, không được viết.
    - Tạo cây ASCII cho các tệp cần thêm hoặc thay đổi. Mỗi tệp một dòng: đường dẫn, sau đó là chức năng của tệp đó.
    - Tuân theo trình tự. Nếu chưa rõ, dùng AskUserQuestion. Trình bày kế hoạch. Chờ phê duyệt.

    ### 5. Triển khai
    - TS: Chạy Bash \`pnpm add @heliuslabs/zolana @solana/kit\` nếu còn thiếu
    - Rust: thêm các crate từ trang SDK được liên kết trong mục lục tài liệu
    - Làm theo kế hoạch đã được phê duyệt. Dùng Write/Edit. Không thay thế cặp khóa Solana
    - Dùng TaskUpdate cho từng bước

    ### 6. Xác minh
    - Đã triển khai mọi phương thức giao diện cho ngôn ngữ được chọn
    - Không có thông tin bí mật trong nhật ký hoặc payload mạng
    - TS: Chạy Bash \`tsc --noEmit\` + các bài kiểm thử hiện có
    - Rust: Chạy Bash \`cargo check\` + \`cargo test\` nếu có bài kiểm thử
    - Dùng TaskUpdate để đánh dấu hoàn tất

    ### Công cụ
    - mcp__helius-docs dành cho các trang tài liệu
    - mcp__deepwiki__ask_question("helius-labs/zolana", "<q>")
    - WebFetch \`https://www.helius.dev/docs/<path>.md\`
    - Tác nhân phụ Task để chạy Grep/Read/WebFetch song song
    - TaskList để xem công việc còn lại

    Các nguyên tắc bất biến:
    - Ví lưu giữ cặp khóa được bảo vệ. Không bao giờ gửi dữ liệu khóa đến Privacy API.
    - Triển khai mọi phương thức trên giao diện của ngôn ngữ đã chọn. Không sao chép các phương thức chỉ dành cho Rust (\`sign_hash\`, \`nullifier_key\`) sang TypeScript.
    - Các thao tác với khóa xem được thực hiện cục bộ và đồng bộ. Bên lưu ký chỉ hỗ trợ ký là không hợp lệ.
    - Chỉ sử dụng các API từ trang hiện tại, mục lục tài liệu và các trang luồng theo đúng trình tự. Nếu API không có ở đó, hãy dừng lại và dùng AskUserQuestion.
    - Không ghi mnemonic, nullifier, khóa xem hoặc chữ ký \`TSPP/derive/v1\` vào nhật ký.
    - Ngôn ngữ là TypeScript hoặc Rust, không phải cả hai.
    - Tài sản gồm SOL, SPL và Token-2022.
    - Mỗi khóa công khai Solana của người dùng đều có thể thêm một Ví riêng tư. Một địa chỉ Solana ánh xạ tới một Địa chỉ được bảo vệ.
    - Khi người nhận của giao dịch chuyển tiền riêng tư không có Ví riêng tư, Privacy API có thể phân giải giao dịch thành một lần rút từ riêng tư sang công khai.
    Nên yêu cầu người dùng cung cấp một chữ ký riêng trong giao diện để đảm bảo họ không vô tình rút tiền về số dư công khai.`}
</Prompt>

<Accordion title="View prompt">
  ```text theme={"system"}
  description: Add a Private Wallet to an existing Solana wallet
  allowed-tools: Bash, Read, Write, Edit, Glob, Grep, WebFetch, AskUserQuestion, Task, TaskCreate, TaskGet, TaskList, TaskUpdate, TaskOutput, mcp__deepwiki, mcp__helius-docs
  ---

  ## Add a Private Wallet to an existing Solana wallet

  Voice:
  - Point. Then a short, self-contained explanation in a real sentence.
  - No fill words.

  Current Page: https://www.helius.dev/docs/privacy/integration/wallet.md

  Implement in this sequence. Do not skip or rearrange:
  1. Shielded keypair derivation
  2. Privacy Interface in key management
  3. User flows.

  Context:
  - Docs index: https://www.helius.dev/docs/privacy.md
  - Spec: https://github.com/helius-labs/zolana/blob/main/docs/spec.md
  - MCP: https://www.helius.dev/docs/privacy/ai-tools.md
  - Packages: @heliuslabs/zolana, @solana/kit · zolana-client, zolana-interface, zolana-program, zolana-keypair, zolana-transaction
  - Examples: https://github.com/helius-labs/zolana-examples/tree/main/typescript-client · https://github.com/helius-labs/zolana-examples/tree/main/rust-client

  Key APIs: ShieldedKeypairLike, ViewingKeyLike, ShieldedKeypairTrait, ViewingKeyTrait, createZolanaClient. Flow APIs: the pages linked from the docs index.

  ### 1. Index project
  - Grep \`ShieldedKeypairLike|ViewingKeyLike|createZolanaClient|@heliuslabs/zolana|zolana-keypair|TSPP/derive\` across src/
  - Glob \`**/*.{ts,tsx,js,rs}\` · read package.json / Cargo.toml
  - Identify: existing Solana key management, seed vs hardware/MPC, account index, send path, balance/history UI
  - Task subagent if multiple packages

  ### 2. Read references
  - WebFetch the current page — both interface languages, both derivation tabs
  - WebFetch the docs index — follow the pages for the sequence above. Add on-/off-ramp only if selected in step 3
  - WebFetch the spec when protocol behavior is ambiguous (registry, spends, encryption)
  - TaskCreate one todo per phase below

  ### 3. Clarify intention
  - AskUserQuestion: Are you using TypeScript or Rust?
  - AskUserQuestion: Are you a seed-based wallet, creating tests, or a non-seed-based wallet?
    - Seed-based wallet → derive from the seed phrase
    - Tests → derive from a fixed message
    - Non-seed-based wallet → derive from a fixed message
  - AskUserQuestion: Do you want on-/off-ramp?
  - AskUserQuestion: Localnet or devnet?
  - Summarize. Wait for confirmation before planning

  ### 4. Create plan
  - Do not edit unrelated files. Do not add dead code.
  - Take existing code byte for byte. Do not invent APIs, files, or helpers that are not on the fetched pages or in the repo.
  - Every claimed path, symbol, and line number comes from step 1 or 2. If it was not read, do not write it.
  - ASCII tree of files to add or change. One line per file: path, then what that file does.
  - Follow the sequence. If unclear, AskUserQuestion. Present the plan. Wait for approval.

  ### 5. Implement
  - TS: Bash \`pnpm add @heliuslabs/zolana @solana/kit\` if missing
  - Rust: add the crates from the SDK page linked from the docs index
  - Follow the approved plan. Write/Edit. Do not replace the Solana keypair
  - TaskUpdate each step

  ### 6. Verify
  - Every interface method for the chosen language is implemented
  - No secrets in logs or network payloads
  - TS: Bash \`tsc --noEmit\` + existing tests
  - Rust: Bash \`cargo check\` + \`cargo test\` if tests exist
  - TaskUpdate complete

  ### Tools
  - mcp__helius-docs for docs pages
  - mcp__deepwiki__ask_question("helius-labs/zolana", "<q>")
  - WebFetch \`https://www.helius.dev/docs/<path>.md\`
  - Task subagent for parallel Grep/Read/WebFetch
  - TaskList for remaining work

  Invariants:
  - Wallet holds the shielded keypair. Never send key material to the Privacy API.
  - Implement every method on the chosen language's interface. Do not copy Rust-only methods (\`sign_hash\`, \`nullifier_key\`) onto TypeScript.
  - Viewing-key operations are local and synchronous. A sign-only custodian is invalid.
  - Use only APIs from the current page, the docs index, and the flow pages in the sequence. If an API is not there, stop and AskUserQuestion.
  - Do not log mnemonic, nullifier, viewing key, or the \`TSPP/derive/v1\` signature.
  - Language is TypeScript or Rust, not both.
  - Assets are SOL, SPL, and Token-2022.
  - Every Solana public key of the user can add a Private Wallet. One Solana address maps to one Shielded Address.
  - When the recipient of a private transfer does not have a Private Wallet, the Privacy API can resolve the transfer to a private-to-public withdrawal.
  We recommend requesting a separate user signature in the UI to ensure the user does not withdraw to a public balance by accident.
  ```
</Accordion>

<Steps>
  <Step>
    ## Tích hợp cặp khóa được bảo vệ

    Việc tích hợp ví riêng tư sẽ thêm một cặp khóa được bảo vệ vào hệ thống quản lý khóa của bạn.
    Cặp khóa được bảo vệ dùng để ký, mã hóa và giải mã giao dịch.

    Cặp khóa được bảo vệ là một gói gồm khóa ký, khóa nullifier và khóa xem.

    * **Khóa ký:** Cặp khóa Solana Ed25519 của ví dùng để ký giao dịch.
    * **Khóa xem:** Một cặp khóa P-256 dùng để mã hóa và giải mã giao dịch.
    * **Khóa nullifier:** <Tooltip tip="A nullifier ensures a private balance cannot be spent twice. A private balance is the sum of all UTXOs (unspent transaction outputs) owned by an address. Each transaction spends (nullifies) input UTXOs and creates new outputs.">Khóa dùng để tạo các nullifier.</Tooltip>

    Ví có thể tạo cặp khóa được bảo vệ theo hai cách:

    1. Đối với ví dựa trên seed, chọn **Tạo từ cụm từ seed**.
    2. Đối với ví không dựa trên seed, chọn **Tạo từ chữ ký EdDSA**.

    <Tabs>
      <Tab title="Derive from seed phrase" id="derive-from-seed-phrase">
        Ví dựa trên seed tạo cặp khóa được bảo vệ từ một cụm từ ghi nhớ BIP-39 và một chỉ mục tài khoản (`0`, `1`, …).

        Mỗi chỉ mục tài khoản ánh xạ một cặp khóa Solana với một cặp khóa được bảo vệ.
        Bạn có thể khôi phục cặp khóa được bảo vệ theo cùng cách khôi phục cặp khóa Solana.

        Ví dụ:

        * Tài khoản 0: Cặp khóa Solana 0 và cặp khóa được bảo vệ 0
        * Tài khoản 1: Cặp khóa Solana 1 và cặp khóa được bảo vệ 1

        | Khóa      | Đường dẫn dẫn xuất                 | Cơ chế                    |
        | --------- | ---------------------------------- | ------------------------- |
        | Ký        | `m/44'/501'/account'/0'`           | SLIP-0010 Ed25519         |
        | Nullifier | `m/44'/1392955331'/account'/1'/0'` | SLIP-0010 Ed25519\[1..32] |
        | Xem       | `m/44'/1392955331'/account'/2'/0'` | SLIP-0010 NIST P-256      |

        Khóa ký được bảo vệ là khóa Solana Ed25519 của tài khoản đó.
        Khóa nullifier và khóa xem là các khóa bổ sung được tạo từ cùng một seed.

        <Info>
          Ví dụ triển khai: [Ví dụ TypeScript](https://github.com/helius-labs/zolana/blob/cad0664e374f6a0e5c532169c5895203e366eb56/sdk-libs/ts/test/seed-based-keypair.test.ts#L60) · [Ví dụ Rust](https://github.com/helius-labs/zolana/blob/cad0664e374f6a0e5c532169c5895203e366eb56/sdk-libs/keypair/tests/seed_based_keypair.rs#L111)
        </Info>
      </Tab>

      <Tab title="Derive from EdDSA signature" id="derive-from-signature">
        Tạo cặp khóa được bảo vệ từ chữ ký EdDSA trên một thông điệp cố định.
        Chữ ký EdDSA có tính xác định, vì vậy chữ ký của cùng một cặp khóa Solana cho cùng một thông điệp luôn tạo ra cùng một cặp khóa được bảo vệ.
        Chúng tôi dùng chữ ký làm seed để tạo cặp khóa được bảo vệ.

        Payload của thông điệp cố định là `"TSPP/derive/v1"`, được mã hóa dưới dạng thông điệp ngoài chuỗi Solana v0.

        Khóa ký được bảo vệ là khóa Solana EdDSA của ví.
        Khóa nullifier và khóa xem là các khóa bổ sung được tạo từ chữ ký.

        <Warning>
          Chữ ký là seed dẫn xuất.
          Bất kỳ ai sở hữu chữ ký đều có thể tạo khóa nullifier và khóa xem, đồng thời giải mã giao dịch của người dùng.
          Từ chối mọi yêu cầu ký thông điệp `"TSPP/derive/v1"` từ bên thứ ba.
        </Warning>

        Mã giả để tạo cặp khóa được bảo vệ từ chữ ký Solana:

        ```jsx theme={"system"}
        function deriveShieldedKeypair(solanaKeypair):
              solanaPubkey = solanaKeypair.publicKeyBytes() // 32 bytes
        	
              payload = UTF8("TSPP/derive/v1")

              // Solana off-chain message v0 envelope
              derivationMessage =
                  bytes("\xffsolana offchain")            // 16 bytes
                  || u8(0)                                // version
                  || SHA256(payload)                      // application domain
                  || u8(0)                                // restricted ASCII format
                  || u8(1)                                // one signer
                  || solanaPubkey
                  || u16LE(length(payload))
                  || payload

              // Ed25519 signatures are deterministic, so the same wallet produces
              // the same 64-byte seed every time.
              derivationSeed = ED25519_SIGN(
                  solanaKeypair.secretKey,
                  derivationMessage
              )

              // HKDF-Extract with no salt
              prk = HKDF_SHA256_EXTRACT(
                  salt = empty,
                  ikm  = derivationSeed
              )

              nullifierSecret = HKDF_SHA256_EXPAND(
                  prk,
                  info   = UTF8("TSPP/nf_key/ed25519/v1"),
                  length = 31
              )

              viewingKeyMaterial = HKDF_SHA256_EXPAND(
                  prk,
                  info   = UTF8("TSPP/view_key/ed25519/v1"),
                  length = 48
              )

              // RFC hash-to-field reduction into a non-zero P-256 scalar
              viewingSecret = P256_SCALAR_FROM_OKM(viewingKeyMaterial)

              return ShieldedKeypair {
                  signingKey:    solanaKeypair,
                  nullifierKey:  NullifierKey(nullifierSecret),
                  viewingKey:    P256Keypair(viewingSecret)
        }
        ```

        <Info>
          Ví dụ triển khai: [TypeScript](https://github.com/helius-labs/zolana/blob/cad0664e374f6a0e5c532169c5895203e366eb56/sdk-libs/ts/src/keypair/shielded.ts#L201) · [Rust](https://github.com/helius-labs/zolana/blob/cad0664e374f6a0e5c532169c5895203e366eb56/sdk-libs/keypair/src/shielded.rs#L126)
        </Info>
      </Tab>
    </Tabs>
  </Step>

  <Step>
    ## Tích hợp Giao diện Quyền riêng tư và SDK

    Giao diện Quyền riêng tư cho phép mã của bạn sử dụng SDK Quyền riêng tư để tạo giao dịch riêng tư mà không cần truy cập trực tiếp vào dữ liệu khóa.
    Hệ thống quản lý khóa của bạn triển khai Giao diện Quyền riêng tư theo hai phần.

    1. Giao diện ký để tạo giao dịch bằng SDK Quyền riêng tư. Xem mã nguồn: [TypeScript](https://github.com/helius-labs/zolana/blob/236e6cd6cee4d07e567b316210e018f31dfa4d90/sdk-libs/ts/src/keypair/shielded.ts#L132)/ [Rust](https://github.com/helius-labs/zolana/blob/236e6cd6cee4d07e567b316210e018f31dfa4d90/sdk-libs/keypair/src/traits/shielded_keypair.rs)
    2. Giao diện mã hóa và giải mã. Xem mã nguồn: [TypeScript](https://github.com/helius-labs/zolana/blob/236e6cd6cee4d07e567b316210e018f31dfa4d90/sdk-libs/ts/src/keypair/shielded.ts#L154)/ [Rust](https://github.com/helius-labs/zolana/blob/236e6cd6cee4d07e567b316210e018f31dfa4d90/sdk-libs/keypair/src/traits/view_key.rs)

    <Info>
      Giao diện Quyền riêng tư không có trạng thái, do đó không lưu trữ số dư hoặc lịch sử giao dịch.
      Để cải thiện hiệu suất, chúng tôi khuyên bạn nên lưu số dư và lịch sử giao dịch của người dùng vào bộ nhớ đệm cục bộ.
    </Info>

    ### Về việc tạo bằng chứng

    Việc tạo bằng chứng không kiến thức yêu cầu dữ liệu đầu vào dạng văn bản thuần của toàn bộ dữ liệu giao dịch người dùng và các khóa nullifier.

    Hiện tại, tính năng tạo bằng chứng trên máy chủ được cung cấp qua URL RPC Helius tiêu chuẩn.

    Tính năng tạo bằng chứng cục bộ sắp ra mắt.
    Tính năng tạo bằng chứng trên máy chủ được mã hóa đầu cuối bằng AWS Nitro dự kiến sẽ có trước khi ra mắt mainnet.
  </Step>

  <Step>
    ## Tích hợp luồng người dùng

    ### Tạo ví riêng tư

    Ví riêng tư được tạo qua hai bước:

    1. Tạo cặp khóa được bảo vệ
    2. Đăng ký địa chỉ Solana trong sổ đăng ký trên chuỗi.

    Việc tạo ví riêng tư không yêu cầu nạp tiền vào số dư riêng tư.

    Sổ đăng ký liên kết khóa công khai ký với các khóa công khai nullifier và xem. Các khóa công khai này cùng nhau tạo thành địa chỉ được bảo vệ.

    ```mermaid theme={"system"}
    %%{init: {
      'theme': 'base',
      'themeVariables': {
        'lineColor':           '#FF6B35',
        'primaryTextColor':    '#737373',
        'primaryBorderColor':  '#9CA3AF',
        'actorBkg':            '#FFFFFF',
        'actorBorder':         '#9CA3AF',
        'actorTextColor':      '#737373',
        'signalColor':         '#FF6B35',
        'signalTextColor':     '#737373',
        'labelBoxBkgColor':    '#FF6B351F',
        'labelBoxBorderColor': '#FF6B35',
        'noteBkgColor':        '#F5F5F5',
        'noteTextColor':       '#737373',
        'noteBorderColor':     '#9CA3AF'
      }
    }}%%
    sequenceDiagram
        participant User
        participant Privacy SDK
        participant Solana

        User->>Privacy SDK: Create Private Wallet
        Privacy SDK->>Solana: Register Solana address

    ```

    <Info>
      Mỗi bản ghi trong sổ đăng ký là một PDA thuộc sở hữu của <Tooltip tip="regyS5rkAcw2YzDJCmTwCTHs2s246FXxbmuRZ42u2PD">[chương trình sổ đăng ký](https://orbmarkets.io/address/regyS5rkAcw2YzDJCmTwCTHs2s246FXxbmuRZ42u2PD)</Tooltip>. Bất kỳ ai cũng có thể tra cứu để xem một địa chỉ Solana có thể nhận chuyển khoản riêng tư hay không.
    </Info>

    <Tabs>
      <Tab title="TypeScript Client">
        ```typescript theme={"system"}
        import { buildRegistrationTransaction } from "@heliuslabs/zolana";
        import { isWalletRegistered } from "@heliuslabs/zolana/wallet";

        const registration = await buildRegistrationTransaction({
          client,
          owner: signer.address,
          address,
        });
        if (registration !== undefined) {
          await sendTransaction(registration);
        }

        const registered = await isWalletRegistered({
          rpc: client,
          owner: signer.address,
        });
        ```

        * `owner` là địa chỉ Solana của người dùng, được dùng để tạo PDA của sổ đăng ký.
        * `address` là địa chỉ được bảo vệ của người dùng.
        * `buildRegistrationTransaction` trả về một giao dịch đăng ký hoặc cập nhật khóa đã biên dịch. Hàm trả về `undefined` nếu ví đã được đăng ký.
        * `sendTransaction` ký và gửi giao dịch.
        * `isWalletRegistered` đọc PDA của sổ đăng ký để kiểm tra trạng thái đăng ký.
      </Tab>

      <Tab title="Rust Client">
        ```rust theme={"system"}
        use solana_signer::Signer;
        use zolana_client::{sign_transaction, Rpc};
        use zolana_wallet::{
            build_registration_transaction_sync,
            is_wallet_registered_sync,
        };

        if let Some(registration) = build_registration_transaction_sync(
            &client,
            owner.pubkey(),
            &owner.shielded_address()?,
            None,
            None,
        )? {
            let registration = sign_transaction(registration, &[&owner])?;
            client.process_transaction(registration)?;
        }

        assert!(is_wallet_registered_sync(&client, owner.pubkey())?);
        ```

        * `owner` là `ShieldedKeypair` của người dùng. Khóa công khai Solana của đối tượng này xác định bản ghi trong sổ đăng ký và chữ ký của đối tượng này cấp quyền đăng ký.
        * `owner.shielded_address()` trả về địa chỉ được bảo vệ của người dùng.
        * `build_registration_transaction_sync` trả về thông điệp đăng ký hoặc cập nhật khóa chưa ký. Hàm trả về `None` nếu ví đã được đăng ký.
        * `None` đầu tiên bỏ qua bằng chứng liên kết khóa đối với ví Ed25519. `None` cuối cùng sử dụng chủ sở hữu làm bên thanh toán. Chủ sở hữu vẫn phải ký.
        * `sign_transaction` ký thông điệp. `process_transaction` gửi và xác nhận giao dịch.
        * `is_wallet_registered_sync` đọc PDA của sổ đăng ký để kiểm tra trạng thái đăng ký.
      </Tab>
    </Tabs>

    <Info>
      Ví dụ đăng ký đầy đủ: [TypeScript](https://github.com/helius-labs/zolana-examples/blob/7775438e0a290a4c28dccf919719bd640c3ec5e3/typescript-client/examples/register_private_wallet.ts) · [Rust](https://github.com/helius-labs/zolana-examples/blob/7775438e0a290a4c28dccf919719bd640c3ec5e3/rust-client/examples/register_private_wallet.rs)
    </Info>

    ### Đồng bộ số dư riêng tư và lịch sử giao dịch

    Quá trình đồng bộ số dư truy xuất trạng thái đã mã hóa từ RPC và giải mã trạng thái đó trong ví.

    RPC không thực hiện giải mã. Chỉ chủ sở hữu mới có thể giải mã số dư riêng tư bằng khóa xem.

    <Info>
      Ví nên giải mã và cập nhật số dư trước các giao dịch riêng tư cũng như tại mọi thời điểm chạy quá trình backfill: khi mở khóa ví, mở ví riêng tư, tiếp tục ứng dụng, kết nối lại mạng, có khoảng trống trong luồng hoặc khôi phục ví.
    </Info>

    <CardGroup cols={2}>
      <Card title="Read a Private Balance" icon="wallet" href="/docs/vi/privacy/guides/read-balance" horizontal />

      <Card title="Read Private Transaction History" icon="clock-rotate-left" href="/docs/vi/privacy/guides/read-history" horizontal />
    </CardGroup>

    ### Nạp vào số dư riêng tư

    Người dùng có thể nạp vào số dư riêng tư theo hai cách:

    1. Chuyển trực tiếp từ số dư tiền pháp định sang số dư tiền mã hóa riêng tư
    2. Nạp từ tài khoản SPL công khai vào số dư riêng tư

    Chuyển tiền trực tiếp và nạp tiền có các bảo đảm quyền riêng tư khác nhau.
    Để có quyền riêng tư tốt hơn, chúng tôi khuyên bạn nên dùng hình thức chuyển tiền trực tiếp thay vì nạp tiền.

    | Trường       | Chuyển trực tiếp từ tiền pháp định | Nạp từ SPL |
    | ------------ | ---------------------------------- | ---------- |
    | Tài sản      | Riêng tư                           | Công khai  |
    | Số tiền      | Riêng tư                           | Công khai  |
    | Nguồn        | Không ở trên chuỗi                 | Công khai  |
    | Địa chỉ đích | Công khai                          | Công khai  |

    <CardGroup cols={2}>
      <Card title="On-/Off-Ramp" icon="circle-dollar-to-slot" href="/docs/vi/privacy/integration/on-off-ramp">
        Chuyển trực tiếp tiền pháp định vào và ra khỏi số dư riêng tư.
      </Card>

      <Card title="Deposit" icon="arrow-down-to-bracket" href="/docs/vi/privacy/guides/deposit">
        Nạp từ số dư tiền mã hóa công khai.
      </Card>
    </CardGroup>

    ### Chuyển khoản riêng tư

    Người dùng có thể gửi các khoản chuyển riêng tư đến bất kỳ địa chỉ ví Solana nào.

    Đối với mỗi khoản chuyển riêng tư, SDK Quyền riêng tư tra cứu địa chỉ ví trong sổ đăng ký trên chuỗi để kiểm tra xem người nhận có ví riêng tư hay không.

    SDK Quyền riêng tư có thể chuyển một khoản chuyển riêng tư thành giao dịch rút từ riêng tư sang công khai khi người nhận không có ví riêng tư.

    <Info>
      Chúng tôi khuyên bạn nên gắn nhãn giao dịch trong giao diện người dùng là giao dịch rút tiền để đảm bảo người dùng không vô tình rút về số dư công khai.
    </Info>

    | Trường            | Khả năng hiển thị | Lý do                                                      |
    | ----------------- | ----------------- | ---------------------------------------------------------- |
    | Tài sản           | Riêng tư          | Tài sản được mã hóa trên chuỗi                             |
    | Số tiền           | Riêng tư          | Số tiền được chuyển được mã hóa trên chuỗi                 |
    | Ví riêng tư nguồn | Công khai         | Trong Ring bảo mật, ví riêng tư nguồn hiển thị trên chuỗi. |
    | Người nhận        | Công khai         | Trong Ring bảo mật, người nhận hiển thị trên chuỗi.        |

    <Card title="Private Transfer" icon="arrow-right-arrow-left" href="/docs/vi/privacy/guides/transfer">
      Chuyển riêng tư vào số dư riêng tư.
    </Card>

    ### Rút về số dư công khai

    Có thể sử dụng giao dịch rút tiền theo hai cách:

    1. Là phương án dự phòng cho các khoản chuyển riêng tư đến người nhận không có ví riêng tư, hoặc
    2. Rút trực tiếp về tài khoản token SPL công khai.

    Đối với giao dịch rút tiền, chúng tôi khuyên bạn nên ghi rõ rằng người dùng đang rời khỏi số dư riêng tư, tương tự như khi xuất cụm từ seed hoặc khóa riêng tư.

    | Trường                 | Khả năng hiển thị | Lý do                                                      |
    | ---------------------- | ----------------- | ---------------------------------------------------------- |
    | Tài sản                | Công khai         | Tài sản hiển thị trên chuỗi                                |
    | Số tiền                | Công khai         | Số tiền được rút hiển thị trên chuỗi                       |
    | Ví riêng tư nguồn      | Công khai         | Trong Ring bảo mật, ví riêng tư nguồn hiển thị trên chuỗi. |
    | Ví công khai đích      | Công khai         | Địa chỉ ví đích hiển thị trên chuỗi                        |
    | Số dư công khai đích   | Công khai         | Số dư công khai sau giao dịch hiển thị trên chuỗi          |
    | Số dư riêng tư còn lại | Riêng tư          | Số dư còn lại được mã hóa trên chuỗi                       |

    <Card title="Withdraw" icon="arrow-up-to-bracket" href="/docs/vi/privacy/guides/withdraw">
      Rút về số dư tiền mã hóa công khai.
    </Card>
  </Step>
</Steps>

## Không tìm thấy nội dung bạn đang tìm kiếm?

<Callout type="info">
  Hãy liên hệ với chúng tôi! [Telegram](https://t.me/tilo_light) | [Email](mailto:sales@helius.xyz) | [Liên hệ](https://www.helius.dev/contact)
</Callout>
