Skip to content

Commit d871e48

Browse files
author
tilo-14
committed
Add delegation instruction examples, delegate-transfer to payments toolkit
- Update delegate-transfer to use transferInterface + { owner } option (replaces transferDelegatedInterface) - Add instruction-level delegate-approve and delegate-revoke examples using createApproveInterfaceInstructions / createRevokeInterfaceInstructions - Add delegate-transfer example to payments spend-permissions - Remove stale create-token-pool instruction example - Update READMEs and package.json scripts Entire-Checkpoint: 4afa49be1970
1 parent 2b60ad8 commit d871e48

9 files changed

Lines changed: 201 additions & 46 deletions

File tree

toolkits/payments/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ Light Token reduces account creation cost by 200x compared to SPL. Transfer cost
5353
| [delegate-approve.ts](spend-permissions/delegate-approve.ts) | Let a delegate spend tokens on your behalf. | `approveInterface` |
5454
| [delegate-revoke.ts](spend-permissions/delegate-revoke.ts) | Revoke delegate access. | `revokeInterface` |
5555
| [delegate-check.ts](spend-permissions/delegate-check.ts) | Check current delegation status and remaining allowance. | `getAtaInterface` |
56+
| [delegate-transfer.ts](spend-permissions/delegate-transfer.ts) | Delegate transfers tokens on behalf of the owner. | `transferInterface` |
5657
| [delegate-full-flow.ts](spend-permissions/delegate-full-flow.ts) | Approve, check, and revoke in one script. | `approveInterface`, `revokeInterface`, `getAtaInterface` |
5758

5859
### Interop (wrap and unwrap)

