I've been looking for examples of people using @solana/spl-token in the browser by bundling it with browserify or rollup or webpack but haven't been able to get any of them to work. I'm not convinced I need @solana/spl-token library but when I try to create a transfer instruction myself (using the web3.js package) it gets rejected.

/* setup connection, connect to phantom wallet, set up the variables for wallet keypairs and the mint address ... can assure you there is no issue with any of this 
// ... 
// ...

empty_transaction.feePayer = window.solana.publicKey;

const instruction = new solanaWeb3.TransactionInstruction({
    keys: [
        { pubkey: source, isSigner: false, isWritable: true }, // Source account
        { pubkey: destination, isSigner: false, isWritable: true }, // Destination account
        { pubkey: owner, isSigner: true, isWritable: true }, 
    programId: token_program_id,
    data: new Uint8Array([3, 255, 255, 255, 255, 0, 0, 0, 0]),

// add the instruction

const blockhashInfo = await clusterConnection.getRecentBlockhash();

const recentBlockhash = blockhashInfo.blockhash;

empty_transaction.recentBlockhash = recentBlockhash;

await empty_transaction.partialSign(signingKeypair);

console.log("everything up until here works, sendAndConfirmTransaction throws an error")
await solanaWeb3.sendAndConfirmTransaction(clusterConnection, empty_transaction, [signingKeypair]);

So I'm asking for anyone with a working example of executing a transfer of spl tokens client side, I don't care how it's done whether you use web3 and build the instruction or spl-token and let the library handle everything, as long as it works. All the recommendations to browserify do not work, if you've been able to browserify spl-token please tell me how you did it. I'm pulling my hair out.

1 Answer 1


Sorry to hear that you've been having issues with the spl-token JS package.

Your approach here is correct overall, you need to sign the transaction with owner though.

And this won't impact the correctness, but you should pass the owner account as isWritable: false.

After that, perhaps there's something wrong with the source or destination accounts (ie not initialized to the correct mint, not enough tokens)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.