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

# Quick Start

> Quick start guide for Loyal's Private Transactions SDK

<img className="block dark:hidden" src="https://mintcdn.com/loyal/DWVryRcChq6727Ic/resources/private-txn/quick-start-light.png?fit=max&auto=format&n=DWVryRcChq6727Ic&q=85&s=dce83db67ab0f76c55de743c81fee1ef" width="1500" height="600" data-path="resources/private-txn/quick-start-light.png" />

<img className="hidden dark:block" src="https://mintcdn.com/loyal/DWVryRcChq6727Ic/resources/private-txn/quick-start-dark.png?fit=max&auto=format&n=DWVryRcChq6727Ic&q=85&s=ce541ff80854c385a78adb3472779de8" width="1500" height="600" data-path="resources/private-txn/quick-start-dark.png" />

## Installation

```bash theme={null}
bun add @loyal-labs/private-transactions
# or
npm install @loyal-labs/private-transactions
```

### Peer Dependencies

```bash theme={null}
bun add @coral-xyz/anchor @solana/web3.js @solana/spl-token @magicblock-labs/ephemeral-rollups-sdk
```

## Create a Client

`fromConfig(...)` creates a client with connections to both base Solana and the MagicBlock PER endpoint. It handles TEE integrity verification and PER auth token acquisition automatically.

```typescript theme={null}
import { Keypair, PublicKey } from "@solana/web3.js";
import {
  ER_VALIDATOR,
  LoyalPrivateTransactionsClient,
  MAGIC_CONTEXT_ID,
  MAGIC_PROGRAM_ID,
} from "@loyal-labs/private-transactions";

const signer = Keypair.fromSecretKey(Uint8Array.from([...secretBytes]));

const client = await LoyalPrivateTransactionsClient.fromConfig({
  signer,
  baseRpcEndpoint: "https://api.devnet.solana.com",
  // Mainnet: https://mainnet-tee.magicblock.app
  // Devnet: https://devnet-tee.magicblock.app
  ephemeralRpcEndpoint: "https://mainnet-tee.magicblock.app",
  ephemeralWsEndpoint: "wss://mainnet-tee.magicblock.app",
  commitment: "confirmed",
});

const tokenMint = new PublicKey("<token-mint>");
const user = signer.publicKey;
```

## Shield: Move Tokens into Private Deposit

Shield moves tokens from your wallet into the private layer (PER).

### 1. Initialize and fund the deposit (base layer)

```typescript theme={null}
// Create deposit account (no-op if already exists)
await client.initializeDeposit({ tokenMint, user, payer: user });

// Transfer tokens from your ATA into the program vault
await client.modifyBalance({
  tokenMint,
  user,
  payer: user,
  amount: 1_000_000,
  increase: true,
});
```

### 2. Create permission and delegate to PER

```typescript theme={null}
// Set up PER access control (idempotent — returns null if already exists)
await client.createPermission({ tokenMint, user, payer: user });

// Delegate deposit to TEE validator — account moves into PER
await client.delegateDeposit({
  tokenMint,
  user,
  payer: user,
  validator: ER_VALIDATOR,
});
```

Your deposit is now private — only you can see it inside PER.

## Private Transfers

Transfer to another user by Telegram username. The destination username deposit must already exist and be delegated.

```typescript theme={null}
await client.transferToUsernameDeposit({
  tokenMint,
  username: "alice_user",
  amount: 100_000,
  user,
  payer: user,
});
```

Or transfer directly to another wallet address:

```typescript theme={null}
await client.transferDeposit({
  tokenMint,
  user,
  destinationUser: new PublicKey("<recipient-wallet>"),
  amount: 100_000,
  payer: user,
});
```

## Claim and Unshield

### Claim from username deposit

The recipient proves Telegram identity via a verified session PDA and claims to their own deposit:

```typescript theme={null}
await client.claimUsernameDepositToDeposit({
  username: "alice_user",
  tokenMint,
  amount: 100_000,
  recipient: new PublicKey("<recipient-wallet>"),
  session: new PublicKey("<telegram-session-pda>"),
});
```

### Unshield: move tokens back to wallet

```typescript theme={null}
// Commit PER state and return deposit to base layer
await client.undelegateDeposit({
  tokenMint,
  user,
  payer: user,
  magicProgram: MAGIC_PROGRAM_ID,
  magicContext: MAGIC_CONTEXT_ID,
});

// Withdraw tokens from vault back to your ATA
await client.modifyBalance({
  tokenMint,
  user,
  payer: user,
  amount: 1_000_000,
  increase: false,
});
```

## Next Steps

* Read [How It Works](/sdk/private-transactions/how-it-works) for the full base-layer + PER lifecycle and smart contract details.
* See [API Reference](/sdk/private-transactions/reference) for all method signatures and types.
* Use [CLI](/sdk/private-transactions/cli) to execute the same flow via `bun scripts/telegram-private-transfer.ts`.
