Browse Source

guide adjustments

tonyboylehub 1 year ago
parent
commit
1b18fb0bc9

+ 103 - 76
src/pages/core/guides/javascript/how-to-create-a-core-nft-asset.md

@@ -30,7 +30,7 @@ npm init
 
 Install the required packages for this guide.
 
-{% packagesUsed packages=["umi", "umiDefaults" ,"tokenMetadata", "core", "@solana/spl-token"] type="npm" /%}
+{% packagesUsed packages=["umi", "umiDefaults", "core", "@metaplex-foundation/umi-uploader-irys"] type="npm" /%}
 
 ```js
 npm i @metaplex-foundation/umi
@@ -53,21 +53,12 @@ npm i @metaplex-foundation/umi-uploader-irys;
 Here we will define all needed imports for this particular guide and create a wrapper function where all our code will execute.
 
 ```ts
+import { create, mplCore } from '@metaplex-foundation/mpl-core'
 import {
-  createFungible,
-  mplTokenMetadata,
-} from '@metaplex-foundation/mpl-token-metadata'
-import {
-  createTokenIfMissing,
-  findAssociatedTokenPda,
-  getSplAssociatedTokenProgramId,
-  mintTokensTo,
-} from '@metaplex-foundation/mpl-toolbox'
-import {
-  generateSigner,
-  percentAmount,
   createGenericFile,
+  generateSigner,
   signerIdentity,
+  sol,
 } from '@metaplex-foundation/umi'
 import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
 import { irysUploader } from '@metaplex-foundation/umi-uploader-irys'
@@ -97,19 +88,24 @@ This example is going to run through setting up Umi with a `generatedSigner()`.
 ```ts
 const umi = createUmi('https://api.devnet.solana.com')
   .use(mplCore())
-  .use(irysUploader())
+  .use(
+    irysUploader({
+      // mainnet address: "https://node1.irys.xyz"
+      // devnet address: "https://devnet.irys.xyz"
+      address: 'https://devnet.irys.xyz',
+    })
+  )
 
-// Generate a new keypair signer.
 const signer = generateSigner(umi)
 
-// Tell umi to use the new signer.
 umi.use(signerIdentity(signer))
 
 // This will airdrop SOL on devnet only for testing.
+console.log('Airdropping 1 SOL to identity')
 await umi.rpc.airdrop(umi.identity.publickey)
 ```
 
-### Use an Existing Wallet
+### Use an Existing Wallet Locally
 
 ```ts
 const umi = createUmi('https://api.devnet.solana.com')
@@ -121,19 +117,15 @@ const signer = generateSigner(umi)
 
 // You will need to us fs and navigate the filesystem to
 // load the wallet you wish to use via relative pathing.
-const walletFile = fs.readFileSync(
+const walletFile = const imageFile = fs.readFileSync(
     path.join(__dirname, './keypair.json')
   )
 
 // Convert your walletFile onto a keypair.
 let keypair = umi.eddsa.createKeypairFromSecretKey(new Uint8Array(walletFile));
 
-// Create an Umi Signer.
-const signer = createSignerFromKeypair(umi, keypair);
-
-// Assign signer to umi as the identity.
-umi.use(signerIdentity(walletFile))
-
+// Load the keypair into umi.
+umi.use(keypairIdentity(umiSigner));
 ```
 
 ## Creating the NFT
