# Custody

This page answers the only question that matters in a wallet: **Can Zirodelta take my money?**

The answer is no. The rest of this page explains exactly why, with the trust boundary made explicit.

## Two keys, two purposes

Zidee splits signing authority into two distinct keys with distinct blast radii:

| Key            | Where it lives               | What it can sign                                          | Who controls it   |
| -------------- | ---------------------------- | --------------------------------------------------------- | ----------------- |
| **Master key** | Privy TEE                    | Withdrawals, transfers, swaps, burns, Autopilot approvals | You               |
| **Agent key**  | Zirodelta server (encrypted) | Hyperliquid orders only                                   | Zirodelta backend |

Every operation that *moves your funds* requires the master key. Every operation that *trades on your funds inside Hyperliquid* uses the agent key.

The agent key cannot withdraw, transfer, swap, burn, or otherwise move USDC anywhere off your Hyperliquid account. This isn't a Zirodelta promise, it's a Hyperliquid L1 protocol boundary.

***

## What the master key controls

Your master key is a Privy embedded wallet, actually two of them, one Solana and one EVM. Both keys sit inside Privy's Trusted Execution Environment.

What you can do with the master key:

* **Send / receive / swap / burn ZDLT, USDC-Sol, SOL** on Solana. You sign in the Privy modal on every transfer.
* **Withdraw USDC from Hyperliquid** to Arbitrum. Server prepares the EIP-712 payload, you sign, server submits, no part of the withdrawal is server-signed.
* **Approve / revoke the Autopilot agent** on Hyperliquid (`approveAgent` / unapproveAgent). Trading authorization, and revocation, is yours alone.
* **Export your private key.** Settings → Export Key reveals the raw private key in a Privy modal so you can back it up or move it to another wallet provider.

Privy's recovery model maps back to your Discord OAuth or email. If you lose your phone, you can sign back in from another device and get the same wallet. Privy has been audited, is SOC 2 Type II certified, and is used in production by exchanges, games, and consumer crypto apps.

## What the agent key controls

When you onboard, you sign two Hyperliquid actions:

* `approveAgent`: registers Zirodelta's per-user agent address as authorized to submit orders from your account.
* `approveBuilderFee`: authorizes Zirodelta to collect its small builder fee on perp orders.

Both are EIP-712 messages stored on Hyperliquid L1. Neither moves any funds.

Once approved, the agent key can:

* Place new orders (perp + spot)
* Cancel existing orders
* Close positions
* Schedule cancel-all timers (used to keep stale orders from sitting after worker downtime)

It cannot:

* Withdraw USDC to Arbitrum or any other chain
* Send USDC, ZDLT, SOL, or any other asset to any address
* Transfer between perp and spot wallets in a way that exits Hyperliquid
* Change account settings or approve another agent

This is not a Zirodelta-imposed limit, it's the agent permission scope as defined by Hyperliquid L1. The agent key is materially incapable of moving funds out of your Hyperliquid account.

## Where the agent key actually sits

Zirodelta's backend stores each user's agent private key encrypted with AES-256-GCM, behind a sealed encryption key that is itself unsealed at boot via a host-bound systemd credential. Decrypted form is held only in process memory while signing an order, never written to disk in plaintext, never logged.

If Zirodelta's server were fully compromised, the attacker could:

* Place orders inside the policy gate (capped notional, allowlisted coins, leverage cap)
* Cancel your existing orders
* Drain your *trading* margin into bad fills (the practical maximum harm)

The attacker could *not*:

* Withdraw your USDC
* Touch your ZDLT, SOL, or any non-HL asset
* Move funds anywhere off your Hyperliquid account

This is the strongest non-custodial guarantee available on Hyperliquid today. It's a protocol-level boundary, not a contractual one.

## Bridge delegation

When you deposit USDC on Arbitrum, Zidee's bridge worker auto-forwards it to Hyperliquid. This requires a one-time delegation step in onboarding.

You're not handing over your master key. You're authorizing a Privy-policy-locked signer that can perform exactly one operation: `USDC.transfer(HL_BRIDGE, amount)`. Privy enforces the policy server-side; the signer cannot move USDC to any other address, can't touch any other token, can't sign withdrawals.

If you ever want to revoke the delegation, you can do it from Privy's dashboard or by exporting your key and rotating to a fresh wallet.

## Revocation

You can pull every authorization at any time:

* **Agent / builder fee**: revoke at `app.hyperliquid.xyz → Settings → API`. Immediate, on-chain. Open positions stay open; you'll need to close them manually after revoke.
* **Bridge delegation**: revoke from Privy's dashboard or rotate to a new wallet.
* **Privy session**: log out from Settings or wipe the local storage on the device.

There's no "support ticket" path Zirodelta needs to involve. Authorizations live on protocols and providers you control directly.

## What Zirodelta sees

Read-only access:

* Your Hyperliquid open positions, collateral balance, funding history (via Hyperliquid's public `clearinghouseState` endpoint, same one any caller can hit).
* Your Solana SPL balances for ZDLT, USDC-Sol, SOL (via public RPC).
* Your Arbitrum USDC + ETH balances (via public RPC).

No privileged access to anything. Everything Zidee shows you is a re-render of what your own RPC calls would return.

***

> **See also:** [Overview](/zidee-wallet/overview.md) · [Tiers](/zidee-wallet/tiers.md) · [Getting Started](/zidee-wallet/getting-started.md) · [Autopilot Agent Wallet](/autopilot/agent-wallet.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.zirodelta.com/zidee-wallet/custody.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
