Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
API_KEY=YOUR_KEY
12 changes: 7 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
node_modules/
dist/
.env
pnpm-lock.yaml
package-lock.json
**/node_modules/
**/dist/
**/.env
**/pnpm-lock.yaml
**/package-lock.json
**/*.json.bak
**/test-ledger
3 changes: 3 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"tabWidth": 4
}
40 changes: 20 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,41 +34,41 @@ End-to-end example: create a mint, token account, mint tokens, and transfer on d

## Cookbook

Step-by-step recipes for light-token on localnet.
Step-by-step recipes for light-token on Devnet/Localnet.

### [Actions](cookbook/actions/)

- **[create-mint](cookbook/actions/create-mint.ts)** - Create a new light-token mint
- **[create-ata](cookbook/actions/create-ata.ts)** - Create an associated light-token account
- **[load-ata](cookbook/actions/load-ata.ts)** - Load a cold token account (compressed) to hot balance (light-token ata)
- **[mint-to](cookbook/actions/mint-to.ts)** - Mint tokens to a light-account
- **[transfer-interface](cookbook/actions/transfer-interface.ts)** - Transfer tokens between light-token, T22, and SPL token accounts.
- **[wrap](cookbook/actions/wrap.ts)** - Wrap SPL to light-token
- **[unwrap](cookbook/actions/unwrap.ts)** - Unwrap light-token to SPL for off-ramps and legacy integrations
- **[create-mint](cookbook/actions/create-mint.ts)** - Create a new light-token mint
- **[create-ata](cookbook/actions/create-ata.ts)** - Create an associated light-token account
- **[load-ata](cookbook/actions/load-ata.ts)** - Load a cold token account (compressed) to hot balance (light-token ata)
- **[mint-to](cookbook/actions/mint-to.ts)** - Mint tokens to a light-account
- **[transfer-interface](cookbook/actions/transfer-interface.ts)** - Transfer tokens between light-token, T22, and SPL token accounts.
- **[wrap](cookbook/actions/wrap.ts)** - Wrap SPL to light-token
- **[unwrap](cookbook/actions/unwrap.ts)** - Unwrap light-token to SPL for off-ramps and legacy integrations

### [Instructions](cookbook/instructions/)

Low-level instruction builders:

- **[create-mint](cookbook/instructions/create-mint.ts)** - Build create mint instruction
- **[create-ata](cookbook/instructions/create-ata.ts)** - Build create ATA instruction
- **[load-ata](cookbook/instructions/load-ata.ts)** - Build load ATA instruction
- **[mint-to](cookbook/instructions/mint-to.ts)** - Build mint-to instruction
- **[transfer-interface](cookbook/instructions/transfer-interface.ts)** - Build transfer interface instruction for transfers between light-token, T22, and SPL token accounts.
- **[wrap](cookbook/instructions/wrap.ts)** - Build wrap instruction
- **[unwrap](cookbook/instructions/unwrap.ts)** - Build unwrap instruction for off-ramps and legacy integrations
- **[create-mint](cookbook/instructions/create-mint.ts)** - Build create mint instruction
- **[create-ata](cookbook/instructions/create-ata.ts)** - Build create ATA instruction
- **[load-ata](cookbook/instructions/load-ata.ts)** - Build load ATA instruction
- **[mint-to](cookbook/instructions/mint-to.ts)** - Build mint-to instruction
- **[transfer-interface](cookbook/instructions/transfer-interface.ts)** - Build transfer interface instruction for transfers between light-token, T22, and SPL token accounts.
- **[wrap](cookbook/instructions/wrap.ts)** - Build wrap instruction
- **[unwrap](cookbook/instructions/unwrap.ts)** - Build unwrap instruction for off-ramps and legacy integrations

## Toolkits

### [Payments and Wallets](toolkits/payments-and-wallets/)

Examples for wallet integrations and payment flows:

- **[get-balance](toolkits/payments-and-wallets/get-balance.ts)** - Fetch token balances for light-token accounts
- **[get-history](toolkits/payments-and-wallets/get-history.ts)** - Fetch transaction history for light-token accounts
- **[send-and-receive](toolkits/payments-and-wallets/send-and-receive.ts)** - Send and receive light-tokens using the transfer interface
- **[wrap-from-spl](toolkits/payments-and-wallets/wrap-from-spl.ts)** - Wrap SPL tokens to light-token
- **[unwrap-to-spl](toolkits/payments-and-wallets/unwrap-to-spl.ts)** - Unwrap light-token to SPL for off-ramps and legacy integrations
- **[get-balance](toolkits/payments-and-wallets/get-balance.ts)** - Fetch token balances for light-token accounts
- **[get-history](toolkits/payments-and-wallets/get-history.ts)** - Fetch transaction history for light-token accounts
- **[send-and-receive](toolkits/payments-and-wallets/send-and-receive.ts)** - Send and receive light-tokens using the transfer interface
- **[wrap](toolkits/payments-and-wallets/wrap.ts)** - Wrap SPL tokens to light-token
- **[unwrap](toolkits/payments-and-wallets/unwrap.ts)** - Unwrap light-token to SPL for off-ramps and legacy integrations