@@ -150,7 +142,6 @@ This example is using a local script/node.js approach using Irys to upload to Ar
 
 ```ts
 // use `fs` to read file via a string path.
-// You will need to understand the concept of pathing from a computing perspective.
 
 const imageFile = fs.readFileSync(
   path.join(__dirname, '..', '/assets/my-image.jpg')
@@ -180,61 +171,54 @@ console.log(imageUri[0])
 
 Once we have a valid and working image URI we can start working on the metadata for our token.
 
-the standard for offchain metadata for a fungible token is as follows
+the standard for offchain metadata for a fungible token is as follows. This should be filled out and writen to either an object `{}` without Javascript or saved to a `metadata.json` file.
+We are going to look at the Javascript object approach.
 
-```json
-{
-  "name": "My NFT",
-  "description": "This is an NFT on Solana",
-  "image": "https://arweave.net/my-image",
-  "animation_url": "https://arweave.net/my-animation",
-  "external_url": "https://example.com",
-  "attributes": [
+```ts
+const metadata = {
+  name: 'My NFT',
+  description: 'This is an NFT on Solana',
+  image: imageUri[0],
+  external_url: 'https://example.com',
+  attributes: [
     {
-      "trait_type": "trait1",
-      "value": "value1"
+      trait_type: 'trait1',
+      value: 'value1',
     },
     {
-      "trait_type": "trait2",
-      "value": "value2"
-    }
+      trait_type: 'trait2',
+      value: 'value2',
+    },
   ],
-  "properties": {
-    "files": [
+  properties: {
+    files: [
       {
-        "uri": "https://arweave.net/my-image",
-        "type": "image/png"
+        uri: imageUri[0],
+        type: 'image/jpeg',
       },
-      {
-        "uri": "https://arweave.net/my-animation",
-        "type": "video/mp4"
-      }
     ],
-    "category": "video"
-  }
+    category: 'image',
+  },
 }
 ```
 
-The fields here include
+The fields here include:
 
-#### name
+| field         | description                                                                                                                                                                               |
+| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| name          | The name of your NFT.                                                                                                                                                                     |
+| description   | The description of your NFT.                                                                                                                                                              |
+| image         | This will be set to the `imageUri` (or any online location of the image) that we uploaded previously.                                                                                     |
+| animation_url | This will be set to the `animation_ulr` (or any online location of the video/glb) that you've uploaded.                                                                                   |
+| external_url  | This would link to an external address of your choice. This is normally the projects website.                                                                                             |
+| attributes    | Using an object og `{trait_type: vlue, "value": "value1"}`                                                                                                                                |
+| image         | This will be set to the `imageUri` (or any online location of the image) that we uploaded previously.                                                                                     |
+| properties    | Contains the `files` field that takes an `[] array` of `{uri: string, type: mimeType}`. Also contains the category field which can be set to `image`, `audio`, `video`, `vfx`, and `html` |
 
-The name of your token.
-
-#### symbol
-
-The short hand of your token. Where Solana's shorthand would be `SOL`.
-
-#### description
-
-The description of your token.
-
-#### image
-
-This will be set to the `imageUri` (or any online location of the image) that we uploaded previously.
+#### Uploading the Metadata Json File
 
 ```js
-// Call upon umi's `uploadJson function to upload our metadata to Arweave via Irys.
+// Call upon umi's `uploadJson()` function to upload our metadata to Arweave via Irys.
 
 const metadataUri = await umi.uploader.uploadJson(metadata).catch((err) => {
   throw new Error(err)
@@ -247,19 +231,42 @@ Now if all has gone to play we should have the URI of JSON file stored in the `m
 
 From here we can use the `create` function from the `mpl-core` package to create our Core Asset NFT.
 
-
 ```ts
 const assetSigner = generateSigner(umi)
 
-const createTx = await create(umi, {
-  asset: assetSigner,
-  collection: collection,
-  name: 'My Asset',
-  uri: 'https://example.com/my-asset.json',
+const tx = await create(umi, {
+  asset: nftSigner,
+  name: 'My NFT',
+  uri: metadataUri,
 }).sendAndConfirm(umi)
 
+//
+// ** Logging out Details**
+//
+
+// Log out the signature and the links to the transaction and the NFT.
+console.log('\nNFT Created')
+console.log('View Transaction on SolanaFM')
+console.log(`https://solana.fm/tx/${signature}?cluster=devnet-alpha`)
+console.log('\n')
+console.log('View NFT on Metaplex Explorer')
+console.log(
+  `https://core.metaplex.com/explorer/${nftSigner.publicKey}?env=devnet`
+)
+```
 
-console.log(base58.deserialize(tx.signature)[0])
+### Loggin Out The Details
+
+```ts
+// Log out the signature and the links to the transaction and the NFT and our work.
+console.log('\nNFT Created')
+console.log('View Transaction on SolanaFM')
+console.log(`https://solana.fm/tx/${signature}?cluster=devnet-alpha`)
+console.log('\n')
+console.log('View NFT on Metaplex Explorer')
+console.log(
+  `https://core.metaplex.com/explorer/${nftSigner.publicKey}?env=devnet`
+)
 ```
 
 ## Full Code Example
@@ -283,6 +290,14 @@ const createNft = async () => {
   //
 
   const umi = createUmi('https://api.devnet.solana.com')
+    .use(mplCore())
+    .use(
+      irysUploader({
+        // mainnet address: "https://node1.irys.xyz"
+        // devnet address: "https://devnet.irys.xyz"
+        address: 'https://devnet.irys.xyz',
+      })
+    )
 
   const signer = generateSigner(umi)
 
@@ -291,6 +306,7 @@ const createNft = async () => {
   // Airdrop 1 SOL to the identity
   // if you end up with a 429 too many requests error, you may have to use
   // the filesystem wallet method or change rpcs.
+  console.log('Airdropping 1 SOL to identity')
   await umi.rpc.airdrop(umi.identity.publicKey, sol(1))
 
   //
@@ -316,7 +332,7 @@ const createNft = async () => {
   // address where the file is located. You can log this out but as the
   // uploader can takes an array of files it also returns an array of uris.
   // To get the uri we want we can call index [0] in the array.
-
+  console.log('Uploading Image...')
   const imageUri = await umi.uploader.upload([umiImageFile]).catch((err) => {
     throw new Error(err)
   })
@@ -355,6 +371,7 @@ const createNft = async () => {
 
   // Call upon umi's `uploadJson` function to upload our metadata to Arweave via Irys.
 
+  console.log('Uploading Metadata...')
   const metadataUri = await umi.uploader.uploadJson(metadata).catch((err) => {
     throw new Error(err)
   })
@@ -366,15 +383,25 @@ const createNft = async () => {
   // We generate a signer for the NFT
   const nftSigner = generateSigner(umi)
 
+  console.log('Creating NFT...')
   const tx = await create(umi, {
     asset: nftSigner,
     name: 'My NFT',
     uri: metadataUri,
   }).sendAndConfirm(umi)
 
-  // finally we can deserialize the signature that we can check on chain.
-  const signature = base58.deserialize(tx.signature)
-  console.log(signature)
+  // Finally we can deserialize the signature that we can check on chain.
+  const signature = base58.deserialize(tx.signature)[0]
+
+  // Log out the signature and the links to the transaction and the NFT.
+  console.log('\nNFT Created')
+  console.log('View Transaction on Solana Explorer')
+  console.log(`https://explorer.solana.com/tx/${signature}?cluster=devnet`)
+  console.log('\n')
+  console.log('View NFT on Metaplex Explorer')
+  console.log(
+    `https://core.metaplex.com/explorer/${nftSigner.publicKey}?env=devnet`
+  )
 }
 
 createNft()

+ 85 - 54
src/pages/guides/javascript/how-to-create-an-spl-token-on-solana.md

@@ -93,20 +93,44 @@ This example is going to run through setting up Umi with a `generatedSigner()`.
 
 You can place the umi variable and code block either inside or outside the `createAndMintTokens()` function. All that matters is that your `umi` variable is accessible from the `createAndMintTokens()` function itself.
 
+### Generating a New Wallet
+
 ```ts
 const umi = createUmi('https://api.devnet.solana.com')
-  .use(mplTokenMetadata())
+  .use(mplCore())
   .use(irysUploader())
 
-// Generates a new private key to use with umi.
+// Generate a new keypair signer.
 const signer = generateSigner(umi)
 
-// Assign the private key to be the default Umi identity.
+// Tell umit to use the new signer.
 umi.use(signerIdentity(signer))
 
-// If using a newly generated privatekey/wallet you may
-// need to airdrop (Devnet only) or transfer SOL to the new address.
-await umi.rpc.airdrop(umi.identity.publicKey, sol(1));
+// Airdrop 1 SOL to the identity
+// if you end up with a 429 too many requests error, you may have to use
+// the a different rpc other than the free default one supplied.
+await umi.rpc.airdrop(umi.identity.publickey)
+```
+
+### Use an Existing Wallet Stored Locally
+
+```ts
+const umi = createUmi('https://api.devnet.solana.com')
+  .use(mplTokenMetadata())
+  .use(mplToolbox())
+  .use(irysUploader())
+
+// You will need to us fs and navigate the filesystem to
+// load the wallet you wish to use via relative pathing.
+const walletFile = const imageFile = fs.readFileSync(
+    path.join(__dirname, './keypair.json')
+  )
+
+// Convert your walletFile onto a keypair.
+let keypair = umi.eddsa.createKeypairFromSecretKey(new Uint8Array(walletFile));
+
+// Load the keypair into umi.
+umi.use(keypairIdentity(umiSigner));
 ```
 
 
@@ -134,7 +158,7 @@ const imageFile = fs.readFileSync(
 // otherwise Arweave will not know how to display your image.
 
 const umiImageFile = createGenericFile(imageFile, 'island-dao.jpeg', {
-  tags: [{ name: 'Content-Type', value: 'image/jpeg' }],
+  tags: [{ name: 'contentType', value: 'image/jpeg' }],
 })
 
 // Here we upload the image to Arweave via Irys and we get returned a uri
@@ -200,21 +224,17 @@ const metadataUri = await umi.uploader.uploadJson(metadata).catch((err) => {
 
 If everything goes as planned, the metadataUri variable should store the URI of the uploaded JSON file.
 
-### Creating the Token
+### Creating a Token
 
 When creating a new token on the Solana blockchain we need to create a few accounts to accommodate the new data.
 
-#### Creating the mint account.
-
-If we are minting the Tokens then we need a Token Account (holds the minted tokens in a persons wallet)
-Mint the token.
-When you first create the tokens, the creator will retain the update authority and mint authority. Both update and mint authority will need to be revoked when listing the token on DEXs such as Jupiter and Orca for validation.
+#### Creating The Mint Account and Token Metadata
 
-#### Mint Account
+While the Mint account of stores initial minting details of Mint such as number of decimals, the total supply, and mint and freeze authorities, the Token Metadata account holds properties of the token such as `name`, off chain metadata `uri`, `description` of the token, and the tokens `symbol`. Together these accounts provide all the information for a SPL Token on Solana.
 
-To make a mint account and save mint data, we use the createFungible helper method. This method simplifies the process of creating an account for you.
+The `createFungible()` function below creates both the Mint account and the Token Metadata account for use.
 
-We need to give the function a keypair for the mint address. We also need to provide additional metadata from a JSON file. This metadata includes the token's name and the metadata URI address.
+We need to supply the function a keypair which will become the mint address. We also need to provide additional metadata from a JSON file. This metadata includes the token's name and the metadata URI address.
 
 ```ts
 const mintSigner = generateSigner(umi)
@@ -232,20 +252,22 @@ const createMintIx = await createFungible(umi, {
 
 #### Token Account
 
-If we are minting the tokens straight away then we need a place to store the tokens in someones wallet. To do this we mathematically generate an address based on both the wallet and mint address which is called a Associated Token Account (ATA) or sometimes just referred to as just a Token Account.
+If we are minting the tokens straight away then we need a place to store the tokens in someones wallet. To do this we mathematically generate an address based on both the wallet and mint address which is called a Associated Token Account (ATA) or sometimes just referred to as just a Token Account. This Token Account (ATA) belongs to the wallet and stores our tokens for us.
 
-#### Generating the Token Account Address.
+#### Generating a Token Account.
 
-The first thing we need to do is figure out what the Token Account address should be. mpl-toolbox has a helper function we can import that does just that.
+The first thing we need to do is figure out what the Token Account address should be. MPL-Toolbox has a helper function we can import that does just that while also creating the Token Account for if it doesn't exist.
 
 ```ts
-const createTokenIx = createTokenIfMissing(umi, {
+const createTokenIx = createTokenAccountIfMissing(umi, {
   mint: mintSigner.publickey,
   owner: umi.identity.publicKey,
   ataProgram: getSplAssociatedTokenProgramId(umi),
 })
 ```
 
+#### Mint Tokens Transaction
+
 Now that we have a instruction to create an Token Account we can mint tokens to that account with the `mintTokenTo()` instruction.
 
 ```ts
@@ -268,6 +290,7 @@ You can send and arrange the transactions in multiple ways but in this example w
 
 const tx = await createFungibleIx
   .add(createTokenIx)
+  .add(createTokenAccountIfMissing)
   .add(mintTokensIx)
   .sendAndConfirm(umi)
 
@@ -319,60 +342,63 @@ const createAndMintTokens = async () => {
 
   umi.use(signerIdentity(signer))
 
-  // Airdrop 1 SOL to the identity
+// Airdrop 1 SOL to the identity
   // if you end up with a 429 too many requests error, you may have to use
   // the filesystem wallet method or change rpcs.
-  await umi.rpc.airdrop(umi.identity.publicKey, sol(1))
+  console.log("AirDrop 1 SOL to the umi identity");
+  await umi.rpc.airdrop(umi.identity.publicKey, sol(1));
 
   // use `fs` to read file via a string path.
-
-  const imageFile = fs.readFileSync(path.join(__dirname, '/assets/image.png'))
+  
+  const imageFile = fs.readFileSync(path.join(__dirname, "../assets/images/1.png"));
 
   // Use `createGenericFile` to transform the file into a `GenericFile` type
-  // that Umi can understand. Make sure you set the mimi tag type correctly
+  // that umi can understand. Make sure you set the mimi tag type correctly
   // otherwise Arweave will not know how to display your image.
 
-  const umiImageFile = createGenericFile(imageFile, 'image.png', {
-    tags: [{ name: 'Content-Type', value: 'image/png' }],
-  })
+  const umiImageFile = createGenericFile(imageFile, "1.png", {
+    tags: [{ name: "Content-Type", value: "image/png" }],
+  });
 
   // Here we upload the image to Arweave via Irys and we get returned a uri
   // address where the file is located. You can log this out but as the
   // uploader can takes an array of files it also returns an array of uris.
   // To get the uri we want we can call index [0] in the array.
 
+  console.log("Uploading image to Arweave via Irys");
   const imageUri = await umi.uploader.upload([umiImageFile]).catch((err) => {
-    throw new Error(err)
-  })
+    throw new Error(err);
+  });
 
-  console.log(imageUri[0])
+  console.log(imageUri[0]);
 
   // Uploading the tokens metadata to Arweave via Irys
 
   const metadata = {
-    name: 'The Kitten Coin',
-    symbol: 'KITTEN',
-    description: 'The Kitten Coin is a token created on the Solana blockchain',
+    name: "The Kitten Coin",
+    symbol: "KITTEN",
+    description: "The Kitten Coin is a token created on the Solana blockchain",
     image: imageUri, // Either use variable or paste in string of the uri.
-  }
+  };
 
-  // Call upon Umi's `uploadJson` function to upload our metadata to Arweave via Irys.
+  // Call upon umi's uploadJson function to upload our metadata to Arweave via Irys.
 
+  console.log("Uploading metadata to Arweave via Irys");
   const metadataUri = await umi.uploader.uploadJson(metadata).catch((err) => {
-    throw new Error(err)
-  })
+    throw new Error(err);
+  });
 
   // Creating the mintIx
 
-  const mintSigner = generateSigner(umi)
+  const mintSigner = generateSigner(umi);
 
   const createFungibleIx = createFungible(umi, {
     mint: mintSigner,
-    name: 'The Kitten Coin',
-    uri: metadataUri, // we use the `metadataUri` variable we created earlier that is storing our uri.
+    name: "The Kitten Coin",
+    uri: metadataUri, // we use the `metedataUri` variable we created earlier that is storing our uri.
     sellerFeeBasisPoints: percentAmount(0),
-    decimals: 9, // set the amount of decimals you want your token to have.
-  })
+    decimals: 0, // set the amount of decimals you want your token to have.
+  });
 
   // This instruction will create a new Token Account if required, if one is found then it skips.
 
@@ -380,7 +406,7 @@ const createAndMintTokens = async () => {
     mint: mintSigner.publicKey,
     owner: umi.identity.publicKey,
     ataProgram: getSplAssociatedTokenProgramId(umi),
-  })
+  });
 
   // The final instruction (if required) is to mint the tokens to the token account in the previous ix.
 
@@ -391,25 +417,30 @@ const createAndMintTokens = async () => {
       owner: umi.identity.publicKey,
     }),
     amount: BigInt(1000),
