Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prochna_Sofia #10

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# NFT_Solana
Створити смартконтракт NFT мовою Rust з логотипом НаУКМА завантаженим в IPFS і задеплоїти його в devnet Solana
Зробити пул реквест коду та вказати Ваше прізвище та хеш транзакції в readme.md

Prochna Sofia
Token: 51kVaJaEU1qs4NwfTAH6b7GWprVCBYWtLSHNKQxY4B1
https://explorer.solana.com/address/51kVaJaEU1qs4NwfTAH6b7GWprVCBYWtLSHNKQxY4B1?cluster=devnet
80 changes: 80 additions & 0 deletions client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import BN from "bn.js";
import * as web3 from "@solana/web3.js";
import * as anchor from "@coral-xyz/anchor";
import type { NftProgram } from "../target/types/nft_program";

// Configure the client to use the local cluster
anchor.setProvider(anchor.AnchorProvider.env());

const program = anchor.workspace.NftProgram as anchor.Program<NftProgram>;


const TOKEN_METADATA_PROGRAM_ID = new anchor.web3.PublicKey(
"metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"
);

// const mintKeypair: anchor.web3.Keypair = anchor.web3.Keypair.generate();
const mintKeypair: anchor.web3.PublicKey = new anchor.web3.PublicKey(
"51kVaJaEU1qs4NwfTAH6b7GWprVCBYWtLSHNKQxY4B1"
);
const tokenAddress = await anchor.utils.token.associatedAddress({
mint: mintKeypair,
owner: program.provider.publicKey,
});
console.log(`New token: ${mintKeypair}`);

// Derive the metadata and master edition addresses

const metadataAddress = (
anchor.web3.PublicKey.findProgramAddressSync(
[
Buffer.from("metadata"),
TOKEN_METADATA_PROGRAM_ID.toBuffer(),
mintKeypair.toBuffer(),
],
TOKEN_METADATA_PROGRAM_ID
)
)[0];
console.log("Metadata initialized");
const masterEditionAddress = anchor.web3.PublicKey.findProgramAddressSync(
[
Buffer.from("metadata"),
TOKEN_METADATA_PROGRAM_ID.toBuffer(),
mintKeypair.toBuffer(),
Buffer.from("edition"),
],
TOKEN_METADATA_PROGRAM_ID
)[0];
console.log("Master edition metadata initialized");

try {
await program.methods
.createSingleNft(
new BN(1),
"Prochna-Sofia-nft",
"PNFT",
"https://run.mocky.io/v3/9586fda8-b711-42a7-9dae-6b774d207bc4",
0.01,
new BN(1)
)
.accounts({
tokenAccount: tokenAddress,
mint: new anchor.web3.PublicKey(
"51kVaJaEU1qs4NwfTAH6b7GWprVCBYWtLSHNKQxY4B1"
),
rent: program.provider.wallet.payer,
tokenProgram: new anchor.web3.PublicKey(
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
),
associatedTokenProgram: new anchor.web3.PublicKey(
"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
),
metadataProgram: TOKEN_METADATA_PROGRAM_ID,
masterEditionAccount: masterEditionAddress,
nftMetadata: metadataAddress,
})
.signers([program.provider.wallet.payer])
.rpc();
} catch (e) {
console.log(e);
}
155 changes: 155 additions & 0 deletions lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
use anchor_lang::prelude::*;
use anchor_spl::associated_token::AssociatedToken;
use anchor_spl::metadata::{
create_master_edition_v3, create_metadata_accounts_v3, CreateMasterEditionV3,
CreateMetadataAccountsV3, Metadata,
};
use anchor_spl::token::{mint_to, Mint, MintTo, Token, TokenAccount};
use mpl_token_metadata::types::{Collection, Creator, DataV2};

declare_id!("EkEBE7HzP7fkQ3MVGuV2JrADyphAgETGnesLqtP8ZHbR");

