I Sent My First SOL with Solana’s Phantom Wallet and web3.js: Here’s How

Solana, one of the blockchains that offer an incredibly low transaction fee, is well known for its speed and efficiency. Compared to Ethereum‘s 15 transactions per second, Solanaโ€™s network can handle about 3,400 transactions per second.

๐Ÿ›‘ Attention: There is no free lunch — Solana sacrifices decentralization to accomplish this speed.

Still — many freelancing clients will ask us to create Solana “decentralized” apps for them, so today, we will try out a transaction on Solana.

We will use Solana web3.js, which provides the interface for the developers to interact with the Solana blockchain using JavaScript. We will create two accounts on the phantom wallet. Then airdrop some balance on the first account, and we will send a transaction to the second account. All the things will be done from scratch in JavaScript.

๐ŸŒ Reference

Here’s an example project description where this practical project would be useful. If you just want to know how it is done, feel free to skip the “Project Description”. ๐Ÿ‘‡

Example Project Description

This project will involve sending and receiving SOL tokens (Solana) over the Solana blockchain. The goal of this project is to facilitate a secure, fast, and reliable transfer of SOL tokens between two parties.

First, the two parties involved in the transaction will need to set up Solana wallets in order to store and send SOL tokens. The wallets will need to be integrated with the Solana blockchain and will need to be used to create an address for each party. Each party will then need to securely store their walletโ€™s address and private key for safekeeping.

Second, the two parties will need to agree on the amount of SOL tokens to be transferred. Once agreed upon, the sender will need to enter the recipientโ€™s address in the walletโ€™s send interface, enter the amount of SOL tokens to be sent, and click โ€˜sendโ€™. The wallet will then generate a transaction on the Solana blockchain and broadcast it to the entire network.

Third, the Solana blockchain will validate the transaction and add it to the blockchain ledger. After a few seconds, the transaction will be confirmed and the recipient will receive the SOL tokens in their wallet. The transaction will then be visible on the Solana blockchain explorer.

Finally, the two parties will need to keep track of the transaction by checking their wallets and the Solana blockchain explorer to ensure that the transaction has been completed successfully.

๐Ÿ‘‰ Summary: This project will enable the two parties to securely, quickly, and reliably send and receive SOL tokens over the Solana blockchain.

Step 1: Create a Phantom Wallet

A very popular wallet for the Solana blockchain is the phantom wallet. The phantom extension is available for chrome, firefox, ios and other androids. Just add the extension on your browser if it still needs to be installed. Since we will build on a testing environment, we will change the network to devnet.

Now we need two create two wallets for the transaction purpose. Go to settings and click on the โ€œadd wallet” option to add a wallet. We use wallet 2 as our sender wallet and wallet 3 as our receiver wallet.

Step 2: Set up Solana-web3.js

First, create a folder and import node modules and package.json  on it.

npm init -y

Now install Solana web3.js.

npm install @solana/web3.js

Now visit the package.json file to check if the dependencies of the Solana web3 are installed properly. You will get the version number for the Solana web3 included there.

Just add (โ€œtypeโ€: โ€œmoduleโ€) in the dependencies list inside the โ€œpackage.json” file. Otherwise, you will face problems in importing modules.

Create a soltransaction.js file which will be used to write all the codes. 

Inside the soltransaction.js file, import web3.

import solanaweb3 from "@solana/web3.js";
import bs58 from "bs58";

We must import bs58, the javaScript component, to compute base 58 encoding. We will require this thing soon.

Step 3: Connect with My Phantom Wallet

To establish a connection with the phantom wallet, we will call the Connection object of the web3.js. This Connection object will establish a connection with RPC API. Let’s create the connection instance.

const connection = new solanaweb3.Connection("https://api.devnet.solana.com");

We used the devnet API URL as we will commit our transaction in the devnet network of the phantom wallet.

To commit the transaction on the Solana blockchain, we need to generate a keypair for the accounts. We need to generate Key pairs with public and private keys (used for signed transactions).

There are two ways to obtain a Keypair.

  • Either you can generate a new Keypair with the help of solanaweb3, or
  • You can obtain a new Keypair using a secret key.

We will use the private key of our wallets to generate Keypair. Move to the phantom wallet extension. You will get an export private key option if you click on the wallet. Just copy the private key from there.

The “Keypair.fromSecretKeyโ€ method of solanaweb3 will help us to generate Keypair from the private key.

Bs58 will decode the uint8Array from the private key of our wallets.

๐ŸŒ Reference

Let’s create two variables, senderWallet and receiverWallet, for our wallet2 and wallet3, respectively.

let senderWallet = solanaweb3.Keypair.fromSecretKey(
  bs58.decode(
    "4g2ij8ML3Jd42LJv33apPpQtFkyK5XV9dq3PGa7LiR6LL33ZmraXYbMg7kCQvTAXd7tJRp7mYL1LQ6HEvHL2DhQF"
  )
);
let receiverWallet = solanaweb3.Keypair.fromSecretKey(
  bs58.decode(
    "5MYvQVLAxJH9FWGf1feCPGC4PagBYcLecW5W8YAJoLLakR47iHVZW16aW2C6Pq6Zo8BHvdh1iCYigM9dUEU7RwyD"
  )
);