-  })
+  });
 
   // The last step is to send the ix's off in a transaction to the chain.
-  // Ix's here can be omitted and added as needed during the chain.
+  // Ix's here can be ommited and added as needed during the transaction chain.
   // If for example you just want to create the Token without minting
-  // any tokens then you can only submit the `createToken` ix.
-
-  // If you want to mint tokens to a different wallet then you can
-  // just pull out the `createTokenIx` ix and `mintTokensIx` ix and send
-  // them as another tx.
+  // any tokens then you may only want to submit the `createToken` ix.
 
+  console.log("Sending transaction")
   const tx = await createFungibleIx
     .add(createTokenIx)
     .add(mintTokensIx)
-    .sendAndConfirm(umi)
+    .sendAndConfirm(umi);
 
   // finally we can deserialize the signature that we can check on chain.
-  console.log(base58.deserialize(tx.signature)[0])
-}
+  const signature = base58.deserialize(tx.signature)[0];
+
+  // Log out the signature and the links to the transaction and the NFT.
+  // Explorer links are for the devnet chain, you can change the clusters to mainnet.
+  console.log('\nTransaction Complete')
+  console.log('View Transaction on Solana Explorer')
+  console.log(`https://explorer.solana.com/tx/${signature}?cluster=devnet`)
+  console.log('View Token on Solana Explorer')
+  console.log(`https://explorer.solana.com/address/${mintSigner.publicKey}?cluster=devnet`)
+};
 
 createAndMintTokens()
 ```

+ 10 - 9
src/pages/guides/javascript/how-to-transfer-sol-on-solana.md

@@ -13,6 +13,7 @@ This guide walks will show you how to build a Javascript function that transfers
 
 - Code Editor of your choice (recommended Visual Studio Code)
 - Node 18.x.x or above.
+- Basic Javascript knowledge
 
 ## Initial Setup
 
@@ -93,23 +94,23 @@ umi.use(signerIdentity(signer))
 await umi.rpc.airdrop(umi.identity.publickey)
 ```
 
