123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- import { Buffer } from 'node:buffer';
- import { describe, test } from 'node:test';
- import { PROGRAM_ID as TOKEN_METADATA_PROGRAM_ID } from '@metaplex-foundation/mpl-token-metadata';
- import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, getAssociatedTokenAddressSync } from '@solana/spl-token';
- import { Keypair, PublicKey, SYSVAR_RENT_PUBKEY, SystemProgram, Transaction, TransactionInstruction } from '@solana/web3.js';
- import { start } from 'solana-bankrun';
- import { CreateTokenArgs, MintToArgs, TransferTokensArgs } from './instructions';
- describe('Transferring Tokens', async () => {
- const PROGRAM_ID = new PublicKey('z7msBPQHDJjTvdQRoEcKyENgXDhSRYeHieN1ZMTqo35');
- const context = await start(
- [
- { name: 'transfer_tokens_program', programId: PROGRAM_ID },
- { name: 'token_metadata', programId: TOKEN_METADATA_PROGRAM_ID },
- ],
- [],
- );
- const client = context.banksClient;
- const payer = context.payer;
- const tokenMintKeypair: Keypair = Keypair.generate();
- const nftMintKeypair: Keypair = Keypair.generate();
- const recipientWallet = Keypair.generate();
- test('Create an SPL Token!', async () => {
- const metadataPDA = PublicKey.findProgramAddressSync(
- [Buffer.from('metadata'), TOKEN_METADATA_PROGRAM_ID.toBuffer(), tokenMintKeypair.publicKey.toBuffer()],
- TOKEN_METADATA_PROGRAM_ID,
- )[0];
- // SPL Token default = 9 decimals
- //
- const createArgs = new CreateTokenArgs(
- 'Solana Gold',
- 'GOLDSOL',
- 'https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/spl-token.json',
- 9,
- );
- const createTokenIx = new TransactionInstruction({
- keys: [
- { pubkey: payer.publicKey, isSigner: true, isWritable: true },
- {
- pubkey: tokenMintKeypair.publicKey,
- isSigner: true,
- isWritable: true,
- },
- { pubkey: metadataPDA, isSigner: false, isWritable: true },
- {
- pubkey: SystemProgram.programId,
- isSigner: false,
- isWritable: false,
- },
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
- {
- pubkey: TOKEN_METADATA_PROGRAM_ID,
- isSigner: false,
- isWritable: false,
- },
- { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
- ],
- programId: PROGRAM_ID,
- data: createArgs.toBuffer(),
- });
- const tx = new Transaction();
- const [blockhash, _] = await client.getLatestBlockhash();
- tx.recentBlockhash = blockhash;
- tx.add(createTokenIx).sign(payer, tokenMintKeypair);
- await client.processTransaction(tx);
- console.log('Success!');
- console.log(` Mint Address: ${tokenMintKeypair.publicKey}`);
- });
- test('Create an NFT!', async () => {
- const metadataPDA = PublicKey.findProgramAddressSync(
- [Buffer.from('metadata'), TOKEN_METADATA_PROGRAM_ID.toBuffer(), nftMintKeypair.publicKey.toBuffer()],
- TOKEN_METADATA_PROGRAM_ID,
- )[0];
- // NFT default = 0 decimals
- //
- const createArgs = new CreateTokenArgs(
- 'Homer NFT',
- 'HOMR',
- 'https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/nft.json',
- 0,
- );
- const createTokenIx = new TransactionInstruction({
- keys: [
- { pubkey: payer.publicKey, isSigner: true, isWritable: true },
- { pubkey: nftMintKeypair.publicKey, isSigner: true, isWritable: true },
- { pubkey: metadataPDA, isSigner: false, isWritable: true },
- {
- pubkey: SystemProgram.programId,
- isSigner: false,
- isWritable: false,
- },
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
- {
- pubkey: TOKEN_METADATA_PROGRAM_ID,
- isSigner: false,
- isWritable: false,
- },
- { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
- ],
- programId: PROGRAM_ID,
- data: createArgs.toBuffer(),
- });
- const tx = new Transaction();
- const [blockhash, _] = await client.getLatestBlockhash();
- tx.recentBlockhash = blockhash;
- tx.add(createTokenIx).sign(payer, nftMintKeypair);
- await client.processTransaction(tx);
- console.log('Success!');
- console.log(` Mint Address: ${nftMintKeypair.publicKey}`);
- });
- test('Mint some tokens to your wallet!', async () => {
- const recipientATA = getAssociatedTokenAddressSync(tokenMintKeypair.publicKey, payer.publicKey);
- const mintArgs = new MintToArgs(100);
- const mintToIx = new TransactionInstruction({
- keys: [
- { pubkey: payer.publicKey, isSigner: true, isWritable: true }, // mint_authority
- { pubkey: payer.publicKey, isSigner: false, isWritable: false }, // recipient
- {
- pubkey: tokenMintKeypair.publicKey,
- isSigner: false,
- isWritable: true,
- }, // mint_pda must be writable
- { pubkey: recipientATA, isSigner: false, isWritable: true }, // associated_token_account must be writable
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, // spl_token::ID
- {
- pubkey: ASSOCIATED_TOKEN_PROGRAM_ID,
- isSigner: false,
- isWritable: false,
- }, // spl_associated_token_account::ID
- {
- pubkey: SystemProgram.programId,
- isSigner: false,
- isWritable: false,
- }, // system_program::ID
- ],
- programId: PROGRAM_ID,
- data: mintArgs.toBuffer(),
- });
- const tx = new Transaction();
- const [blockhash, _] = await client.getLatestBlockhash();
- tx.recentBlockhash = blockhash;
- tx.add(mintToIx).sign(payer);
- await client.processTransaction(tx);
- console.log('Success!');
- console.log(` ATA Address: ${recipientATA}`);
- });
- test('Transfer tokens to another wallet!', async () => {
- const fromAssociatedTokenAddress = getAssociatedTokenAddressSync(tokenMintKeypair.publicKey, payer.publicKey);
- console.log(`Owner Token Address: ${fromAssociatedTokenAddress}`);
- const toAssociatedTokenAddress = getAssociatedTokenAddressSync(tokenMintKeypair.publicKey, recipientWallet.publicKey);
- console.log(`Recipient Token Address: ${toAssociatedTokenAddress}`);
- const transferArgs = new TransferTokensArgs(15);
- const transferTokensIx = new TransactionInstruction({
- keys: [
- { pubkey: payer.publicKey, isSigner: true, isWritable: true }, // Owner
- { pubkey: recipientWallet.publicKey, isSigner: true, isWritable: true }, // Recipient
- {
- pubkey: tokenMintKeypair.publicKey,
- isSigner: false,
- isWritable: true,
- }, // Mint account
- {
- pubkey: fromAssociatedTokenAddress,
- isSigner: false,
- isWritable: true,
- }, // Owner Token account
- { pubkey: toAssociatedTokenAddress, isSigner: false, isWritable: true }, // Recipient Token account
- // { pubkey: payer.publicKey, isSigner: true, isWritable: true }, // Payer
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, // Token program
- {
- pubkey: ASSOCIATED_TOKEN_PROGRAM_ID,
- isSigner: false,
- isWritable: false,
- }, // Associated token program
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, // System program
- ],
- programId: PROGRAM_ID,
- data: transferArgs.toBuffer(),
- });
- const tx = new Transaction();
- const [blockhash, _] = await client.getLatestBlockhash();
- tx.recentBlockhash = blockhash;
- tx.add(transferTokensIx).sign(payer, recipientWallet);
- await client.processTransaction(tx);
- });
- });
|