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

# API Reference

> API reference for @loyal-labs/private-transactions

## Package

```typescript theme={null}
import { ... } from "@loyal-labs/private-transactions";
```

## Main Client

### `LoyalPrivateTransactionsClient`

The SDK client wraps both base-layer and PER (Private Ephemeral Rollup) program access. All operations route to the correct layer automatically.

### Factory

```typescript theme={null}
static fromConfig(config: ClientConfig): Promise<LoyalPrivateTransactionsClient>
```

Creates a client with dual connections. Handles TEE RPC integrity verification and PER auth token acquisition automatically.

```typescript theme={null}
interface ClientConfig {
  signer: WalletSigner;
  baseRpcEndpoint: string;
  baseWsEndpoint?: string;
  ephemeralRpcEndpoint: string;
  ephemeralWsEndpoint?: string;
  commitment?: Commitment; // default: "confirmed"
  authToken?: { token: string; expiresAt: number };
}
```

## Core Methods

### Deposit Initialization

#### `initializeDeposit(params): Promise<string>`

Create a deposit account for a user and token mint on the base layer. No-op if the account already exists.

```typescript theme={null}
interface InitializeDepositParams {
  user: PublicKey;
  tokenMint: PublicKey;
  payer: PublicKey;
  rpcOptions?: RpcOptions;
}
```

#### `initializeUsernameDeposit(params): Promise<string>`

Create a username-based deposit account. Validates username (5–32 chars, alphanumeric + underscore).

```typescript theme={null}
interface InitializeUsernameDepositParams {
  username: string;
  tokenMint: PublicKey;
  payer: PublicKey;
  rpcOptions?: RpcOptions;
}
```

### Balance Operations

#### `modifyBalance(params): Promise<ModifyBalanceResult>`

Deposit or withdraw real SPL tokens to/from the program vault. Requires the deposit to be **not delegated**.

* `increase: true` — transfers tokens from user's ATA to vault, increments deposit `amount`
* `increase: false` — transfers tokens from vault to user's ATA, decrements deposit `amount`

```typescript theme={null}
interface ModifyBalanceParams {
  user: PublicKey;
  tokenMint: PublicKey;
  amount: number | bigint;
  increase: boolean;
  payer: PublicKey;
  userTokenAccount: PublicKey;
  rpcOptions?: RpcOptions;
}

interface ModifyBalanceResult {
  signature: string;
  deposit: DepositData;
}
```

### Claim

#### `claimUsernameDepositToDeposit(params): Promise<string>`

Transfer tokens from a username deposit to the recipient's user deposit. Both accounts must be **delegated**. Requires a verified Telegram session matching the username.

```typescript theme={null}
interface ClaimUsernameDepositToDepositParams {
  username: string;
  tokenMint: PublicKey;
  amount: number | bigint;
  recipient: PublicKey;
  session: PublicKey;
  rpcOptions?: RpcOptions;
}
```

### Permission Management

#### `createPermission(params): Promise<string | null>`

Create a PER access control account for a user deposit. Returns `null` if the permission already exists. Deposit must be **not delegated**.

```typescript theme={null}
interface CreatePermissionParams {
  user: PublicKey;
  tokenMint: PublicKey;
  payer: PublicKey;
  rpcOptions?: RpcOptions;
}
```

#### `createUsernamePermission(params): Promise<string | null>`

Create PER access control for a username deposit. Requires a verified Telegram session.

```typescript theme={null}
interface CreateUsernamePermissionParams {
  username: string;
  tokenMint: PublicKey;
  session: PublicKey;
  authority: PublicKey;
  payer: PublicKey;
  rpcOptions?: RpcOptions;
}
```

### Delegation

#### `delegateDeposit(params): Promise<string>`

Delegate a user deposit to the TEE validator for PER execution. Account must be **not already delegated**.

```typescript theme={null}
interface DelegateDepositParams {
  user: PublicKey;
  tokenMint: PublicKey;
  payer: PublicKey;
  validator: PublicKey; // typically ER_VALIDATOR
  rpcOptions?: RpcOptions;
}
```

#### `delegateUsernameDeposit(params): Promise<string>`

Delegate a username deposit to PER.

