@unclaimedsol/spl-burn-close-sdk 1.2.0 โ†’ 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,6 +9,7 @@ This library only **builds unsigned transactions** โ€“ you handle signing and se
9
9
  - ๐Ÿงน Close token accounts, reclaiming rent to the user.
10
10
  - ๐Ÿ’ธ Automatic 5% protocol fee (hardcoded in program).
11
11
  - โšก Automatic batching (default 12 ATAs per transaction).
12
+ - ๐Ÿช™ Supports SPL Token and Token-2022.
12
13
  - ๐Ÿ” Supports **frontend partial signing** and **backend full signing** workflows.
13
14
  - ๐Ÿš€ No hidden config: single function to integrate.
14
15
 
@@ -29,7 +30,7 @@ This library only **builds unsigned transactions** โ€“ you handle signing and se
29
30
  npm i @unclaimedsol/spl-burn-close-sdk
30
31
  ```
31
32
 
32
- We use @solana/web3.js in peerDependencies to avoid version conflicts. So, make sure you already have it installed.
33
+ We use @solana/web3.js in peerDependencies to avoid version conflicts, so make sure you already have it installed.
33
34
 
34
35
  Requires Node 18+.
35
36
 
@@ -40,7 +41,7 @@ Requires Node 18+.
40
41
  ### Signing with Keypair
41
42
 
42
43
  ```typescript