#[program]
pub mod nft_program {
use super::*;
pub fn create_single_nft(
ctx: Context<CreateNFT>,
id: u64,
name: String,
symbol: String,
uri: String,
price: f32,
cant: u64,
) -> Result<()> {
msg!("Creating seeds");
let id_bytes = id.to_le_bytes();
let seeds = &["mint".as_bytes(),id_bytes.as_ref(),&[ctx.bumps.mint],
];

msg!("Run mint_to");

mint_to(
CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
MintTo {
authority: ctx.accounts.authority.to_account_info(),
to: ctx.accounts.token_account.to_account_info(),
mint: ctx.accounts.mint.to_account_info(),
},
&[&seeds[..]],
),
1, // 1 token
)?;

msg!("Run create metadata accounts v3");

create_metadata_accounts_v3(
CpiContext::new_with_signer(
ctx.accounts.metadata_program.to_account_info(),
CreateMetadataAccountsV3 {
payer: ctx.accounts.payer.to_account_info(),
mint: ctx.accounts.mint.to_account_info(),
metadata: ctx.accounts.nft_metadata.to_account_info(),
mint_authority: ctx.accounts.authority.to_account_info(),
update_authority: ctx.accounts.authority.to_account_info(),
system_program: ctx.accounts.system_program.to_account_info(),
rent: ctx.accounts.rent.to_account_info(),
},
&[&seeds[..]],
),
DataV2 {
name,
symbol,
uri,
seller_fee_basis_points: 0,
creators: None,
collection: None,
uses: None,
},
true,
true,
None,
)?;

msg!("Run create master edition v3");

create_master_edition_v3(
CpiContext::new_with_signer(
ctx.accounts.metadata_program.to_account_info(),
CreateMasterEditionV3 {
edition: ctx.accounts.master_edition_account.to_account_info(),
payer: ctx.accounts.payer.to_account_info(),
mint: ctx.accounts.mint.to_account_info(),
metadata: ctx.accounts.nft_metadata.to_account_info(),
mint_authority: ctx.accounts.authority.to_account_info(),
update_authority: ctx.accounts.authority.to_account_info(),
system_program: ctx.accounts.system_program.to_account_info(),
token_program: ctx.accounts.token_program.to_account_info(),
rent: ctx.accounts.rent.to_account_info(),
},
&[&seeds[..]],
),
Some(1),
)?;

msg!("Minted NFT successfully");

Ok(())
}
}

#[derive(Accounts)]
#[instruction(id: u64)]
pub struct CreateNFT<'info> {
#[account(mut)]
pub authority: Signer<'info>,
#[account(mut)]
pub payer: Signer<'info>,
#[account(
init,
payer = payer,
mint::decimals = 0,
mint::authority = authority,
mint::freeze_authority = authority,
seeds = ["mint".as_bytes(), id.to_le_bytes().as_ref()],
bump,
)]
pub mint: Account<'info, Mint>,
#[account(
init_if_needed,
payer = payer,
associated_token::mint = mint,
associated_token::authority = payer,
)]
pub token_account: Account<'info, TokenAccount>,
pub associated_token_program: Program<'info, AssociatedToken>,
pub rent: Sysvar<'info, Rent>,
pub system_program: Program<'info, System>,
pub token_program: Program<'info, Token>,
pub metadata_program: Program<'info, Metadata>,
#[account(
mut,
seeds = [
b"metadata".as_ref(),
metadata_program.key().as_ref(),
mint.key().as_ref(),
b"edition".as_ref(),
],
bump,
seeds::program = metadata_program.key()
)]
/// CHECK:
pub master_edition_account: UncheckedAccount<'info>,
#[account(
mut,
seeds = [
b"metadata".as_ref(),
metadata_program.key().as_ref(),
mint.key().as_ref(),
],
bump,
seeds::program = metadata_program.key()
)]
/// CHECK:
pub nft_metadata: UncheckedAccount<'info>,
}