toolkits/payments/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
"delegate-approve": "tsx spend-permissions/delegate-approve.ts",
2020
"delegate-revoke": "tsx spend-permissions/delegate-revoke.ts",
2121
"delegate-check": "tsx spend-permissions/delegate-check.ts",
22-
"delegate-full-flow": "tsx spend-permissions/delegate-full-flow.ts"
22+
"delegate-full-flow": "tsx spend-permissions/delegate-full-flow.ts",
23+
"delegate-transfer": "tsx spend-permissions/delegate-transfer.ts"
2324
},
2425
"dependencies": {
2526
"@lightprotocol/compressed-token": "^0.23.0-beta.10",
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { Keypair } from "@solana/web3.js";
2+
import {
3+
approveInterface,
4+
transferInterface,
5+
} from "@lightprotocol/compressed-token/unified";
6+
import { rpc, payer, setup } from "../setup.js";
7+
8+
(async function () {
9+
const { mint, senderAta } = await setup();
10+
11+
// Approve: grant delegate permission to spend up to 500,000 tokens
12+
const delegate = Keypair.generate();
13+
await approveInterface(
14+
rpc,
15+
payer,
16+
senderAta,
17+
mint,
18+
delegate.publicKey,
19+
500_000,
20+
payer
21+
);
22+
console.log("Approved delegate:", delegate.publicKey.toBase58());
23+
24+
// Delegate transfers tokens on behalf of the owner
25+
const recipient = Keypair.generate();
26+
const tx = await transferInterface(
27+
rpc,
28+
payer,
29+
senderAta,
30+
mint,
31+
recipient.publicKey,
32+
delegate,
33+
200_000,
34+
undefined,
35+
undefined,
36+
{ owner: payer.publicKey }
37+
);
38+
39+
console.log("Delegated transfer to:", recipient.publicKey.toBase58());
40+
console.log("Amount: 200,000 tokens");
41+
console.log("Tx:", tx);
42+
})();

typescript-client/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ TypeScript client examples for light-token-sdk.
2929
- **[transfer-interface](instructions/transfer-interface.ts)** - Build transfer instruction
3030
- **[wrap](instructions/wrap.ts)** - Wrap SPL/T22 to light-token
3131
- **[unwrap](instructions/unwrap.ts)** - Unwrap light-token to SPL/T22
32-
- **[create-token-pool](instructions/create-token-pool.ts)** - Create a token pool
32+
- **[delegate-approve](instructions/delegate-approve.ts)** - Build approve delegate instructions
33+
- **[delegate-revoke](instructions/delegate-revoke.ts)** - Build revoke delegate instructions
3334

3435
## Setup
3536

typescript-client/actions/delegate-transfer.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
} from "@lightprotocol/compressed-token";
99
import {
1010
approveInterface,
11-
transferDelegatedInterface,
11+
transferInterface,
1212
} from "@lightprotocol/compressed-token/unified";
1313
import { homedir } from "os";
1414
import { readFileSync } from "fs";
@@ -48,15 +48,17 @@ const payer = Keypair.fromSecretKey(
4848
console.log("Approved delegate:", delegate.publicKey.toBase58());
4949

5050
// Delegate transfers tokens on behalf of the owner
51-
const tx = await transferDelegatedInterface(
51+
const tx = await transferInterface(
5252
rpc,
5353
payer,
5454
senderAta,
5555
mint,
5656
recipient.publicKey,
5757
delegate,
58-
payer.publicKey,
59-
200_000
58+
200_000,
59+
undefined,
60+
undefined,
61+
{ owner: payer.publicKey }
6062
);
6163

6264
console.log("Delegated transfer:", tx);

typescript-client/instructions/create-token-pool.ts

Lines changed: 0 additions & 40 deletions
This file was deleted.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import "dotenv/config";
2+
import { Keypair, sendAndConfirmTransaction, Transaction } from "@solana/web3.js";
3+
import { createRpc } from "@lightprotocol/stateless.js";
4+
import {
5+
createMintInterface,
6+
createAtaInterface,
7+
mintToInterface,
8+
getAssociatedTokenAddressInterface,
9+
createApproveInterfaceInstructions,
10+
} from "@lightprotocol/compressed-token";
11+
import { homedir } from "os";
12+
import { readFileSync } from "fs";
13+
14+
// devnet:
15+
// const RPC_URL = `https://devnet.helius-rpc.com?api-key=${process.env.API_KEY!}`;
16+
// const rpc = createRpc(RPC_URL);
17+
// localnet:
18+
const rpc = createRpc();
19+
20+
const payer = Keypair.fromSecretKey(
21+
new Uint8Array(
22+
JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8"))
23+
)
24+
);
25+
26+
(async function () {
27+
const { mint } = await createMintInterface(rpc, payer, payer, null, 9);
28+
29+
const owner = Keypair.generate();
30+
await createAtaInterface(rpc, payer, mint, owner.publicKey);
31+
const ownerAta = getAssociatedTokenAddressInterface(mint, owner.publicKey);
32+
await mintToInterface(rpc, payer, mint, ownerAta, payer, 1_000_000_000);
33+
34+
const delegate = Keypair.generate();
35+
36+
// Build approve instruction batches.
37+
// Returns TransactionInstruction[][] — send [0..n-2] first (load batches),
38+
// then send [n-1] (the approve instruction).
39+
const batches = await createApproveInterfaceInstructions(
40+
rpc,
41+
payer.publicKey,
42+
mint,
43+
ownerAta,
44+
delegate.publicKey,
45+
500_000_000,
46+
owner.publicKey,
47+
9
48+
);
49+
50+
// Send load batches in parallel, then the final approve batch
51+
for (let i = 0; i < batches.length - 1; i++) {
52+
const tx = new Transaction().add(...batches[i]);
53+
await sendAndConfirmTransaction(rpc, tx, [payer, owner]);
54+
}
55+
56+
const approveTx = new Transaction().add(...batches[batches.length - 1]);
57+
const signature = await sendAndConfirmTransaction(rpc, approveTx, [
58+
payer,
59+
owner,
60+
]);
61+
62+
console.log("Approved delegate:", delegate.publicKey.toBase58());
63+
console.log("Allowance: 500,000,000 tokens");
64+
console.log("Tx:", signature);
65+
})();
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import "dotenv/config";
2+
import { Keypair, sendAndConfirmTransaction, Transaction } from "@solana/web3.js";
3+
import { createRpc } from "@lightprotocol/stateless.js";
4+
import {
5+
createMintInterface,
6+
createAtaInterface,
7+
mintToInterface,
8+
getAssociatedTokenAddressInterface,
9+
createApproveInterfaceInstructions,
10+
createRevokeInterfaceInstructions,
11+
} from "@lightprotocol/compressed-token";
12+
import { homedir } from "os";
13+
import { readFileSync } from "fs";
14+
15+
// devnet:
16+
// const RPC_URL = `https://devnet.helius-rpc.com?api-key=${process.env.API_KEY!}`;
17+
// const rpc = createRpc(RPC_URL);
18+
// localnet:
19+
const rpc = createRpc();
20+
21+
const payer = Keypair.fromSecretKey(
22+
new Uint8Array(
23+
JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8"))
24+
)
25+
);
26+
27+
(async function () {
28+
const { mint } = await createMintInterface(rpc, payer, payer, null, 9);
29+
30+
const owner = Keypair.generate();
31+
await createAtaInterface(rpc, payer, mint, owner.publicKey);
32+
const ownerAta = getAssociatedTokenAddressInterface(mint, owner.publicKey);
33+
await mintToInterface(rpc, payer, mint, ownerAta, payer, 1_000_000_000);
34+
35+
// Approve a delegate first (so we have something to revoke)
36+
const delegate = Keypair.generate();
37+
const approveBatches = await createApproveInterfaceInstructions(
38+
rpc,
39+
payer.publicKey,
40+
mint,
41+
ownerAta,
42+
delegate.publicKey,
43+
500_000_000,
44+
owner.publicKey,
45+
9
46+
);
47+
for (const batch of approveBatches) {
48+
const tx = new Transaction().add(...batch);
49+
await sendAndConfirmTransaction(rpc, tx, [payer, owner]);
50+
}
51+
console.log("Approved delegate:", delegate.publicKey.toBase58());
52+
53+
// Build revoke instruction batches.
54+
// Returns TransactionInstruction[][] — send [0..n-2] first (load batches),
55+
// then send [n-1] (the revoke instruction).
56+
const revokeBatches = await createRevokeInterfaceInstructions(
57+
rpc,
58+
payer.publicKey,
59+
mint,
60+
ownerAta,
61+
owner.publicKey,
62+
9
63+
);
64+
65+
for (let i = 0; i < revokeBatches.length - 1; i++) {
66+
const tx = new Transaction().add(...revokeBatches[i]);
67+
await sendAndConfirmTransaction(rpc, tx, [payer, owner]);
68+
}
69+
70+
const revokeTx = new Transaction().add(
71+
...revokeBatches[revokeBatches.length - 1]
72+
);
73+
const signature = await sendAndConfirmTransaction(rpc, revokeTx, [
74+
payer,
75+
owner,
76+
]);
77+
78+
console.log("Revoked all delegate permissions");
79+
console.log("Tx:", signature);
80+
})();

typescript-client/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242
"load-ata:instruction": "tsx instructions/load-ata.ts",
4343
"delegate:approve": "tsx actions/delegate-approve.ts",
4444
"delegate:revoke": "tsx actions/delegate-revoke.ts",
45+
"delegate:transfer": "tsx actions/delegate-transfer.ts",
46+
"delegate-approve:instruction": "tsx instructions/delegate-approve.ts",
47+
"delegate-revoke:instruction": "tsx instructions/delegate-revoke.ts",
4548
"merge-accounts": "tsx actions/merge-token-accounts.ts"
4649
}
4750
}

0 commit comments

Comments
 (0)