Create an SPL interface (omnibus account) for an existing SPL mint. createSplInterface() requires only fee_payer and has no mint authority constraint.
The SPL Interface PDA requires rent; individual compressed token accounts are rent-free.
function-create-token-pool.ts
// Creates SPL interface (omnibus account) for existing SPL mint
const transactionSignature = await createSplInterface (
rpc ,
payer ,
mint ,
);
Best Practice: Each mint supports up to 4 SPL interfaces. During compression/decompression, SPL Interface PDAs get write-locked. Use addTokenPools() to create additional interfaces and increase per-block write-lock capacity.
Get Started
Create SPL interface
Install packages in your working directory: npm install @lightprotocol/stateless.js@beta \
@lightprotocol/compressed-token@beta
Install the CLI globally: npm install -g @lightprotocol/zk-compression-cli@beta
Install packages in your working directory: yarn add @lightprotocol/stateless.js@beta \
@lightprotocol/compressed-token@beta
Install the CLI globally: yarn global add @lightprotocol/zk-compression-cli@beta
Install packages in your working directory: pnpm add @lightprotocol/stateless.js@beta \
@lightprotocol/compressed-token@beta
Install the CLI globally: pnpm add -g @lightprotocol/zk-compression-cli@beta
# start local test-validator in a separate terminal
light test-validator
In the code examples, use createRpc() without arguments for localnet.
Get an API key from Helius and add to .env: API_KEY =< your-helius-api-key >
In the code examples, use createRpc(RPC_URL) with the devnet URL.
import "dotenv/config" ;
import { Keypair , PublicKey } from "@solana/web3.js" ;
import { createRpc } from "@lightprotocol/stateless.js" ;
import { createSplInterface } from "@lightprotocol/compressed-token" ;
import { createMint as createSplMint , TOKEN_PROGRAM_ID } from "@solana/spl-token" ;
import { homedir } from "os" ;
import { readFileSync } from "fs" ;
// devnet:
const RPC_URL = `https://devnet.helius-rpc.com?api-key= ${ process . env . API_KEY ! } ` ;
// localnet:
// const RPC_URL = undefined;
const payer = Keypair . fromSecretKey (
new Uint8Array (
JSON . parse ( readFileSync ( ` ${ homedir () } /.config/solana/id.json` , "utf8" ))
)
);
( async function () {
// devnet:
const rpc = createRpc ( RPC_URL );
// localnet:
// const rpc = createRpc();
// Setup: Create existing SPL mint
const mintKeypair = Keypair . generate ();
await createSplMint ( rpc , payer , payer . publicKey , null , 9 , mintKeypair , undefined , TOKEN_PROGRAM_ID );
// Create SPL interface for existing mint
const tx = await createSplInterface ( rpc , payer , mintKeypair . publicKey );
console . log ( "Mint:" , mintKeypair . publicKey . toBase58 ());
console . log ( "Tx:" , tx );
})();
Troubleshooting
The mint has no SPL Interface PDA. const poolTx = await createSplInterface ( rpc , payer , mint );
console . log ( "SPL interface created:" , poolTx );
Advanced Configuration
Batch SPL interface creation
Create SPL interfaces for multiple mints: const mints = [
new PublicKey ( "MINT_1_ADDRESS" ),
new PublicKey ( "MINT_2_ADDRESS" ),
new PublicKey ( "MINT_3_ADDRESS" ),
];
for ( const mint of mints ) {
try {
const poolTx = await createSplInterface ( rpc , payer , mint );
console . log ( `SPL interface created for ${ mint . toBase58 () } :` , poolTx );
} catch ( error ) {
console . log ( `Failed for ${ mint . toBase58 () } :` , error . message );
}
}
Create SPL interface for Token-2022 mints: import { TOKEN_2022_PROGRAM_ID } from '@solana/spl-token' ;
const poolTx = await createSplInterface (
rpc ,
payer ,
mint , // Token-2022 mint
undefined ,
TOKEN_2022_PROGRAM_ID ,
);
Next Steps
How to Merge Compressed Token Accounts