Payments and wallets
Build payment flows and wallet integrations using light-token on Solana. The light-token API matches SPL-token and extends it to include the light token program.
| Creation cost |
SPL |
light-token |
| Token Account |
~2,000,000 lamports |
~11,000 lamports |
Workflow
- Clarify intent
- Recommend plan mode, if it's not activated
- Use
AskUserQuestion to resolve blind spots
- All questions must be resolved before execution
- Identify references and skills
- Write plan file (YAML task format)
- Use
AskUserQuestion for anything unclear — never guess or assume
- Identify blockers: permissions, dependencies, unknowns
- Plan must be complete before execution begins
- Execute
- Use
Task tool with subagents for parallel research
- Subagents load skills via
Skill tool
- Track progress with
TodoWrite
- When stuck: ask to spawn a read-only subagent with
Read, Glob, Grep, and DeepWiki MCP access, loading skills/ask-mcp. Scope reads to skill references, example repos, and docs.
API overview
| Operation |
SPL |
light-token (action / instruction) |
| Receive |
getOrCreateAssociatedTokenAccount() |
loadAta() / createLoadAtaInstructions() |
| Transfer |
createTransferInstruction() |
transferInterface() / createTransferInterfaceInstructions() |
| Get balance |
getAccount() |
getAtaInterface() |
| Tx history |
getSignaturesForAddress() |
rpc.getSignaturesForOwnerInterface() |
| Wrap from SPL |
N/A |
wrap() / createWrapInstruction() |
| Unwrap to SPL |
N/A |
unwrap() / createUnwrapInstructions() |
| Register SPL mint |
N/A |
createSplInterface() / LightTokenProgram.createSplInterface() |
| Create mint |
createMint() |
createMintInterface() |
Plural functions (createTransferInterfaceInstructions, createUnwrapInstructions) return TransactionInstruction[][] — each inner array is one transaction. They handle loading cold accounts automatically.
Domain references
| Task |
Reference |
| Build payment flows (receive, send, balance, history, wrap/unwrap) |
payments.md |
| Build wallet UI (display tokens, transfer, wrap/unwrap) |
wallets.md |
| Sign with Wallet Adapter or Mobile Wallet Adapter |
sign-with-adapter.md |
| Sign with Privy (embedded wallet provider) |
sign-with-privy.md |
| Prevent duplicate actions (double-spend prevention) |
nullifiers.md |
Setup
npm install @lightprotocol/compressed-token@beta @lightprotocol/stateless.js@beta @solana/web3.js @solana/spl-token
import { createRpc } from "@lightprotocol/stateless.js";
import {
createLoadAtaInstructions,
loadAta,
createTransferInterfaceInstructions,
transferInterface,
createUnwrapInstructions,
unwrap,
getAssociatedTokenAddressInterface,
getAtaInterface,
wrap,
} from "@lightprotocol/compressed-token/unified";
const rpc = createRpc(RPC_ENDPOINT);
Resources
SDK references
| Package |
Link |
@lightprotocol/stateless.js |
API docs |
@lightprotocol/compressed-token |
API docs |
@lightprotocol/nullifier-program |
npm |
Security
The Privy signing examples transmit secrets to an external API — review sign-with-privy.md before running.
- Declared dependencies.
HELIUS_RPC_URL is required for all examples. The Privy signing flow additionally requires PRIVY_APP_ID, PRIVY_APP_SECRET, TREASURY_WALLET_ID, and TREASURY_AUTHORIZATION_KEY — get these at privy.io. Load secrets from a secrets manager, not agent-global environment.
- Privy signing flow.
PRIVY_APP_SECRET and TREASURY_AUTHORIZATION_KEY are sent to Privy's signing API. Verify these only reach Privy's official endpoints. See sign-with-privy.md.
- Subagent scope. When stuck, the skill asks to spawn a read-only subagent with
Read, Glob, Grep scoped to skill references, example repos, and docs.
- Install source.
npx skills add Lightprotocol/skills from Lightprotocol/skills.
- Audited protocol. Audit reports at github.com/Lightprotocol/light-protocol/tree/main/audits.
1---2name: payments-and-wallets3description: For stablecoin payment flows and wallet integrations on Solana 200x cheaper token accounts. Receive, send, balance, history, and client-side signing with Privy and Solana wallet adapters. Optional guide to add nullifiers to prevent payments from being executed more than once.4---5
6# Payments and wallets
7
8Build payment flows and wallet integrations using light-token on Solana. The light-token API matches SPL-token and extends it to include the light token program.
9
10| Creation cost | SPL | light-token |
11| :---------------- | :------------------ | :------------------- |
12| **Token Account** | ~2,000,000 lamports | ~**11,000** lamports |
13
14## Workflow
15
161. **Clarify intent**
17 - Recommend plan mode, if it's not activated
18 - Use `AskUserQuestion` to resolve blind spots
19 - All questions must be resolved before execution
202. **Identify references and skills**
21 - Match task to [domain references](#domain-references) below
22 - Locate relevant documentation and examples
233. **Write plan file** (YAML task format)
24 - Use `AskUserQuestion` for anything unclear — never guess or assume
25 - Identify blockers: permissions, dependencies, unknowns
26 - Plan must be complete before execution begins
274. **Execute**
28 - Use `Task` tool with subagents for parallel research
29 - Subagents load skills via `Skill` tool
30 - Track progress with `TodoWrite`
315. **When stuck**: ask to spawn a read-only subagent with `Read`, `Glob`, `Grep`, and DeepWiki MCP access, loading `skills/ask-mcp`. Scope reads to skill references, example repos, and docs.
32
33## API overview
34
35| Operation | SPL | light-token (action / instruction) |
36|-----------|-----|-------------------------------------|
37| Receive | `getOrCreateAssociatedTokenAccount()` | `loadAta()` / `createLoadAtaInstructions()` |
38| Transfer | `createTransferInstruction()` | `transferInterface()` / `createTransferInterfaceInstructions()` |
39| Get balance | `getAccount()` | `getAtaInterface()` |
40| Tx history | `getSignaturesForAddress()` | `rpc.getSignaturesForOwnerInterface()` |
41| Wrap from SPL | N/A | `wrap()` / `createWrapInstruction()` |
42| Unwrap to SPL | N/A | `unwrap()` / `createUnwrapInstructions()` |
43| Register SPL mint | N/A | `createSplInterface()` / `LightTokenProgram.createSplInterface()` |
44| Create mint | `createMint()` | `createMintInterface()` |
45
46Plural functions (`createTransferInterfaceInstructions`, `createUnwrapInstructions`) return `TransactionInstruction[][]` — each inner array is one transaction. They handle loading cold accounts automatically.
47
48## Domain references
49
50| Task | Reference |
51|------|-----------|
52| Build payment flows (receive, send, balance, history, wrap/unwrap) | [payments.md](references/payments.md) |
53| Build wallet UI (display tokens, transfer, wrap/unwrap) | [wallets.md](references/wallets.md) |
54| Sign with Wallet Adapter or Mobile Wallet Adapter | [sign-with-adapter.md](references/sign-with-adapter.md) |
55| Sign with Privy (embedded wallet provider) | [sign-with-privy.md](references/sign-with-privy.md) |
56| Prevent duplicate actions (double-spend prevention) | [nullifiers.md](references/nullifiers.md) |
57
58## Setup
59
60```bash
61npm install @lightprotocol/compressed-token@beta @lightprotocol/stateless.js@beta @solana/web3.js @solana/spl-token
62```
63
64```typescript
65import { createRpc } from "@lightprotocol/stateless.js";
66import {
67 createLoadAtaInstructions,
68 loadAta,
69 createTransferInterfaceInstructions,
70 transferInterface,
71 createUnwrapInstructions,
72 unwrap,
73 getAssociatedTokenAddressInterface,
74 getAtaInterface,
75 wrap,
76} from "@lightprotocol/compressed-token/unified";
77
78const rpc = createRpc(RPC_ENDPOINT);
79```
80
81## Resources
82
83- [Payments docs](https://zkcompression.com/light-token/toolkits/for-payments)
84- [Wallets docs](https://zkcompression.com/light-token/toolkits/for-wallets)
85- [GitHub examples](https://github.com/Lightprotocol/examples-light-token/tree/main/toolkits/payments-and-wallets)
86- [Nullifier program](https://github.com/Lightprotocol/nullifier-program/)
87
88## SDK references
89
90| Package | Link |
91|---------|------|
92| `@lightprotocol/stateless.js` | [API docs](https://lightprotocol.github.io/light-protocol/stateless.js/index.html) |
93| `@lightprotocol/compressed-token` | [API docs](https://lightprotocol.github.io/light-protocol/compressed-token/index.html) |
94| `@lightprotocol/nullifier-program` | [npm](https://www.npmjs.com/package/@lightprotocol/nullifier-program) |
95
96## Security
97
98The Privy signing examples transmit secrets to an external API — review [sign-with-privy.md](references/sign-with-privy.md) before running.
99
100- **Declared dependencies.** `HELIUS_RPC_URL` is required for all examples. The Privy signing flow additionally requires `PRIVY_APP_ID`, `PRIVY_APP_SECRET`, `TREASURY_WALLET_ID`, and `TREASURY_AUTHORIZATION_KEY` — get these at [privy.io](https://privy.io). Load secrets from a secrets manager, not agent-global environment.
101- **Privy signing flow.** `PRIVY_APP_SECRET` and `TREASURY_AUTHORIZATION_KEY` are sent to Privy's signing API. Verify these only reach Privy's official endpoints. See [sign-with-privy.md](references/sign-with-privy.md).
102- **Subagent scope.** When stuck, the skill asks to spawn a read-only subagent with `Read`, `Glob`, `Grep` scoped to skill references, example repos, and docs.
103- **Install source.** `npx skills add Lightprotocol/skills` from [Lightprotocol/skills](https://github.com/Lightprotocol/skills).
104- **Audited protocol.** Audit reports at [github.com/Lightprotocol/light-protocol/tree/main/audits](https://github.com/Lightprotocol/light-protocol/tree/main/audits).