43
- import { Connection, Keypair } from "@solana/web3.js";
44
+ import { Connection, Keypair, PublicKey } from "@solana/web3.js";
44
45
  import {
45
46
  buildBurnAndCloseTransactions,
46
47
  PROGRAM_ID,
@@ -82,6 +83,7 @@ import { Connection, PublicKey } from "@solana/web3.js";
82
83
  import {
83
84
  buildBurnAndCloseTransactions,
84
85
  PROGRAM_ID,
86
+ TOKEN_2022_PROGRAM_ID,
85
87
  } from "@unclaimedsol/spl-burn-close-sdk";
86
88
 
87
89
  const connection = new Connection("https://api.mainnet-beta.solana.com");
@@ -100,6 +102,16 @@ const txs = await buildBurnAndCloseTransactions(
100
102
  pairs
101
103
  );
102
104
 
105
+ // For Token-2022 accounts, pass TOKEN_2022_PROGRAM_ID and consider using a smaller chunkSize:
106
+ // const txs = await buildBurnAndCloseTransactions(
107
+ // connection,
108
+ // PROGRAM_ID,
109
+ // user,
110
+ // pairs,
111
+ // { chunkSize: 2 },
112
+ // TOKEN_2022_PROGRAM_ID
113
+ // );
114
+
103
115
  // Sign
104
116
  const signed = wallet.signAllTransactions
105
117
  ? await wallet.signAllTransactions(txs)
@@ -107,7 +119,7 @@ const signed = wallet.signAllTransactions
107
119
 
108
120
  // Send
109
121
  for (const stx of signed) {
110
- const sig = await connection.sendRawTransaction(tx.serialize());
122
+ const sig = await connection.sendRawTransaction(stx.serialize());
111
123
  let latestBlockhash = await connection.getLatestBlockhash(
112
124
  connection.commitment
113
125
  );
@@ -122,6 +134,13 @@ for (const stx of signed) {
122
134
 
123
135
  ---
124
136
 
137
+ ## ๐ŸŒ Cluster support
138
+
139
+ This SDK targets the Unclaimed SOL mainnet program (`PROGRAM_ID`) and fee recipient (`FEE_RECIPIENT`).
140
+ Transactions will only succeed on a cluster where that program is deployed.
141
+
142
+ ---
143
+
125
144
  ## ๐Ÿ’ป Demo
126
145
 
127
146
  There is a nice tutorial guide with a demo repository that shows the usage of the SDK to burn and close all token accounts for the wallet. You can find it [here](https://blog.unclaimedsol.com/close-burn-solana-tokens-web3js-sdk/).
package/dist/index.cjs CHANGED
@@ -1,9 +1,15 @@
1
- import { PublicKey, SystemProgram, Transaction, TransactionInstruction, } from "@solana/web3.js";
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TOKEN_2022_PROGRAM_ID = exports.TOKEN_PROGRAM_ID = exports.FEE_RECIPIENT = exports.PROGRAM_ID = void 0;
4
+ exports.buildBurnAndCloseTransactions = buildBurnAndCloseTransactions;
5
+ exports.buildBurnAndCloseInstruction = buildBurnAndCloseInstruction;
6
+ const web3_js_1 = require("@solana/web3.js");
2
7
  /** Exporting on-chain program ID for convenience */
3
- const PROGRAM_ID = new PublicKey("UNCaXzXkR3vp8mbCJyxWUvwuRk5uHgzrwe6jcWPfiUR");
8
+ exports.PROGRAM_ID = new web3_js_1.PublicKey("UNCaXzXkR3vp8mbCJyxWUvwuRk5uHgzrwe6jcWPfiUR");
4
9
  /** Hardcoded fee recipient on-chain expectation */
5
- const FEE_RECIPIENT = new PublicKey("uncNCRycMtNPj2kXHfwiCgNrzCTnC9xU5FS8ZeWyn3M");
6
- const TOKEN_PROGRAM_ID = new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
10
+ exports.FEE_RECIPIENT = new web3_js_1.PublicKey("uncNCRycMtNPj2kXHfwiCgNrzCTnC9xU5FS8ZeWyn3M");
11
+ exports.TOKEN_PROGRAM_ID = new web3_js_1.PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
12
+ exports.TOKEN_2022_PROGRAM_ID = new web3_js_1.PublicKey("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb");
7
13
  /**
8
14
  * Build *unsigned* transactions that call the on-chain burn+close program.
9
15
  * You sign and send them yourself (frontend wallet or backend keypair).
@@ -16,11 +22,11 @@ const TOKEN_PROGRAM_ID = new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ
16
22
  * @param tokenProgramId Support for multiple Token programs
17
23
  * @returns Array of *unsigned* Transaction objects
18
24
  */
19
- export async function buildBurnAndCloseTransactions(connection, programId, user, pairs, options = {}, tokenProgramId = TOKEN_PROGRAM_ID) {
25
+ async function buildBurnAndCloseTransactions(connection, programId, user, pairs, options = {}, tokenProgramId = exports.TOKEN_PROGRAM_ID) {
20
26
  if (!pairs.length)
21
27
  return [];
22
28
  const chunkSize = Math.max(1, options.chunkSize ?? 12);
23
- const commitment = options.commitment ?? "processed";
29
+ const commitment = options.commitment ?? "confirmed";
24
30
  const feePayer = options.feePayer ?? user;
25
31
  // Split into chunks so we stay under CU / account limits
26
32
  const chunks = [];
@@ -28,35 +34,31 @@ export async function buildBurnAndCloseTransactions(connection, programId, user,
28
34
  chunks.push(pairs.slice(i, i + chunkSize));
29
35
  }
30
36
  // Instruction data: [selector=0]
31
- const data = Buffer.from([0]);
37
+ // Use Uint8Array (browser-safe) and cast for web3.js' Buffer typing.
38
+ const data = new Uint8Array([0]);
39
+ const recentBlockhash = options.recentBlockhash ??
40
+ (await connection.getLatestBlockhash({ commitment })).blockhash;
32
41
  const txs = [];
33
42
  for (const chunk of chunks) {
34
43
  const keys = [
35
44
  // NOTE: Mark the user as signer in the instruction meta;
36
45
  // the caller must actually sign the Transaction later.
37
- { pubkey: FEE_RECIPIENT, isSigner: false, isWritable: true },
46
+ { pubkey: exports.FEE_RECIPIENT, isSigner: false, isWritable: true },
38
47
  { pubkey: user, isSigner: true, isWritable: true },
39
48
  { pubkey: tokenProgramId, isSigner: false, isWritable: false },
40
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
49
+ { pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
41
50
  ];
42
51
  for (const { mint, ata } of chunk) {
43
52
  keys.push({ pubkey: mint, isSigner: false, isWritable: true }, { pubkey: ata, isSigner: false, isWritable: true });
44
53
  }
45
- const ix = new TransactionInstruction({
54
+ const ix = new web3_js_1.TransactionInstruction({
46
55
  programId,
47
56
  keys,
48
57
  data,
49
58
  });
50
- const tx = new Transaction().add(ix);
59
+ const tx = new web3_js_1.Transaction().add(ix);
51
60
  tx.feePayer = feePayer;
52
- // Use provided blockhash or fetch one
53
- if (options.recentBlockhash) {
54
- tx.recentBlockhash = options.recentBlockhash;
55
- }
56
- else {
57
- const { blockhash } = await connection.getLatestBlockhash({ commitment });
58
- tx.recentBlockhash = blockhash;
59
- }
61
+ tx.recentBlockhash = recentBlockhash;
60
62
  txs.push(tx);
61
63
  }
62
64
  return txs;
@@ -69,28 +71,28 @@ export async function buildBurnAndCloseTransactions(connection, programId, user,
69
71
  * create or sign full transactions โ€” it only constructs one
70
72
  * instruction for a batch of (mint, ATA) pairs.
71
73
  */
72
- export async function buildBurnAndCloseInstruction(programId, user, pairs, tokenProgramId) {
74
+ async function buildBurnAndCloseInstruction(programId, user, pairs, tokenProgramId) {
73
75
  if (!pairs.length) {
74
76
  return null;
75
77
  }
76
78
  // instruction data selector: 0 = burn_and_close_token_accounts
77
- const data = Buffer.from([0]);
79
+ const data = new Uint8Array([0]);
78
80
  // accounts order MUST match the on-chain program's expectation:
79
- // [0] fee_payer_account (your fee recipient)
81
+ // [0] fee_recipient_account (your fee recipient)
80
82
  // [1] user_wallet_account (the signer)
81
83
  // [2] token_program_account (SPL Token program or Token-2022 program)
82
84
  // [3] system_program_account
83
85
  // then repeating (mint, ata) pairs, both writable
84
86
  const keys = [
85
- { pubkey: FEE_RECIPIENT, isSigner: false, isWritable: true },
87
+ { pubkey: exports.FEE_RECIPIENT, isSigner: false, isWritable: true },
86
88
  { pubkey: user, isSigner: true, isWritable: true },
87
89
  { pubkey: tokenProgramId, isSigner: false, isWritable: false },
88
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
90
+ { pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
89
91
  ];
90
92
  for (const { mint, ata } of pairs) {
91
93
  keys.push({ pubkey: mint, isSigner: false, isWritable: true }, { pubkey: ata, isSigner: false, isWritable: true });
92
94
  }
93
- return new TransactionInstruction({
95
+ return new web3_js_1.TransactionInstruction({
94
96
  programId,
95
97
  keys,
96
98
  data,
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export declare const PROGRAM_ID: PublicKey;
4
4
  /** Hardcoded fee recipient on-chain expectation */
5
5
  export declare const FEE_RECIPIENT: PublicKey;
6
6
  export declare const TOKEN_PROGRAM_ID: PublicKey;
7
+ export declare const TOKEN_2022_PROGRAM_ID: PublicKey;
7
8
  export type Pair = {
8
9
  mint: PublicKey;
9
10
  ata: PublicKey;
@@ -20,7 +21,7 @@ export type BuildOptions = {
20
21
  feePayer?: PublicKey;
21
22
  /**
22
23
  * Provide your own recent blockhash (advanced). If omitted,
23
- * we fetch a fresh one per transaction.
24
+ * we fetch a fresh one and reuse it for all built transactions.
24
25
  */
25
26
  recentBlockhash?: string;
26
27
  };
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ export const PROGRAM_ID = new PublicKey("UNCaXzXkR3vp8mbCJyxWUvwuRk5uHgzrwe6jcWP
4
4
  /** Hardcoded fee recipient on-chain expectation */
5
5
  export const FEE_RECIPIENT = new PublicKey("uncNCRycMtNPj2kXHfwiCgNrzCTnC9xU5FS8ZeWyn3M");
6
6
  export const TOKEN_PROGRAM_ID = new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
7
+ export const TOKEN_2022_PROGRAM_ID = new PublicKey("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb");
7
8
  /**
8
9
  * Build *unsigned* transactions that call the on-chain burn+close program.
9
10
  * You sign and send them yourself (frontend wallet or backend keypair).
@@ -20,7 +21,7 @@ export async function buildBurnAndCloseTransactions(connection, programId, user,
20
21
  if (!pairs.length)
21
22
  return [];
22
23
  const chunkSize = Math.max(1, options.chunkSize ?? 12);
23
- const commitment = options.commitment ?? "processed";
24
+ const commitment = options.commitment ?? "confirmed";
24
25
  const feePayer = options.feePayer ?? user;
25
26
  // Split into chunks so we stay under CU / account limits
26
27
  const chunks = [];
@@ -28,7 +29,10 @@ export async function buildBurnAndCloseTransactions(connection, programId, user,
28
29
  chunks.push(pairs.slice(i, i + chunkSize));
29
30
  }
30
31
  // Instruction data: [selector=0]
31
- const data = Buffer.from([0]);
32
+ // Use Uint8Array (browser-safe) and cast for web3.js' Buffer typing.
33
+ const data = new Uint8Array([0]);
34
+ const recentBlockhash = options.recentBlockhash ??
35
+ (await connection.getLatestBlockhash({ commitment })).blockhash;
32
36
  const txs = [];
33
37
  for (const chunk of chunks) {
34
38
  const keys = [
@@ -49,14 +53,7 @@ export async function buildBurnAndCloseTransactions(connection, programId, user,
49
53
  });
50
54
  const tx = new Transaction().add(ix);
51
55
  tx.feePayer = feePayer;
52
- // Use provided blockhash or fetch one
53
- if (options.recentBlockhash) {
54
- tx.recentBlockhash = options.recentBlockhash;
55
- }
56
- else {
57
- const { blockhash } = await connection.getLatestBlockhash({ commitment });
58
- tx.recentBlockhash = blockhash;
59
- }
56
+ tx.recentBlockhash = recentBlockhash;
60
57
  txs.push(tx);
61
58
  }
62
59
  return txs;
@@ -74,9 +71,9 @@ export async function buildBurnAndCloseInstruction(programId, user, pairs, token
74
71
  return null;
75
72
  }
76
73
  // instruction data selector: 0 = burn_and_close_token_accounts
77
- const data = Buffer.from([0]);
74
+ const data = new Uint8Array([0]);
78
75
  // accounts order MUST match the on-chain program's expectation:
79
- // [0] fee_payer_account (your fee recipient)
76
+ // [0] fee_recipient_account (your fee recipient)
80
77
  // [1] user_wallet_account (the signer)
81
78
  // [2] token_program_account (SPL Token program or Token-2022 program)
82
79
  // [3] system_program_account
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unclaimedsol/spl-burn-close-sdk",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "SDK to burn and close SPL token accounts via the Unclaimed SOL program (with a built-in 5% fee).",
5
5
  "license": "MIT",
6
6
  "author": "Unclaimed SOL",
@@ -28,13 +28,14 @@
28
28
  "README.md"
29
29
  ],
30
30
  "scripts": {
31
- "build": "tsc -p tsconfig.json && node ./scripts/build-cjs.js",
31
+ "build": "tsc -p tsconfig.json && tsc -p tsconfig.cjs.json && node ./scripts/build-cjs.js",
32
32
  "prepublishOnly": "npm run build"
33
33
  },
34
- "dependencies": {
34
+ "peerDependencies": {
35
35
  "@solana/web3.js": "^1.98.4"
36
36
  },
37
37
  "devDependencies": {
38
+ "@solana/web3.js": "^1.98.4",
38
39
  "typescript": "^5.6.3"
39
40
  },
40
41
  "engines": {