-### Use an Existing Wallet
-
-If you wish to use an existing wallet you can import this a few different ways. The below code assumes that the private key is stored in `.json` format on your hardrive somewhere.
+### Use an Existing Wallet Stored Locally
 
 ```ts
 const umi = createUmi('https://api.devnet.solana.com')
-  .use(mplCore())
-  .use(irysUploader())
-
-// Generate a new keypair signer.
-const signer = generateSigner(umi)
+  .use(mplToolbox())
 
-// You will need to use fs and navigate the filesystem to
+// You will need to us fs and navigate the filesystem to
 // load the wallet you wish to use via relative pathing.
 const walletFile = const imageFile = fs.readFileSync(
     path.join(__dirname, './keypair.json')
   )
+
+// Convert your walletFile onto a keypair.
+let keypair = umi.eddsa.createKeypairFromSecretKey(new Uint8Array(walletFile));
+
+// Load the keypair into umi.
+umi.use(keypairIdentity(umiSigner));
 ```
 
 ## Transferring Sol

+ 25 - 114
src/pages/guides/javascript/how-to-transfer-spl-tokens-on-solana.md

@@ -9,6 +9,8 @@ updated: '06-24-2024'
 
 This guide will show you how to build out a Javascript function to send and transfer SPL tokens on the Solana blockchain utilizing the Metaplex Umi client wrapper and MPL Toolbox packages.
 