Now our sender and receiver wallet is ready. So we can get the balance from each account.

Step 4: Get the Balance From My Wallets

(async () => {
  let senderBalance = await connection.getBalance(senderWallet.publicKey);
  let receiverBalance = await connection.getBalance(receiverWallet.publicKey);

  console.log(
    `Sender Balance: ${senderBalance / solanaweb3.LAMPORTS_PER_SOL} SOL`
  );
  console.log(
    `Receiver Balance: ${receiverBalance / solanaweb3.LAMPORTS_PER_SOL} SOL`
  );
})();

These senderBalance and receiverBalance variables inside the async await function will use the getBalance() method of the solanaweb3 to extract the balance from the sender and receiver accounts.

The getBalance method will take the public key of the wallet addresses as the parameter.

Then we โ€œconsole.logโ€ the sender and receiver balance to see It on the terminal. To express the balance in short, we used LAMPORTS_PER_SOL. Lamport is the smallest unit of Solana. A Lamport has a value of 0.000000001 SOL.

Now, if we run the script on the visual studio code terminal. We should get the balance of the two wallets.

node soltransaction.js

Step 5: Airdrop Solana in Sender Account

Now we will airdrop some balance to the sender account using the web3.js library through the devnet network.

Again, we will create an async await function and use the requestAirdrop() method of the web3 to request an airdrop on the sender account.

(async()=>{
let txhash = await connection.requestAirdrop(senderWallet.publicKey, 1e9));
console.log(`Transaction hash : ${txhash}`)
})()

The โ€œconnection.requestAirdrop” method will take two parameters. The first one is the public key of the account that will be receiving the airdrop and the second one is the amount it will be receiving as an airdrop.

In this case, it will receive a billion lamport equal to a Solana.

This txhash variable will provide us with a transaction hash that we can track down later on the blockchain explorer, such as Solana beach or solscan or Solana explorer etc.

Then just run the script to get the transaction hash on the terminal.

Copy the transaction hash from the terminal and move to “explorer.solana.com“. Check the cluster is switched to devnet as we are using the devnet network. Now paste the transaction hash on the search query. You will get all the details of the transaction, and the sender account must be credited with one sol.

You can visit the phantom wallet and check wallet 2. It must be credited with one sol. Now, if you want to airdrop more sol on the wallet2, you can change the figure on the requestAirdrop code and run the script again.

Step 6: Transfer Solana from one account to another

We have airdropped some balance in our sender wallet; now, Letโ€™s try to transfer some sol from the sender wallet to the receiver wallet. Again we need to wrap all the function calls inside an async() function.

(async () => {
  let transaction = new solanaweb3.Transaction().add(
    solanaweb3.SystemProgram.transfer({
      fromPubkey: senderWallet.publicKey,
      toPubkey: receiverWallet.publicKey,
      lamports: 2 * solanaweb3.LAMPORTS_PER_SOL,
    })
  );
  transaction.feePayer = senderWallet.publicKey;
  let transactionHash = await connection.sendTransaction(transaction, [
    senderWallet,
    receiverWallet,
  ]);
  console.log(`${transactionHash}`);
})();

We need to create a new transaction first, and then we need to initiate the โ€œSystemProgram.transferโ€ method.

SystemProgram is one of the native programs of Solana that is a handful for creating new accounts, allocating account data, assigning accounts to own programs, transferring lamports from System Program-owned accounts and paying transaction fees.

We will utilize the transfer method of the SystemProgram to transfer sol from the sender wallet to the receiver wallet.

๐ŸŒ Reference

This โ€œSystemProgram.transferโ€ method asks for three parameters. They are the public key of the wallet that will be used for sending sol, the public key of the wallet that will receive the amount, and the amount of lamports you ask to transfer.

We need to confirm the feepayer for the transaction. Otherwise, the transaction will not take place. In this case, the sender wallet will pay the fee for the transaction.

Now we need to send this transaction to the devnet cluster. For that, we will call the sendTransaction method of the solanaweb3 that takes two parameters. One is the transaction itself, and the next is an array consisting of the sender and receiver Keypair. This will return a transaction hash again when you โ€œconsole.logโ€ on the terminal.

Before running the node, you need to bring the airdrop section under the comment or delete the portion if you want. Otherwise, this airdrop will again start executing. Letโ€™s call the node on the terminal.

Copy the transaction hash from the terminal and paste it on the Solana explorer. You can see the transfer from the sender’s wallet to the receiver’s wallet.

Now, you move to the phantom wallet extension. Check the balance of wallet 2 and wallet 3. You must see that your wallet 3 is credited with two sol. And if you check wallet 2, you will see the transfer balance and the transfer fee have been debited from the wallet.

So thatโ€™s all for today. You have seen how the Solana blockchain interacts with the Solana web3.js and how the transaction takes place on the Solana blockchain. I hope you enjoyed the tutorial. Thanks for being with me. ๐Ÿ™

๐ŸŒ Reference