```typescript theme={null}
interface DelegateUsernameDepositParams {
  username: string;
  tokenMint: PublicKey;
  payer: PublicKey;
  validator: PublicKey;
  rpcOptions?: RpcOptions;
}
```

#### `undelegateDeposit(params): Promise<string>`

Commit PER state and return deposit ownership to the program on the base layer. Account must be **delegated**. Waits for ownership to change back to `PROGRAM_ID` on the base connection.

```typescript theme={null}
interface UndelegateDepositParams {
  user: PublicKey;
  tokenMint: PublicKey;
  payer: PublicKey;
  magicProgram: PublicKey;  // MAGIC_PROGRAM_ID
  magicContext: PublicKey;  // MAGIC_CONTEXT_ID
  rpcOptions?: RpcOptions;
}
```

#### `undelegateUsernameDeposit(params): Promise<string>`

Commit and return username deposit ownership to the program.

```typescript theme={null}
interface UndelegateUsernameDepositParams {
  username: string;
  tokenMint: PublicKey;
  session: PublicKey;
  payer: PublicKey;
  magicProgram: PublicKey;
  magicContext: PublicKey;
  rpcOptions?: RpcOptions;
}
```

### Private Transfers

These execute on the PER layer — both source and destination accounts must be **delegated**.

#### `transferDeposit(params): Promise<string>`

Transfer balance between two user deposits (accounting only, no token movement).

```typescript theme={null}
interface TransferDepositParams {
  user: PublicKey;
  tokenMint: PublicKey;
  destinationUser: PublicKey;
  amount: number | bigint;
  payer: PublicKey;
  rpcOptions?: RpcOptions;
}
```

#### `transferToUsernameDeposit(params): Promise<string>`

Transfer from a user deposit to a username deposit.

```typescript theme={null}
interface TransferToUsernameDepositParams {
  username: string;
  tokenMint: PublicKey;
  amount: number | bigint;
  user: PublicKey;
  payer: PublicKey;
  rpcOptions?: RpcOptions;
}
```

### Queries

Query deposit state from either the base layer or the ephemeral layer.

#### `getBaseDeposit(user, tokenMint): Promise<DepositData | null>`

Fetch a user deposit from the base layer.

#### `getEphemeralDeposit(user, tokenMint): Promise<DepositData | null>`

Fetch a user deposit from PER.

#### `getBaseUsernameDeposit(username, tokenMint): Promise<UsernameDepositData | null>`

Fetch a username deposit from the base layer.

#### `getEphemeralUsernameDeposit(username, tokenMint): Promise<UsernameDepositData | null>`

Fetch a username deposit from PER.

```typescript theme={null}
interface DepositData {
  user: PublicKey;
  tokenMint: PublicKey;
  amount: bigint;
  address: PublicKey; // PDA
}

interface UsernameDepositData {
  username: string;
  tokenMint: PublicKey;
  amount: bigint;
  address: PublicKey; // PDA
}
```

### PDA Helpers (instance)

* `findDepositPda(user, tokenMint): [PublicKey, number]`
* `findUsernameDepositPda(username, tokenMint): [PublicKey, number]`
* `findVaultPda(tokenMint): [PublicKey, number]`

### Accessors

* `publicKey: PublicKey` — connected wallet's public key
* `getBaseProgram(): Program` — underlying base-layer Anchor program
* `getEphemeralProgram(): Program` — underlying PER-layer Anchor program
* `getProgramId(): PublicKey` — returns `PROGRAM_ID`

## Exported Types

```typescript theme={null}
// Wallet types
type WalletSigner = WalletLike | Keypair | AnchorProvider;
interface WalletLike {
  publicKey: PublicKey;
  signTransaction<T>(tx: T): Promise<T>;
  signAllTransactions<T>(txs: T[]): Promise<T[]>;
}

// RPC options
interface RpcOptions {
  skipPreflight?: boolean;
  preflightCommitment?: Commitment;
  maxRetries?: number;
}

// Delegation status
interface DelegationRecord {
  authority: string;
  owner?: string;
  delegationSlot?: number;
  lamports?: number;
}
interface DelegationStatusResult {
  isDelegated: boolean;
  fqdn?: string;
  delegationRecord: DelegationRecord;
}
interface DelegationStatusResponse {
  jsonrpc: "2.0";
  id: number | string;
  result: DelegationStatusResult;
  error?: { code: number; message: string } | null;
}
```