+For this guide you will need to have some SPL Tokens in your wallet to transfer so if you not have any in your wallet you will need to get someone to transfer some to you or you can follow our other [how to create an SPL Token guide](/guides/javascript/how-to-create-an-spl-token-on-solana).
+
 ## Prerequisite
 
 - Code Editor of your choice (recommended Visual Studio Code)
@@ -46,122 +48,29 @@ npm i @metaplex-foundation/mpl-toolbox;
 
 Here we will define all needed imports for this particular guide and create a wrapper function where all our code will execute.
 
-```ts
-import { mplToolbox, transferSol } from '@metaplex-foundation/mpl-toolbox'
-import {
-  generateSigner,
-  publicKey,
-  signerIdentity,
-  sol,
-} from '@metaplex-foundation/umi'
-import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
-import { base58 } from '@metaplex-foundation/umi/serializers'
-
-// Create the wrapper function
-const transferSolana = async () => {
-  ///
-  ///
-  ///  all our code will go in here
-  ///
-  ///
-}
-
-// run the wrapper function
-transferSolana()
-```
-
-## Setting up Umi
-
-This example is going to run through setting up Umi with a `generatedSigner()`. If you wish to set up a wallet or signer in a different way you can check out the [**Connecting to Umi**](/umi/connecting-to-umi) guide.
-
-### Generating a New Wallet
-
-```ts
-const umi = createUmi('https://api.devnet.solana.com')
-  .use(mplCore())
-  .use(irysUploader())
-
-// Generate a new keypair signer.
-const signer = generateSigner(umi)
-
-// Tell umit to use the new signer.
-umi.use(signerIdentity(signer))
-
-// This will airdrop SOL on devnet only for testing.
-await umi.rpc.airdrop(umi.identity.publickey)
-```
-
-### Use an Existing Wallet
-
-```ts
-const umi = createUmi('https://api.devnet.solana.com')
-  .use(mplCore())
-  .use(irysUploader())
-
-// Generate a new keypair signer.
-const signer = generateSigner(umi)
-
-// You will need to us fs and navigate the filesystem to
-// load the wallet you wish to use via relative pathing.
-const walletFile = const imageFile = fs.readFileSync(
-    path.join(__dirname, './keypair.json')
-  )
-```
-
-## Key Accounts
-
-When transferring SPL Tokens on Solana we need to work out both the senders and recievers SPL Token Account addresses for the token we are trying to send.
-
-Token Account addresses are unique between coins and wallets so we need to use a helper function to determine what each account address is for the both the sender and the receiver.
-
-```ts
-// The address of the Token you want to transfer.
-const splToken = publicKey('111111111111111111111111111111')
-
-// The address of the wallet you want to transfer the Token to.
-const recipientWallet = publicKey('22222222222222222222222222222222')
-
-// Find the associated token account for the SPL Token on the senders wallet.
-const sourceTokenAccount = findAssociatedTokenPda(umi, {
-  mint: splToken,
-  owner: umi.identity.publicKey,
-})
-
-// Find the associated token account for the SPL Token on the receivers wallet.
-const destinationTokenAccount = findAssociatedTokenPda(umi, {
-  mint: splToken,
-  owner: recipientWallet,
-})
-```
-
-## Sending the SPL Tokens
-
 ```ts
 import {
   findAssociatedTokenPda,
   mplToolbox,
   transferTokens,
 } from '@metaplex-foundation/mpl-toolbox'
-import {
-  generateSigner,
-  publicKey,
-  signerIdentity,
-  sol,
-} from '@metaplex-foundation/umi'
+import { keypairIdentity, publicKey } from '@metaplex-foundation/umi'
 import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
 import { base58 } from '@metaplex-foundation/umi/serializers'
+import fs from 'fs'
+import path from 'path'
 
 const transferSplTokens = async () => {
   const umi = createUmi('https://api.devnet.solana.com').use(mplToolbox())
 
-  const signer = generateSigner(umi)
+  // import a wallet that has the SPL Token you want to transfer
+  const walletFile = fs.readFileSync(path.join(__dirname, './keypair.json'))
 
-  umi.use(signerIdentity(signer))
+  // Convert your walletFile onto a keypair.
+  let keypair = umi.eddsa.createKeypairFromSecretKey(new Uint8Array(walletFile))
 
-  // Airdrop 1 SOL to the identity
-  // if you end up with a 429 too many requests error, you may have to use
-  // the filesystem wallet method or change rpcs.
-  await umi.rpc.airdrop(umi.identity.publicKey, sol(1))
+  // Load the keypair into umi.
+  umi.use(keypairIdentity(keypair))
 
   //
   // Key Accounts
@@ -171,7 +80,7 @@ const transferSplTokens = async () => {
   const splToken = publicKey('111111111111111111111111111111')
 
   // The address of the wallet you want to transfer the Token to.
-  const recipientWallet = publicKey('22222222222222222222222222222222')
+  const destinationWallet = publicKey('22222222222222222222222222222222')
 
   // Find the associated token account for the SPL Token on the senders wallet.
   const sourceTokenAccount = findAssociatedTokenPda(umi, {
@@ -182,25 +91,27 @@ const transferSplTokens = async () => {
   // Find the associated token account for the SPL Token on the receivers wallet.
   const destinationTokenAccount = findAssociatedTokenPda(umi, {
     mint: splToken,
-    owner: recipientWallet,
+    owner: destinationWallet,
   })
 
   //
-  // Transfer SPL Token
+  // Transfer SOL
   //
 
-  const res = await transferTokens(umi, {
-    source: sourceTokenAccount,
-    destination: destinationTokenAccount,
-    amount: 10000, // amount of tokens to transfer*
+  const res = await transferSol(umi, {
+    source: umi.identity,
+    // change address to an address you wish to send SOL to
+    destination: publicKey('111111111111111111111111111111111111'),
+    amount: sol(0.2),
   }).sendAndConfirm(umi)
 
-  // Log the signature of the transaction
-  console.log(base58.deserialize(res.signature))
+  // Finally we can deserialize the signature that we can check on chain.
+  const signature = base58.deserialize(res.signature)[0]
 
-  // *When transfering tokens you have to account for the decimal places.
-  // So if you wish to transfer 1 full token and have 5 decimal places
-  // you will need to transfer 100000 tokens to send 1 whole token.
+  // Log out the signature and the links to the transaction and the NFT.
+  console.log('\nTransfer Complete')
+  console.log('View Transaction on Solana Explorer')
+  console.log(`https://explorer.solana.com/tx/${signature}?cluster=devnet`)
 }
 
 transferSplTokens()

