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

# Deposit, withdraw, and convert USDH on HIP-4 wallets

> Deposit USDC, buy and sell USDH, move funds between spot and perps, and withdraw to external addresses using the HIP-4 wallet adapter.

The wallet adapter (`hip4.wallet`) handles all fund management for HIP-4 prediction trading: moving USDC between your perp and spot accounts, buying and selling USDH on the spot market, and withdrawing funds to external addresses. It relies on two distinct signers - one for user-authorized EIP-712 operations, and one for L1 agent-signed spot orders - so you need to configure both before using the full method surface.

## Two signers

The wallet adapter uses two separate signing keys depending on the operation:

**User's wallet** - set via `setSigner`. Required for EIP-712 operations: transfers between spot and perps, withdrawals, and USD sends. The signer must produce a valid EIP-712 signature on the `HyperliquidSignTransaction` domain.

**Agent key** - initialized via `hip4.auth.initAuth`. Required for USDH spot buy/sell, which use L1 agent signing (MessagePack serialization + keccak-256 + EIP-712 on the `Exchange` domain, chain ID 1337). The agent key signs on behalf of the user's wallet but is a separate keypair.

### `setSigner` interface

```typescript theme={null}
interface WalletSigner {
  address: string;
  signTypedData: (domain: unknown, types: unknown, value: unknown) => Promise<string>;
}
```

This interface is compatible with viem's `walletClient.signTypedData` and any other EIP-712-capable signer.

```typescript theme={null}
hip4.wallet.setSigner({
  address: userAddress,
  signTypedData: walletClient.signTypedData.bind(walletClient),
});
```

## Methods

| Method                              | Signing  | Description                                                          |
| ----------------------------------- | -------- | -------------------------------------------------------------------- |
| `setSigner(signer)`                 | -        | Set the user's wallet for EIP-712 operations                         |
| `buyUsdh(amount)`                   | L1 agent | Buy USDH on spot; priced at oracle × 1.1, IOC                        |
| `sellUsdh(amount)`                  | L1 agent | Sell USDH on spot; priced at oracle × 0.9, IOC                       |
| `sellHype(amount)`                  | L1 agent | Sell HYPE on the HYPE/USDC spot market; size floored to 2 decimals   |
| `transferToSpot(amount)`            | EIP-712  | Transfer USDC from perp → spot                                       |
| `transferToPerps(amount)`           | EIP-712  | Transfer USDC from spot → perp                                       |
| `withdraw({ destination, amount })` | EIP-712  | Withdraw USDC to an external address                                 |
| `usdSend({ destination, amount })`  | EIP-712  | Send USDC to another Hyperliquid address                             |
| `agentSetAbstraction(mode)`         | L1 agent | Switch the master account's abstraction mode (`"u"` / `"p"` / `"i"`) |

All amounts are strings representing USDC or USDH quantities with up to 6 decimal places (e.g. `"100"`, `"25.50"`).

## `WalletActionResult`

Every method returns a `Promise<WalletActionResult>`:

```typescript theme={null}
interface WalletActionResult {
  success: boolean;
  error?: string;
  filledSz?: string;   // spot orders only: filled size
  avgPx?: string;      // spot orders only: average fill price
}
```

Check `success` before reading `filledSz` and `avgPx`. These fields are only populated for the spot-order methods (`buyUsdh`, `sellUsdh`, and `sellHype`).

## Deposit flow

To fund a prediction account, transfer USDC from your perp balance to spot, then buy USDH on the spot market.

```typescript theme={null}
// Step 1: Transfer USDC from perp to spot (EIP-712, user's wallet)
const transfer = await hip4.wallet.transferToSpot("100");
if (!transfer.success) {
  throw new Error(`Transfer failed: ${transfer.error}`);
}

// Step 2: Buy USDH on the spot market (L1 agent signing)
const buy = await hip4.wallet.buyUsdh("100");
if (!buy.success) {
  throw new Error(`Buy failed: ${buy.error}`);
}

console.log(`Bought ${buy.filledSz} USDH at avg price ${buy.avgPx}`);
```

## Withdraw flow

To exit a prediction position and withdraw funds, sell USDH back to USDC, move it to your perp account, then withdraw.

```typescript theme={null}
// Step 1: Sell USDH on the spot market (L1 agent signing)
const sell = await hip4.wallet.sellUsdh("50");
if (!sell.success) {
  throw new Error(`Sell failed: ${sell.error}`);
}

// Step 2: Transfer USDC from spot to perp (EIP-712, user's wallet)
const transfer = await hip4.wallet.transferToPerps("50");
if (!transfer.success) {
  throw new Error(`Transfer failed: ${transfer.error}`);
}

// Step 3: Withdraw USDC to an external address (EIP-712, user's wallet)
const withdrawal = await hip4.wallet.withdraw({
  destination: "0xYourExternalWalletAddress",
  amount: "50",
});
if (!withdrawal.success) {
  throw new Error(`Withdrawal failed: ${withdrawal.error}`);
}
```

## `sellHype(amount)`

Sells HYPE on the **HYPE/USDC** spot market (not USDH). Use this to convert HYPE - for example, balance received on Hypercore - back into USDC. Like `buyUsdh`/`sellUsdh`, it is an IOC spot order signed with the L1 agent key.

The `amount` is a HYPE quantity string. HYPE has 2 size decimals on the spot market, so the size is **floored** (`ROUND_DOWN`) to 2 decimal places before submission - never rounded up - so a sell can never exceed your HYPE balance.

```typescript theme={null}
// Sell 1.006 HYPE → floored to 1.00 before submission
const sell = await hip4.wallet.sellHype("1.006");
if (!sell.success) {
  throw new Error(`Sell failed: ${sell.error}`);
}

console.log(`Sold ${sell.filledSz} HYPE at avg price ${sell.avgPx}`);
```

The correct HYPE/USDC spot index is selected automatically from the adapter's `testnet` flag (`107` on mainnet, `1035` on testnet).

## `agentSetAbstraction(mode)`

Switches the master account's abstraction mode using the approved agent key. This is an L1 agent-signed action, so the agent must be initialized first.

```typescript theme={null}
const res = await hip4.wallet.agentSetAbstraction("u");
if (!res.success) {
  throw new Error(`Set abstraction failed: ${res.error}`);
}
```

| Mode  | Meaning                                                       |
| ----- | ------------------------------------------------------------- |
| `"u"` | Unified account - merges spot and perps into a single balance |
| `"p"` | Portfolio margin                                              |
| `"i"` | Disabled (abstraction off)                                    |

<Warning>
  `buyUsdh`, `sellUsdh`, `sellHype`, and `agentSetAbstraction` require the agent to be initialized first. Call `hip4.auth.initAuth(walletAddress, agentSigner)` before invoking any of them, or they will fail with a `"Not authenticated"` error.
</Warning>

<Warning>
  `transferToSpot`, `transferToPerps`, `withdraw`, and `usdSend` require `setSigner` to be called first with the user's actual wallet. These operations use EIP-712 user signing and cannot use the agent key.
</Warning>
