123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- import { Buffer } from 'node:buffer';
- import { PROGRAM_ID as TOKEN_METADATA_PROGRAM_ID } from '@metaplex-foundation/mpl-token-metadata';
- import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, getAssociatedTokenAddress } from '@solana/spl-token';
- import {
- Connection,
- Keypair,
- PublicKey,
- SYSVAR_RENT_PUBKEY,
- SystemProgram,
- Transaction,
- TransactionInstruction,
- sendAndConfirmTransaction,
- } from '@solana/web3.js';
- import { BN } from 'bn.js';
- import { CreateTokenArgs, MintNftArgs, MintSplArgs, MyInstruction, TransferTokensArgs } from './instructions';
- function createKeypairFromFile(path: string): Keypair {
- return Keypair.fromSecretKey(Buffer.from(JSON.parse(require('node:fs').readFileSync(path, 'utf-8'))));
- }
- describe('Transferring Tokens', async () => {
- // const connection = new Connection(`http://localhost:8899`, 'confirmed');
- const connection = new Connection('https://api.devnet.solana.com/', 'confirmed');
- const payer = createKeypairFromFile(`${require('node:os').homedir()}/.config/solana/id.json`);
- const program = createKeypairFromFile('./program/target/deploy/program-keypair.json');
- const tokenMintKeypair: Keypair = Keypair.generate();
- const nftMintKeypair: Keypair = Keypair.generate();
- const recipientWallet = Keypair.generate();
- it('Create an SPL Token!', async () => {
- const metadataAddress = PublicKey.findProgramAddressSync(
- [Buffer.from('metadata'), TOKEN_METADATA_PROGRAM_ID.toBuffer(), tokenMintKeypair.publicKey.toBuffer()],
- TOKEN_METADATA_PROGRAM_ID,
- )[0];
- const instructionData = new CreateTokenArgs({
- instruction: MyInstruction.Create,
- token_title: 'Solana Gold',
- token_symbol: 'GOLDSOL',
- token_uri: 'https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/spl-token.json',
- decimals: 9,
- });
- const ix = new TransactionInstruction({
- keys: [
- {
- pubkey: tokenMintKeypair.publicKey,
- isSigner: true,
- isWritable: true,
- }, // Mint account
- { pubkey: payer.publicKey, isSigner: false, isWritable: true }, // Mint authority account
- { pubkey: metadataAddress, isSigner: false, isWritable: true }, // Metadata account
- { pubkey: payer.publicKey, isSigner: true, isWritable: true }, // Payer
- { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false }, // Rent account
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, // System program
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, // Token program
- {
- pubkey: TOKEN_METADATA_PROGRAM_ID,
- isSigner: false,
- isWritable: false,
- }, // Token metadata program
- ],
- programId: program.publicKey,
- data: instructionData.toBuffer(),
- });
- const sx = await sendAndConfirmTransaction(connection, new Transaction().add(ix), [payer, tokenMintKeypair]);
- console.log('Success!');
- console.log(` Mint Address: ${tokenMintKeypair.publicKey}`);
- console.log(` Tx Signature: ${sx}`);
- });
- it('Create an NFT!', async () => {
- const metadataAddress = PublicKey.findProgramAddressSync(
- [Buffer.from('metadata'), TOKEN_METADATA_PROGRAM_ID.toBuffer(), nftMintKeypair.publicKey.toBuffer()],
- TOKEN_METADATA_PROGRAM_ID,
- )[0];
- const instructionData = new CreateTokenArgs({
- instruction: MyInstruction.Create,
- token_title: 'Homer NFT',
- token_symbol: 'HOMR',
- token_uri: 'https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/nft.json',
- decimals: 0,
- });
- const ix = new TransactionInstruction({
- keys: [
- { pubkey: nftMintKeypair.publicKey, isSigner: true, isWritable: true }, // Mint account
- { pubkey: payer.publicKey, isSigner: false, isWritable: true }, // Mint authority account
- { pubkey: metadataAddress, isSigner: false, isWritable: true }, // Metadata account
- { pubkey: payer.publicKey, isSigner: true, isWritable: true }, // Payer
- { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false }, // Rent account
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, // System program
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, // Token program
- {
- pubkey: TOKEN_METADATA_PROGRAM_ID,
- isSigner: false,
- isWritable: false,
- }, // Token metadata program
- ],
- programId: program.publicKey,
- data: instructionData.toBuffer(),
- });
- const sx = await sendAndConfirmTransaction(connection, new Transaction().add(ix), [payer, nftMintKeypair]);
- console.log('Success!');
- console.log(` Mint Address: ${nftMintKeypair.publicKey}`);
- console.log(` Tx Signature: ${sx}`);
- });
- it('Mint some tokens to your wallet!', async () => {
- const associatedTokenAccountAddress = await getAssociatedTokenAddress(tokenMintKeypair.publicKey, payer.publicKey);
- const instructionData = new MintSplArgs({
- instruction: MyInstruction.MintSpl,
- quantity: new BN(150),
- });
- const ix = new TransactionInstruction({
- keys: [
- {
- pubkey: tokenMintKeypair.publicKey,
- isSigner: false,
- isWritable: true,
- }, // Mint account
- { pubkey: payer.publicKey, isSigner: false, isWritable: true }, // Mint authority account
- {
- pubkey: associatedTokenAccountAddress,
- isSigner: false,
- isWritable: true,
- }, // ATA
- { pubkey: payer.publicKey, isSigner: true, isWritable: true }, // Payer
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: true }, // System program
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, // Token program
- {
- pubkey: ASSOCIATED_TOKEN_PROGRAM_ID,
- isSigner: false,
- isWritable: false,
- }, // Token metadata program
- ],
- programId: program.publicKey,
- data: instructionData.toBuffer(),
- });
- const sx = await sendAndConfirmTransaction(connection, new Transaction().add(ix), [payer]);
- console.log('Success!');
- console.log(` ATA Address: ${associatedTokenAccountAddress}`);
- console.log(` Tx Signature: ${sx}`);
- });
- it('Mint the NFT to your wallet!', async () => {
- const metadataAddress = PublicKey.findProgramAddressSync(
- [Buffer.from('metadata'), TOKEN_METADATA_PROGRAM_ID.toBuffer(), nftMintKeypair.publicKey.toBuffer()],
- TOKEN_METADATA_PROGRAM_ID,
- )[0];
- const editionAddress = PublicKey.findProgramAddressSync(
- [Buffer.from('metadata'), TOKEN_METADATA_PROGRAM_ID.toBuffer(), nftMintKeypair.publicKey.toBuffer(), Buffer.from('edition')],
- TOKEN_METADATA_PROGRAM_ID,
- )[0];
- const associatedTokenAccountAddress = await getAssociatedTokenAddress(nftMintKeypair.publicKey, payer.publicKey);
- const instructionData = new MintNftArgs({
- instruction: MyInstruction.MintNft,
- });
- const ix = new TransactionInstruction({
- keys: [
- { pubkey: nftMintKeypair.publicKey, isSigner: false, isWritable: true }, // Mint account
- { pubkey: metadataAddress, isSigner: false, isWritable: true }, // Metadata account
- { pubkey: editionAddress, isSigner: false, isWritable: true }, // Edition account
- { pubkey: payer.publicKey, isSigner: false, isWritable: true }, // Mint authority account
- {
- pubkey: associatedTokenAccountAddress,
- isSigner: false,
- isWritable: true,
- }, // ATA
- { pubkey: payer.publicKey, isSigner: true, isWritable: true }, // Payer
- { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false }, // Rent account
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, // System program
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, // Token program
- {
- pubkey: ASSOCIATED_TOKEN_PROGRAM_ID,
- isSigner: false,
- isWritable: false,
- }, // Associated token program
- {
- pubkey: TOKEN_METADATA_PROGRAM_ID,
- isSigner: false,
- isWritable: false,
- }, // Token metadata program
- ],
- programId: program.publicKey,
- data: instructionData.toBuffer(),
- });
- const sx = await sendAndConfirmTransaction(connection, new Transaction().add(ix), [payer]);
- console.log('Success!');
- console.log(` ATA Address: ${associatedTokenAccountAddress}`);
- console.log(` Tx Signature: ${sx}`);
- });
- it('Prep a new test wallet for transfers', async () => {
- await connection.confirmTransaction(
- await connection.requestAirdrop(recipientWallet.publicKey, await connection.getMinimumBalanceForRentExemption(0)),
- );
- console.log(`Recipient Pubkey: ${recipientWallet.publicKey}`);
- });
- it('Transfer tokens to another wallet!', async () => {
- const fromAssociatedTokenAddress = await getAssociatedTokenAddress(tokenMintKeypair.publicKey, payer.publicKey);
- console.log(`Owner Token Address: ${fromAssociatedTokenAddress}`);
- const toAssociatedTokenAddress = await getAssociatedTokenAddress(tokenMintKeypair.publicKey, recipientWallet.publicKey);
- console.log(`Recipient Token Address: ${toAssociatedTokenAddress}`);
- const transferToInstructionData = new TransferTokensArgs({
- instruction: MyInstruction.TransferTokens,
- quantity: new BN(15),
- });
- const ix = new TransactionInstruction({
- keys: [
- {
- 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 }, // Owner
- { pubkey: recipientWallet.publicKey, isSigner: true, isWritable: true }, // Recipient
- { pubkey: payer.publicKey, isSigner: true, isWritable: true }, // Payer
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, // System program
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, // Token program
- {
- pubkey: ASSOCIATED_TOKEN_PROGRAM_ID,
- isSigner: false,
- isWritable: false,
- }, // Associated token program
- ],
- programId: program.publicKey,
- data: transferToInstructionData.toBuffer(),
- });
- await sendAndConfirmTransaction(connection, new Transaction().add(ix), [payer, recipientWallet], { skipPreflight: true });
- });
- it('Transfer NFT to another wallet!', async () => {
- const fromAssociatedTokenAddress = await getAssociatedTokenAddress(nftMintKeypair.publicKey, payer.publicKey);
- console.log(`Owner Token Address: ${fromAssociatedTokenAddress}`);
- const toAssociatedTokenAddress = await getAssociatedTokenAddress(nftMintKeypair.publicKey, recipientWallet.publicKey);
- console.log(`Recipient Token Address: ${toAssociatedTokenAddress}`);
- const transferToInstructionData = new TransferTokensArgs({
- instruction: MyInstruction.TransferTokens,
- quantity: new BN(1),
- });
- const ix = new TransactionInstruction({
- keys: [
- { pubkey: nftMintKeypair.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 }, // Owner
- { pubkey: recipientWallet.publicKey, isSigner: true, isWritable: true }, // Recipient
- { pubkey: payer.publicKey, isSigner: true, isWritable: true }, // Payer
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, // System program
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, // Token program
- {
- pubkey: ASSOCIATED_TOKEN_PROGRAM_ID,
- isSigner: false,
- isWritable: false,
- }, // Associated token program
- ],
- programId: program.publicKey,
- data: transferToInstructionData.toBuffer(),
- });
- await sendAndConfirmTransaction(connection, new Transaction().add(ix), [payer, recipientWallet], { skipPreflight: true });
- });
- });
|