+ 76 - 54
src/pages/token-metadata/guides/javascript/create-an-nft.md

@@ -53,22 +53,19 @@ npm i @metaplex-foundation/umi-uploader-irys;
 Here we will define all needed imports for this particular guide and create a wrapper function where all our code will execute.
 
 ```ts
+import { createProgrammableNft, mplTokenMetadata } from "@metaplex-foundation/mpl-token-metadata";
 import {
-  createNft,
-  createProgrammableNft,
-  mplTokenMetadata,
-} from '@metaplex-foundation/mpl-token-metadata'
-import {
+  createGenericFile,
   generateSigner,
   percentAmount,
-  createGenericFile,
   signerIdentity,
-} from '@metaplex-foundation/umi'
-import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
-import { irysUploader } from '@metaplex-foundation/umi-uploader-irys'
-import { base58 } from '@metaplex-foundation/umi/serializers'
-import fs from 'fs'
-import path from 'path'
+  sol,
+} from "@metaplex-foundation/umi";
+import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
+import { irysUploader } from "@metaplex-foundation/umi-uploader-irys";
+import { base58 } from "@metaplex-foundation/umi/serializers";
+import fs from "fs";
+import path from "path";
 
 // Create the wrapper function
 const createNft = async () => {
@@ -91,8 +88,14 @@ This example is going to run through setting up Umi with a `generatedSigner()`.
 
 ```ts
 const umi = createUmi('https://api.devnet.solana.com')