### [Streaming Tokens](toolkits/streaming-tokens/)

Expand Down
2 changes: 0 additions & 2 deletions cookbook/.env.example

This file was deleted.

84 changes: 22 additions & 62 deletions cookbook/actions/compress-batch.ts
Original file line number Diff line number Diff line change
@@ -1,72 +1,32 @@
import "dotenv/config";
import { Keypair } from "@solana/web3.js";
import { createRpc, bn } from "@lightprotocol/stateless.js";
import {
createMint,
mintTo,
decompress,
compress,
} from "@lightprotocol/compressed-token";
import { createMint, mintTo, decompress, compress } from "@lightprotocol/compressed-token";
import { createAssociatedTokenAccount } from "@solana/spl-token";
import { homedir } from "os";
import { readFileSync } from "fs";

async function main() {
// 1. Setup RPC and fund accounts
const rpc = createRpc();
const payer = Keypair.generate();
const airdropSig = await rpc.requestAirdrop(payer.publicKey, 10e9);
await rpc.confirmTransaction(airdropSig, "confirmed");
console.log("Payer:", payer.publicKey.toBase58());
const RPC_URL = `https://devnet.helius-rpc.com?api-key=${process.env.API_KEY!}`;
const payer = Keypair.fromSecretKey(
new Uint8Array(
JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8"))
)
);

const owner = Keypair.generate();
const airdropSig2 = await rpc.requestAirdrop(owner.publicKey, 1e9);
await rpc.confirmTransaction(airdropSig2, "confirmed");
(async function () {
const rpc = createRpc(RPC_URL);

// 2. Create SPL mint with token pool
const mintAuthority = Keypair.generate();
const mintKeypair = Keypair.generate();
const { mint } = await createMint(
rpc,
payer,
mintAuthority.publicKey,
9,
mintKeypair
);
console.log("Mint:", mint.toBase58());
// Setup: Get SPL tokens (needed to compress)
const { mint } = await createMint(rpc, payer, payer.publicKey, 9);
const splAta = await createAssociatedTokenAccount(rpc, payer, mint, payer.publicKey);
await mintTo(rpc, payer, mint, payer.publicKey, payer, bn(10000));
await decompress(rpc, payer, mint, bn(10000), payer, splAta);

// 3. Create SPL ATA and fund it
const splAta = await createAssociatedTokenAccount(
rpc,
payer,
mint,
owner.publicKey
);
console.log("SPL ATA:", splAta.toBase58());
// Batch compress to multiple recipients
const recipients = Array.from({ length: 5 }, () => Keypair.generate().publicKey);
const amounts = [bn(100), bn(200), bn(300), bn(400), bn(500)];

await mintTo(rpc, payer, mint, owner.publicKey, mintAuthority, bn(10000));
await decompress(rpc, payer, mint, bn(10000), owner, splAta);
console.log("Funded SPL ATA with 10000 tokens");
const tx = await compress(rpc, payer, mint, amounts, payer, splAta, recipients);

// 4. Batch compress to multiple recipients (max 10 for V2 trees)
const recipients = Array.from({ length: 5 }, () => Keypair.generate().publicKey);
const amounts = [bn(100), bn(200), bn(300), bn(400), bn(500)];

const signature = await compress(
rpc,
payer,
mint,
amounts, // array of amounts
owner,
splAta,
recipients // array of recipients (same length as amounts)
);

console.log("Batch compressed to 5 recipients");
console.log("Amounts:", amounts.map((a) => a.toString()).join(", "));
console.log("Transaction:", signature);
}

main().catch((err) => {
console.error("Error:", err);
if (err.logs) console.error("Logs:", err.logs);
process.exit(1);
});
console.log("Tx:", tx);
})();
94 changes: 26 additions & 68 deletions cookbook/actions/compress.ts
Original file line number Diff line number Diff line change
@@ -1,72 +1,30 @@
import "dotenv/config";
import { Keypair } from "@solana/web3.js";
import { createRpc, bn } from "@lightprotocol/stateless.js";
import {
createMint,
mintTo,
decompress,
compress,
} from "@lightprotocol/compressed-token";
import { createMint, mintTo, decompress, compress } from "@lightprotocol/compressed-token";
import { createAssociatedTokenAccount } from "@solana/spl-token";

