npm package: @prvtlabs/prvttools
Description: SDK for Solana ZK Programs — Privacy-preserving VRF, Lottery, Airdrop, Dice, Voting & Payments on Solana. Zero deployment, AI-native, composable via CPI.
Author: prvt.tools
Latest version: 1.0.0

# @prvtlabs/prvttools

**AI-Powered Zero-Knowledge DApps on Solana** — Build privacy-preserving decentralized applications without deploying a single smart contract.

[![npm version](https://img.shields.io/npm/v/@prvtlabs/prvttools.svg)](https://www.npmjs.com/package/@prvtlabs/prvttools)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)

---

## What is this?

**prvt.tools** provides **6 pre-deployed zero-knowledge programs on Solana** that developers and AI agents can call directly — no Anchor build, no deploy keys, no upgrade authority. Just build and sign transactions.

This SDK gives you TypeScript classes, utilities, and types to interact with all 6 programs.

### Why use this?

- **Zero Deployment** — Use shared on-chain ZK programs out of the box. No Rust, no Anchor CLI.
- **AI-Native** — AI agents read IDL definitions and generate transaction instructions automatically.
- **One Program, Unlimited Apps** — Every project uses the same on-chain programs with unique PDA-isolated state.
- **Privacy by Default** — Sensitive data stays off-chain, only zero-knowledge proofs go on-chain.
- **Composable via CPI** — Any Solana program can cross-program invoke these ZK primitives.

---

## Programs

All programs are **live on Solana Devnet** and verified on-chain.

| Program | Description | Program ID | Test Results |
|---------|-------------|------------|--------------|
| **ZK Dice** | Provably fair casino — dice, coin flip, custom range | `4zsyst6Sf6MymUCJthR65eSgWEahbJJ5nd2zRCbJ8Yh6` | 7/7 PASS |
| **ZK Lottery** | Provably fair lottery with committed randomness | `BqB7rvCAeU8ig3AxUZsZBgfK2ZTiSHr6p67ez5z8FuhK` | 7/7 PASS |
| **ZK Airdrop** | Merkle-proof token distribution with nullifiers | `4X1UaqFrJXjoZg8eGt866yytQB5BYZktANi2KDFi9RZ5` | 7/7 PASS |
| **ZK Voting** | Anonymous commit-reveal voting with Merkle eligibility | `3C5NdnjyEkwGu5mqJhh9t21b4PVCufiYgQZhqxd5sp4g` | 4/6 PASS |
| **ZK Payments** | Private payments, escrow, invoices with range proofs | `7gN9AJYbjNtc7wkeRzU2BeUQLNfoA99DnmPyeyRMvFFg` | 8/9 PASS |
| **ZK VRF** | Verifiable random function for tamper-proof randomness | `4QLdhkY3TT2RBxv39jCYFpetiwZxSw6dkXKFfTbkfm1B` | 5/7 PASS |

**Overall: 38/43 tests passing (88%)**

---

## Installation

```bash
npm install @prvtlabs/prvttools
```

```bash
yarn add @prvtlabs/prvttools
```

```bash
pnpm add @prvtlabs/prvttools
```

### Peer Dependencies

```bash
npm install @coral-xyz/anchor @solana/web3.js
```

---

## Quick Start

```typescript
import { Connection, Keypair } from '@solana/web3.js';
import * as anchor from '@coral-xyz/anchor';
import {
  ZkVrf, ZkLottery, ZkDice,
  ZkAirdrop, ZkVoting, ZkPayments
} from '@prvtlabs/prvttools';

// Setup provider
const connection = new Connection('https://api.devnet.solana.com');
const wallet = new anchor.Wallet(Keypair.generate());
const provider = new anchor.AnchorProvider(connection, wallet, {});

// Initialize any program — no deployment needed
const vrf = new ZkVrf(provider);
const lottery = new ZkLottery(provider);
const dice = new ZkDice(provider);
const airdrop = new ZkAirdrop(provider);
const voting = new ZkVoting(provider);
const payments = new ZkPayments(provider);
```

---

## Program Guides

### ZK Dice — Provably Fair Casino Games

Game types: `dice6`, `dice100`, `coinFlip`, custom range. Uses commit-reveal: house commits a server seed hash, player bets, house reveals seed, bet is resolved deterministically.

**Instructions:** `initialize`, `commitServerSeed`, `placeBet`, `revealServerSeed`, `resolveBet`, `depositHouseFunds`, `withdrawHouseFunds`, `updateConfig`

```typescript
import { ZkDice, generateSalt, sha256 } from '@prvtlabs/prvttools';

const dice = new ZkDice(provider);

// House setup
const houseEdgeBps = 250; // 2.5%
const maxBet = BigInt(0.1 * 1e9);
const minBet = BigInt(0.001 * 1e9);
await dice.initialize(houseEdgeBps, maxBet, minBet, authority.publicKey);
await dice.depositHouseFunds(BigInt(1 * 1e9), depositor.publicKey);

// Commit server seed
const seedId = BigInt(Date.now());
const serverSeed = generateSalt();
const commitment = sha256(serverSeed);
await dice.commitServerSeed(seedId, commitment, house.publicKey);

// Player places bet
await dice.placeBet(
  BigInt(0.01 * 1e9),  // bet amount
  generateSalt(),       // client seed
  { dice6: {} },        // game type
  4,                    // prediction: roll 4+ to win
  seedId,
  player.publicKey
);

// Reveal and resolve
await dice.revealServerSeed(seedId, serverSeed, house.publicKey);
await dice.resolveBet(seedId, player.publicKey);
```

---

### ZK Lottery — Provably Fair Lottery System

Create lottery rounds, users buy tickets, winner is revealed using committed randomness. Prize pool distributed to winner minus platform fee.

**Instructions:** `initialize`, `createLottery`, `buyTickets`, `revealWinner`, `claimPrize`, `cancelLottery`, `updateConfig`

```typescript
import { ZkLottery } from '@prvtlabs/prvttools';

const lottery = new ZkLottery(provider);

await lottery.initialize(authority.publicKey);

// Create lottery
const lotteryId = BigInt(Date.now());
await lottery.createLottery(
  lotteryId,
  BigInt(0.01 * 1e9),  // ticket price
  100,                   // max tickets
  BigInt(currentSlot + 1000),  // end slot
  creator.publicKey
);

// Buy tickets
await lottery.buyTickets(lotteryId, 5, buyer.publicKey);

// Draw winner & claim
await lottery.draw(lotteryId, vrfRoundId, authority.publicKey);
await lottery.claimPrize(lotteryId, winner.publicKey);
```

---

### ZK Airdrop — Privacy-Preserving Token Distribution

Distribute tokens using Merkle tree proofs. Users prove eligibility without revealing the full recipient list. Nullifiers prevent double-claiming.

**Instructions:** `createAirdrop`, `claim`, `closeAirdrop`, `pauseAirdrop`, `resumeAirdrop`, `updateMerkleRoot`, `addFunds`

```typescript
import { ZkAirdrop, buildMerkleTree, computeMerkleLeaf, generateSalt } from '@prvtlabs/prvttools';
import { PublicKey } from '@solana/web3.js';

const airdrop = new ZkAirdrop(provider);

// Build Merkle tree from eligible addresses
const leaves = eligibleAddresses.map(addr => computeMerkleLeaf(addr));
const { root, proofs } = buildMerkleTree(leaves);

// Create airdrop campaign
const airdropId = BigInt(Date.now());
await airdrop.createAirdrop(
  airdropId, root,
  BigInt(100 * 1e9),                  // amount per recipient
  BigInt(eligibleAddresses.length),    // total recipients
  tokenMint,
  BigInt(currentSlot + 50000),         // expiry
  authority.publicKey
);

// Eligible user claims
const userIndex = eligibleAddresses.findIndex(a => a.equals(user.publicKey));
const proof = proofs.get(userIndex)!;
await airdrop.claim(airdropId, proof, BigInt(userIndex), generateSalt(), user.publicKey);
```

---

### ZK Voting — Anonymous Voting System

Two-phase commit-reveal voting. Phase 1: voters commit encrypted vote hash. Phase 2: voters reveal their vote. Nullifiers prevent double-voting. Merkle root gates voter eligibility.

**Instructions:** `initialize`, `createProposal`, `commitVote`, `revealVote`, `finalizeProposal`, `cancelProposal`, `updateVoterRoot`

**Lifecycle:** Pending → Active → Revealing → Finalized (or Cancelled)

```typescript
import { ZkVoting, createVoteCommitment, generateSalt, generateNullifier,
         buildMerkleTree, computeMerkleLeaf } from '@prvtlabs/prvttools';

const voting = new ZkVoting(provider);
await voting.initialize(authority.publicKey);

// Build voter eligibility tree
const leaves = eligibleVoters.map(v => computeMerkleLeaf(v));
const { root, proofs } = buildMerkleTree(leaves);

// Create proposal
const proposalId = BigInt(Date.now());
await voting.createProposal(
  proposalId, "Treasury Allocation",
  "How should we allocate Q1 funds?",
  ["Development", "Marketing", "Community", "Reserve"],
  root,
  BigInt(currentSlot + 100),    // voting start
  BigInt(currentSlot + 5000),   // voting end
  BigInt(currentSlot + 10000),  // reveal end
  creator.publicKey
);

// Commit vote (Phase 1)
const salt = generateSalt();
const commitment = createVoteCommitment(0, salt);  // vote for option 0
const nullifier = generateNullifier(voter.publicKey, proposalId);
const proof = proofs.get(voterIndex)!;
await voting.commitVote(proposalId, commitment, proof, BigInt(voterIndex), nullifier, voter.publicKey);

// Reveal vote (Phase 2)
await voting.revealVote(proposalId, 0, salt, voter.publicKey);

// Finalize
await voting.finalizeProposal(proposalId, authority.publicKey);
```

---

### ZK Payments — Private Payment Verification & Escrow

Commit-reveal payments, range proofs, escrow with hidden amounts, and invoicing. Payment amounts stay private until revealed. Escrow supports dispute resolution.

**Instructions:** `initialize`, `createPaymentCommitment`, `revealPayment`, `executePayment`, `createRangeAttestation`, `createEscrow`, `depositToEscrow`, `releaseEscrow`, `refundEscrow`, `createInvoice`, `payInvoice`

**Escrow lifecycle:** Active → Funded → Released / Refunded / Disputed
**Invoice lifecycle:** Pending → Paid / Cancelled / Overdue

```typescript
import { ZkPayments, createAmountCommitment, generateSalt, sha256 } from '@prvtlabs/prvttools';

const payments = new ZkPayments(provider);
await payments.initialize(authority.publicKey);

// Private payment with hidden amount
const paymentId = BigInt(Date.now());
const amount = BigInt(0.5 * 1e9);
const salt = generateSalt();
const commitment = createAmountCommitment(amount, salt);

await payments.createPayment(
  paymentId, commitment, recipient.publicKey,
  BigInt(0.1 * 1e9), BigInt(1 * 1e9),    // min/max range
  BigInt(currentSlot + 10000),
  sender.publicKey
);
await payments.revealPayment(paymentId, amount, salt, sender.publicKey);
await payments.executePayment(paymentId, sender.publicKey);

// Escrow with hidden amount
const escrowId = BigInt(Date.now());
const escrowCommitment = createAmountCommitment(BigInt(1 * 1e9), generateSalt());
const conditionHash = sha256(Buffer.from('condition_met'));

await payments.createEscrow(
  escrowId, escrowCommitment, conditionHash,
  arbiter.publicKey, BigInt(currentSlot + 50000),
  depositor.publicKey, beneficiary.publicKey
);
await payments.depositToEscrow(escrowId, BigInt(1 * 1e9), depositor.publicKey);
await payments.releaseEscrow(escrowId, Buffer.from('condition_met'), arbiter.publicKey);

// Invoice system
const invoiceId = BigInt(Date.now());
const invoiceCommitment = createAmountCommitment(BigInt(0.1 * 1e9), generateSalt());
await payments.createInvoice(
  invoiceId, invoiceCommitment, sha256(Buffer.from('Service Payment')),
  BigInt(currentSlot + 10000), issuer.publicKey, payer.publicKey
);
await payments.payInvoice(invoiceId, BigInt(0.1 * 1e9), generateSalt(), payer.publicKey);
```

---

### ZK VRF — Verifiable Random Function

On-chain verifiable randomness. Operator commits to a seed, users request randomness, operator reveals preimage, request is fulfilled with deterministic random output.

**Instructions:** `initialize`, `createRound`, `requestRandomness`, `reveal`, `fulfillRequest`, `closeRound`, `withdrawFees`, `updateConfig`

```typescript
import { ZkVrf, generateSalt, sha256 } from '@prvtlabs/prvttools';

const vrf = new ZkVrf(provider);
await vrf.initialize(authority.publicKey);

// Operator creates round
const roundId = BigInt(Date.now());
await vrf.createRound(roundId, authority.publicKey);

// User requests randomness
const clientSeed = generateSalt();
await vrf.requestRandomness(roundId, clientSeed, requester.publicKey);

// Operator reveals and fulfills
const serverSeed = generateSalt();
await vrf.reveal(roundId, serverSeed, oracle.publicKey);
await vrf.fulfillRequest(roundId, requester.publicKey);
```

---

## Utility Functions

### Cryptographic Utilities

```typescript
import {
  sha256,                  // SHA256 hash
  generateSalt,            // Random 32-byte salt
  createCommitment,        // Generic commit: sha256(value + salt)
  createAmountCommitment,  // Amount commit for payments
  createVoteCommitment,    // Vote commit for voting
  generateNullifier,       // Nullifier to prevent double-actions
} from '@prvtlabs/prvttools';

const salt = generateSalt();              // 32-byte Buffer
const hash = sha256(Buffer.from('data')); // 32-byte hash
const commitment = createCommitment(value, salt);
```

### Merkle Tree Utilities

```typescript
import {
  computeMerkleLeaf,   // Compute leaf from PublicKey
  computeMerkleNode,   // Compute parent from two children
  buildMerkleTree,     // Build tree, returns { root, proofs }
  verifyMerkleProof,   // Verify a proof against root
} from '@prvtlabs/prvttools';

const leaves = addresses.map(addr => computeMerkleLeaf(addr));
const { root, proofs } = buildMerkleTree(leaves);
const isValid = verifyMerkleProof(leaf, proof, leafIndex, root);
```

### PDA Derivation

Every program uses Program Derived Addresses for state isolation. The SDK provides helpers for all PDAs:

```typescript
import {
  PROGRAM_IDS,
  // VRF
  getVrfConfigPDA, getVrfRoundPDA, getVrfRequestPDA,
  // Lottery
  getLotteryConfigPDA, getLotteryPDA, getLotteryPoolPDA, getTicketPDA,
  // Airdrop
  getAirdropPDA, getAirdropVaultPDA, getAirdropNullifierPDA,
  // Dice
  getDiceConfigPDA, getHouseVaultPDA, getServerSeedPDA, getBetPDA,
  // Voting
  getVotingConfigPDA, getProposalPDA, getVotePDA, getVoteNullifierPDA,
  // Payments
  getPaymentConfigPDA, getPaymentPDA, getEscrowPDA, getEscrowVaultPDA,
  getInvoicePDA, getAttestationPDA,
} from '@prvtlabs/prvttools';
```

---

## Types

All TypeScript types are fully exported:

```typescript
import type {
  // VRF
  VrfConfig, VrfRound, RandomnessRequest,
  // Lottery
  LotteryConfig, Lottery, LotteryTicket, LotteryStatus,
  // Dice
  DiceConfig, ServerSeed, Bet, GameType,
  // Airdrop
  Airdrop, AirdropNullifier, AirdropStatus,
  // Voting
  VotingConfig, Proposal, Vote, ProposalStatus,
  // Payments
  PaymentConfig, PaymentCommitment, Escrow, Invoice,
  PaymentStatus, EscrowStatus, InvoiceStatus,
} from '@prvtlabs/prvttools';
```

---

## AI Agent Integration

AI agents can build ZK dApps in 3 steps:

1. **Load IDL** — Read the JSON IDL for any program (included in `idl/` directory)
2. **Derive PDAs** — Use program ID + seeds to compute account addresses
3. **Build TX** — Construct `TransactionInstruction` with discriminator + args

No deployment. No Rust. No Anchor CLI. Just transaction construction.

The SDK ships with IDL files for all 6 programs:
- `idl/zk_dice.json`
- `idl/zk_lottery.json`
- `idl/zk_voting.json`
- `idl/zk_airdrop.json`
- `idl/zk_payments.json`
- `idl/zk_vrf.json`

---

## Error Handling

All SDK methods return transaction signatures on success:

```typescript
try {
  const tx = await dice.placeBet(amount, clientSeed, gameType, prediction, seedId, player);
  console.log('Transaction:', tx);
} catch (error) {
  if (error.message.includes('insufficient funds')) {
    console.error('Not enough SOL');
  } else if (error.message.includes('6001')) {
    console.error('Anchor program error — check error code');
  } else {
    console.error('Transaction failed:', error);
  }
}
```

---

## Network Configuration

Programs are deployed on **Solana Devnet**. For custom RPC:

```typescript
const connection = new Connection('https://your-rpc-endpoint.com', 'confirmed');
const provider = new anchor.AnchorProvider(connection, wallet, {
  commitment: 'confirmed',
  preflightCommitment: 'confirmed',
});
```

---

## Wallet Connection

### Node.js / Backend

```typescript
import { Connection, Keypair } from '@solana/web3.js';
import * as anchor from '@coral-xyz/anchor';
import { ZkDice } from '@prvtlabs/prvttools';

// Load keypair from file
import fs from 'fs';
const secret = JSON.parse(fs.readFileSync('./keypair.json', 'utf-8'));
const keypair = Keypair.fromSecretKey(Uint8Array.from(secret));

const connection = new Connection('https://api.devnet.solana.com', 'confirmed');
const wallet = new anchor.Wallet(keypair);
const provider = new anchor.AnchorProvider(connection, wallet, {});

const dice = new ZkDice(provider);
```

### React / Next.js (with Wallet Adapter)

```bash
npm install @solana/wallet-adapter-react @solana/wallet-adapter-wallets @solana/wallet-adapter-react-ui
```

```tsx
import { useAnchorWallet, useConnection } from '@solana/wallet-adapter-react';
import * as anchor from '@coral-xyz/anchor';
import { ZkDice, ZkLottery } from '@prvtlabs/prvttools';

function MyComponent() {
  const { connection } = useConnection();
  const wallet = useAnchorWallet();

  const playDice = async () => {
    if (!wallet) return;
    const provider = new anchor.AnchorProvider(connection, wallet, {});
    const dice = new ZkDice(provider);

    // Now use any SDK method — wallet signs automatically
    await dice.placeBet(
      BigInt(0.01 * 1e9),
      generateSalt(),
      { dice6: {} },
      4,
      seedId,
      wallet.publicKey
    );
  };

  return <button onClick={playDice}>Roll Dice</button>;
}
```

### Wallet Provider Setup (App root)

```tsx
import { WalletProvider } from '@solana/wallet-adapter-react';
import { ConnectionProvider } from '@solana/wallet-adapter-react';
import { PhantomWalletAdapter, SolflareWalletAdapter } from '@solana/wallet-adapter-wallets';
import { WalletModalProvider } from '@solana/wallet-adapter-react-ui';

const wallets = [new PhantomWalletAdapter(), new SolflareWalletAdapter()];

function App({ children }) {
  return (
    <ConnectionProvider endpoint="https://api.devnet.solana.com">
      <WalletProvider wallets={wallets} autoConnect>
        <WalletModalProvider>
          {children}
        </WalletModalProvider>
      </WalletProvider>
    </ConnectionProvider>
  );
}
```

### Supported Wallets

Any Solana wallet works — Phantom, Solflare, Backpack, Ledger, Torus, etc. The SDK just needs an `AnchorProvider` with a connected wallet.

---

## Use Cases

| Use Case | Programs |
|----------|----------|
| **Gaming** | ZK Dice + ZK VRF for provably fair games |
| **Governance** | ZK Voting for anonymous DAO proposals |
| **Token Distribution** | ZK Airdrop for private Merkle airdrops |
| **DeFi** | ZK Payments for private escrow & invoicing |
| **Lotteries & Raffles** | ZK Lottery + ZK VRF for fair draws |
| **Any dApp needing randomness** | ZK VRF standalone |

---

## Contributing

Contributions are welcome! Please submit issues and pull requests.

---

## License

[MIT](LICENSE)