-  .use(mplCore())
-  .use(irysUploader())
+  .use(mplTokenMetadata())
+  .use(
+    irysUploader({
+      // mainnet address: "https://node1.irys.xyz"
+      // devnet address: "https://devnet.irys.xyz"
+      address: "https://devnet.irys.xyz",
+    })
+  );
 
 // Generate a new keypair signer.
 const signer = generateSigner(umi)
@@ -108,8 +111,14 @@ await umi.rpc.airdrop(umi.identity.publickey)
 
 ```ts
 const umi = createUmi('https://api.devnet.solana.com')
-  .use(mplCore())
-  .use(irysUploader())
+  .use(mplTokenMetadata())
+  .use(
+    irysUploader({
+      // mainnet address: "https://node1.irys.xyz"
+      // devnet address: "https://devnet.irys.xyz"
+      address: "https://devnet.irys.xyz",
+    })
+  );
 
 // Generate a new keypair signer.
 const signer = generateSigner(umi)
@@ -337,15 +346,24 @@ const createNft = async () => {
   //
 
   const umi = createUmi('https://api.devnet.solana.com')
+    .use(mplTokenMetadata())
+  .use(
+    irysUploader({
+      // mainnet address: "https://node1.irys.xyz"
+      // devnet address: "https://devnet.irys.xyz"
+      address: "https://devnet.irys.xyz",
+    })
+  );
 
-  const signer = generateSigner(umi)
+  const signer = generateSigner(umi);
 
-  umi.use(signerIdentity(signer))
+  umi.use(signerIdentity(signer));
 
   // Airdrop 1 SOL to the identity
   // if you end up with a 429 too many requests error, you may have to use
   // the filesystem wallet method or change rpcs.
-  await umi.rpc.airdrop(umi.identity.publicKey, sol(1))
+  console.log("Airdropping 1 SOL to identity");
+  await umi.rpc.airdrop(umi.identity.publicKey, sol(1));
 
   //
   // ** Upload an image to Arweave **
@@ -355,90 +373,94 @@ const createNft = async () => {
   // You will need to understand the concept of pathing from a computing perspective.
 
   const imageFile = fs.readFileSync(
-    path.join(__dirname, '../assets/images/0.png')
-  )
+    path.join(__dirname, "../assets/images/0.png")
+  );
 
   // Use `createGenericFile` to transform the file into a `GenericFile` type
   // that umi can understand. Make sure you set the mimi tag type correctly
   // otherwise Arweave will not know how to display your image.
 
-  const umiImageFile = createGenericFile(imageFile, '0.png', {
-    tags: [{ name: 'Content-Type', value: 'image/jpeg' }],
-  })
+  const umiImageFile = createGenericFile(imageFile, "0.png", {
+    tags: [{ name: "Content-Type", value: "image/png" }],
+  });
 
   // Here we upload the image to Arweave via Irys and we get returned a uri
   // address where the file is located. You can log this out but as the
   // uploader can takes an array of files it also returns an array of uris.
   // To get the uri we want we can call index [0] in the array.
 
+  console.log("Uploading image...");
   const imageUri = await umi.uploader.upload([umiImageFile]).catch((err) => {
-    throw new Error(err)
-  })
-
-  console.log('imageUri: ' + imageUri[0])
+    throw new Error(err);
+  });
 
   //
   // ** Upload Metadata to Arweave **
   //
 
   const metadata = {
-    name: 'My NFT',
-    description: 'This is an NFT on Solana',
+    name: "My Nft",
+    description: "This is an Nft on Solana",
     image: imageUri[0],
-    external_url: 'https://example.com',
+    external_url: "https://example.com",
     attributes: [
       {
-        trait_type: 'trait1',
-        value: 'value1',
+        trait_type: "trait1",
+        value: "value1",
       },
       {
-        trait_type: 'trait2',
-        value: 'value2',
+        trait_type: "trait2",
+        value: "value2",
       },
     ],
     properties: {
       files: [
         {
           uri: imageUri[0],
-          type: 'image/jpeg',
+          type: "image/jpeg",
         },
       ],
-      category: 'image',
+      category: "image",
     },
-  }
+  };
 
   // Call upon umi's uploadJson function to upload our metadata to Arweave via Irys.
-
+  console.log("Uploading metadata...");
   const metadataUri = await umi.uploader.uploadJson(metadata).catch((err) => {
-    throw new Error(err)
-  })
+    throw new Error(err);
+  });
 
   //
-  // ** Creating the NFT **
+  // ** Creating the Nft **
   //
 
-  // We generate a signer for the NFT
-  const nftSigner = generateSigner(umi)
+  // We generate a signer for the Nft
+  const nftSigner = generateSigner(umi);
 
-  // Decide on a ruleset for the NFT.
+  // Decide on a ruleset for the Nft.
   // Metaplex ruleset - publicKey("eBJLFYPxJmMGKuFwpDWkzxZeUrad92kZRC5BJLpzyT9")
   // Compatability ruleset - publicKey("AdH2Utn6Fus15ZhtenW4hZBQnvtLgM1YCW2MfVp7pYS5")
   const ruleset = null // or set a publicKey from above
 
-  // decide if you are using createNft() or createProgramableNft() and swap
-  // out as desired.
-
+  console.log("Creating Nft...");
   const tx = await createProgrammableNft(umi, {
     mint: nftSigner,
     sellerFeeBasisPoints: percentAmount(5.5),
-    name: 'My NFT',
+    name: metadata.name,
     uri: metadataUri,
     ruleSet: ruleset,
-  }).sendAndConfirm(umi)
-
-  // finally we can deserialize the signature that we can check on chain.
-  const signature = base58.deserialize(tx.signature)
-  console.log(signature)
+  }).sendAndConfirm(umi);
+
+  // Finally we can deserialize the signature that we can check on chain.
+  const signature = base58.deserialize(tx.signature)[0];
+
+  // Log out the signature and the links to the transaction and the NFT.
+  console.log("\npNFT Created")
+  console.log("View Transaction on Solana Explorer");
+  console.log(`https://explorer.solana.com/tx/${signature}?cluster=devnet`);
+  console.log("\n");
+  console.log("View NFT on Metaplex Explorer");
+  console.log(`https://explorer.solana.com/address/${nftSigner.publicKey}?cluster=devnet`);
 }
 
 createNft()