async function main() {
// 1. Setup RPC and fund accounts
const rpc = createRpc();
const payer = Keypair.generate();
const airdropSig = await rpc.requestAirdrop(payer.publicKey, 10e9);
await rpc.confirmTransaction(airdropSig, "confirmed");
console.log("Payer:", payer.publicKey.toBase58());

const owner = Keypair.generate();
const airdropSig2 = await rpc.requestAirdrop(owner.publicKey, 1e9);
await rpc.confirmTransaction(airdropSig2, "confirmed");

// 2. Create SPL mint with token pool
const mintAuthority = Keypair.generate();
const mintKeypair = Keypair.generate();
const { mint } = await createMint(
rpc,
payer,
mintAuthority.publicKey,
9,
mintKeypair
);
console.log("Mint:", mint.toBase58());

// 3. Create SPL ATA and fund it with SPL tokens
const splAta = await createAssociatedTokenAccount(
rpc,
payer,
mint,
owner.publicKey
);
console.log("SPL ATA:", splAta.toBase58());

// Mint compressed then decompress to get SPL tokens
await mintTo(rpc, payer, mint, owner.publicKey, mintAuthority, bn(1000));
await decompress(rpc, payer, mint, bn(1000), owner, splAta);
console.log("Funded SPL ATA with 1000 tokens");

// 4. Compress SPL tokens to cold storage
const recipient = Keypair.generate();

const signature = await compress(
rpc,
payer,
mint,
bn(500), // amount to compress
owner, // owner of SPL account (signer)
splAta, // source SPL token account
recipient.publicKey // recipient of compressed tokens
);

console.log("Compressed 500 tokens to cold storage");
console.log("Recipient:", recipient.publicKey.toBase58());
console.log("Transaction:", signature);
}

main().catch((err) => {
console.error("Error:", err);
if (err.logs) console.error("Logs:", err.logs);
process.exit(1);
});
import { homedir } from "os";
import { readFileSync } from "fs";

const RPC_URL = `https://devnet.helius-rpc.com?api-key=${process.env.API_KEY!}`;
const payer = Keypair.fromSecretKey(
new Uint8Array(
JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8"))
)
);

(async function () {
const rpc = createRpc(RPC_URL);

// Setup: Get SPL tokens (needed to compress)
const { mint } = await createMint(rpc, payer, payer.publicKey, 9);
const splAta = await createAssociatedTokenAccount(rpc, payer, mint, payer.publicKey);
await mintTo(rpc, payer, mint, payer.publicKey, payer, bn(1000));
await decompress(rpc, payer, mint, bn(1000), payer, splAta);

// Compress SPL tokens to cold storage
const recipient = Keypair.generate();
const tx = await compress(rpc, payer, mint, bn(500), payer, splAta, recipient.publicKey);

console.log("Tx:", tx);
})();
60 changes: 18 additions & 42 deletions cookbook/actions/create-ata.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,27 @@
import "dotenv/config";
import { Keypair } from "@solana/web3.js";
import { createRpc } from "@lightprotocol/stateless.js";
import {
createRpc,
featureFlags,
VERSION,
} from "@lightprotocol/stateless.js";
import {
createMintInterface,
createAtaInterface,
getAssociatedTokenAddressInterface,
createMintInterface,
createAtaInterface,
} from "@lightprotocol/compressed-token";
import { homedir } from "os";
import { readFileSync } from "fs";

featureFlags.version = VERSION.V2;

async function main() {
// 1. Setup RPC and fund payer
const rpc = createRpc();
const payer = Keypair.generate();
const airdropSig = await rpc.requestAirdrop(payer.publicKey, 10e9);
await rpc.confirmTransaction(airdropSig, "confirmed");
console.log("Payer:", payer.publicKey.toBase58());
const RPC_URL = `https://devnet.helius-rpc.com?api-key=${process.env.API_KEY!}`;
const payer = Keypair.fromSecretKey(
new Uint8Array(
JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8"))
)
);

// 2. Create a light-mint
const mintSigner = Keypair.generate();
const { mint } = await createMintInterface(
rpc,
payer,
payer, // mintAuthority
null, // freezeAuthority
9, // decimals
mintSigner
);
console.log("Mint:", mint.toBase58());
(async function () {
const rpc = createRpc(RPC_URL);

// 3. Create associated token account for owner
const owner = Keypair.generate();
const txSignature = await createAtaInterface(rpc, payer, mint, owner.publicKey);
console.log("ATA created for:", owner.publicKey.toBase58());
console.log("Transaction:", txSignature);
const { mint } = await createMintInterface(rpc, payer, payer, null, 9);

// 4. Derive the ATA address
const ata = getAssociatedTokenAddressInterface(mint, owner.publicKey);
console.log("ATA address:", ata.toBase58());
}
const owner = Keypair.generate();
const ata = await createAtaInterface(rpc, payer, mint, owner.publicKey);

main().catch((err) => {
console.error("Error:", err);
if (err.logs) console.error("Logs:", err.logs);
process.exit(1);
});
console.log("ATA:", ata.toBase58());
})();
Loading