## Type Guards

* `isKeypair(signer): signer is Keypair`
* `isAnchorProvider(signer): signer is AnchorProvider`
* `isWalletLike(signer): signer is WalletLike`

## Exported Constants

| Constant                | Value                                          |
| ----------------------- | ---------------------------------------------- |
| `PROGRAM_ID`            | `97FzQdWi26mFNR21AbQNg4KqofiCLqQydQfAvRQMcXhV` |
| `DELEGATION_PROGRAM_ID` | `DELeGGvXpWV2fqJUhqcF5ZSYMS4JTLjteaAMARRSaeSh` |
| `PERMISSION_PROGRAM_ID` | `ACLseoPoyC3cBqoUtkbjZ4aDrkurZW86v19pXz2XQnp1` |
| `ER_VALIDATOR`          | `MTEWGuqxUpYZGFJQcp8tLN7x5v9BSeoFHYWQQ3n3xzo`  |
| `MAGIC_PROGRAM_ID`      | `Magic11111111111111111111111111111111111111`  |
| `MAGIC_CONTEXT_ID`      | `MagicContext1111111111111111111111111111111`  |

### PDA Seeds

| Constant                | String Value            |
| ----------------------- | ----------------------- |
| `DEPOSIT_SEED`          | `"deposit_v2"`          |
| `USERNAME_DEPOSIT_SEED` | `"username_deposit_v2"` |
| `VAULT_SEED`            | `"vault"`               |
| `PERMISSION_SEED`       | `"permission:"`         |

### Utilities

* `solToLamports(sol: number): number`
* `lamportsToSol(lamports: number): number`
* `LAMPORTS_PER_SOL`

## Exported PDA Helpers (standalone)

| Function                                      | Seeds                                                        |
| --------------------------------------------- | ------------------------------------------------------------ |
| `findDepositPda(user, tokenMint)`             | `["deposit_v2", user, tokenMint]`                            |
| `findUsernameDepositPda(username, tokenMint)` | `["username_deposit_v2", username, tokenMint]`               |
| `findVaultPda(tokenMint)`                     | `["vault", tokenMint]`                                       |
| `findPermissionPda(account)`                  | `["permission:", account]` (PERMISSION\_PROGRAM\_ID)         |
| `findDelegationRecordPda(account)`            | `["delegation", account]` (DELEGATION\_PROGRAM\_ID)          |
| `findDelegationMetadataPda(account)`          | `["delegation-metadata", account]` (DELEGATION\_PROGRAM\_ID) |
| `findBufferPda(account)`                      | `["buffer", account]` (PROGRAM\_ID)                          |

## IDL Export

For advanced users who need direct Anchor program access:

```typescript theme={null}
import { IDL } from "@loyal-labs/private-transactions";
import type { TelegramPrivateTransfer } from "@loyal-labs/private-transactions";
```

## Example

```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 tokenMint = new PublicKey("<token-mint>");

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",
});

// Shield
await client.initializeDeposit({ user: signer.publicKey, tokenMint, payer: signer.publicKey });
await client.modifyBalance({ user: signer.publicKey, tokenMint, payer: signer.publicKey, amount: 1_000_000, increase: true });
await client.createPermission({ user: signer.publicKey, tokenMint, payer: signer.publicKey });
await client.delegateDeposit({ user: signer.publicKey, tokenMint, payer: signer.publicKey, validator: ER_VALIDATOR });

// Private transfer
await client.transferToUsernameDeposit({ username: "alice_user", tokenMint, amount: 100_000, user: signer.publicKey, payer: signer.publicKey });

// Unshield
await client.undelegateDeposit({ user: signer.publicKey, tokenMint, payer: signer.publicKey, magicProgram: MAGIC_PROGRAM_ID, magicContext: MAGIC_CONTEXT_ID });
await client.modifyBalance({ user: signer.publicKey, tokenMint, payer: signer.publicKey, amount: 1_000_000, increase: false });
```
