Created
October 6, 2022 11:16
-
-
Save what-name/f948f8def57206839816047e30587914 to your computer and use it in GitHub Desktop.
How to create SFTs on Solana (TypeScript)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This Gist is the code for the tutorial "How to create SFTs on Solana". | |
// See the tutorial on Youtube: https://youtu.be/BYmcw0LThGE | |
// Check out SOAP - https://solanasoap.lol - https://twitter.com/solanasoap | |
// yarn add @metaplex-foundation/js@0.16.0 @solana/web3.js@1.63.1 | |
import { bundlrStorage, keypairIdentity, Metaplex, CreatorInput, KeypairSigner, JsonMetadata, CreateSftInput } from '@metaplex-foundation/js'; | |
import { Keypair, clusterApiUrl, Connection, PublicKey } from '@solana/web3.js'; | |
import * as fs from "fs" | |
const clusterString = "devnet" | |
// sftkeypair.json (create and use your own keypair) | |
// Load a local keypair | |
const keypairFile = fs.readFileSync('sftkeypair.json'); | |
const keypair = Keypair.fromSecretKey(Buffer.from(JSON.parse(keypairFile.toString()))); | |
// Set up foundation | |
const connection = new Connection(clusterApiUrl(clusterString)) | |
const metaplex = Metaplex.make(connection) | |
.use(keypairIdentity(keypair)) | |
.use(bundlrStorage({ | |
address: 'https://devnet.bundlr.network', | |
providerUrl: 'https://api.devnet.solana.com', | |
timeout: 60000, | |
})) | |
console.log("Public key of keypair being used: ", keypair.publicKey.toBase58()) | |
// Create keypair to add as first verified creator | |
const randomCreatorKeypair = Keypair.generate() | |
const randomCreatorKeypairSigner: KeypairSigner = { | |
publicKey: randomCreatorKeypair.publicKey, | |
secretKey: randomCreatorKeypair.secretKey | |
} | |
// Assemble verified creators object | |
const soapCreator: CreatorInput[] = [ | |
{ | |
// Unique first verified creator per soap | |
address: randomCreatorKeypair.publicKey, | |
share: 0, | |
authority: randomCreatorKeypairSigner | |
}, | |
{ | |
// main soap creator | |
address: metaplex.identity().publicKey, | |
share: 100, | |
} | |
] | |
// Create collection signer object | |
const collectionSigner: KeypairSigner = { | |
publicKey: metaplex.identity().publicKey, | |
secretKey: metaplex.identity().secretKey | |
} | |
// NFT Metadata | |
const jsonMetadata: JsonMetadata = { | |
name: "SFT SOAP Tutorial", | |
symbol: "SOAP", | |
description: "You really did grind it out. Well, this diamond lootbox you got was well deserved. Here's a memento to show your friends, as if they wouldn't know you spend all day on Twitter anyways.", | |
seller_fee_basis_points: 500, | |
image: "https://i.pinimg.com/736x/0a/bb/e5/0abbe546e479edc1eb62f5a8ccd66328.jpg", | |
external_url: "http://solanasoap.lol", | |
attributes: [ | |
{ | |
trait_type: "What Dis", | |
value: "A soap" | |
}, | |
{ | |
trait_type: "Twitter", | |
value: "All day errday" | |
}, | |
], | |
properties: { | |
creators: [ | |
{ | |
// Unique first verified creator per soap | |
address: randomCreatorKeypair.publicKey.toBase58(), | |
share: 0, | |
}, | |
{ | |
// main soap creator | |
address: metaplex.identity().publicKey.toBase58(), | |
share: 100, | |
} | |
], | |
files: [ | |
{ | |
type: "image/jpg", | |
uri: "https://i.pinimg.com/736x/0a/bb/e5/0abbe546e479edc1eb62f5a8ccd66328.jpg", | |
} | |
], | |
category: "image" | |
}, | |
collection: { | |
name: "SOAP", | |
family: "SOAP" | |
} | |
} | |
// Upload off-chain metadata to ARWeave | |
const { uri } = await metaplex | |
.nfts() | |
.uploadMetadata(jsonMetadata) | |
.run(); | |
console.log("URI of SFT metadata", uri) | |
// Create CreateSftInput object | |
const createSftInput: CreateSftInput = { | |
payer: metaplex.identity(), | |
tokenOwner: metaplex.identity().publicKey, | |
// tokenAmount: ({basisPoints: 10, currency: null}), | |
uri: uri, | |
name: jsonMetadata.name, | |
sellerFeeBasisPoints: jsonMetadata.seller_fee_basis_points, | |
symbol: jsonMetadata.symbol, | |
creators: soapCreator, | |
isCollection: true, | |
collection: new PublicKey("6AVMuYXFRDkM1JC2szHFMJwCG3kYKLMEh3duz6eGu4oP"), | |
collectionAuthority: collectionSigner, | |
collectionIsSized: false | |
} | |
// Create SFT | |
const sft = await metaplex.nfts().createSft(createSftInput).run() | |
console.log("SFT Mint Address: ", sft.mintAddress.toBase58()) | |
console.log("SFT Mint: ", "https://solscan.io/token/" + sft.mintAddress.toBase58() + "?cluster=" + clusterString) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment