'Properly Convert Lamports to SOL

Testing out devnet and airdrops. Below is my code for a basic wallet with a 2 sol airdrop. I am trying to convert Lamports back into SOL by dividing LAMPARTS_PER_SOL constant. The expected output should be Wallet balance is 2 when dividing by the constant mentioned above, instead it's Wallet balance is 0. How can I resolve this?

My code:

   const {
  Connection,
  PublicKey,
  clusterApiUrl,
  Keypair,
  LAMPORTS_PER_SOL,
} = require("@solana/web3.js");

const wallet = new Keypair();

const publicKey = new PublicKey(wallet._keypair.publicKey);
const secretKey = wallet._keypair.secretKey;

const getWalletBalance = async () => {
  try {
    const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
    const walletBalance = await connection.getBalance(publicKey);
    console.log(`Wallet balance is ${walletBalance}`);
  } catch (err) {
    console.error(err);
  }
};
const airDropSol = async () => {
  try {
    const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

    const fromAirDropSignature = await connection.requestAirdrop(
      publicKey,
      (2 * LAMPORTS_PER_SOL) /= LAMPORTS_PER_SOL
    );

    await connection.confirmTransaction(fromAirDropSignature);
  } catch (err) {
    console.log(err);
  }
};
const main = async () => {
  await getWalletBalance();
  await airDropSol();
  await getWalletBalance();
};
main();


Solution 1:[1]

There is not much that I could find for my particular situation since Solana development is so new, but I was able to resolve it when stumbling upon the parseFloat() method.

I first had to remove the quotient from the const fromAirDropSignature and prepend the parseFloat() method to walletBalanceinside the console.log section.

Intial code:

    const getWalletBalance = async () => {
  try {
    const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
    const walletBalance = await connection.getBalance(publicKey);
    console.log(`Wallet balance is ${walletBalance}`);
  } catch (err) {
    console.error(err);
  }
};
const airDropSol = async () => {
  try {
    const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

    const fromAirDropSignature = await connection.requestAirdrop(
      publicKey,
      (2 * LAMPORTS_PER_SOL) /= LAMPORTS_PER_SOL
    );

Output:

    Wallet balance is 0

Working Code:

const getWalletBalance = async () => {
  try {
    const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
    const walletBalance = await connection.getBalance(publicKey);
    console.log(
      `Wallet balance is ${parseFloat(walletBalance) / LAMPORTS_PER_SOL} SOL`
    );
  } catch (err) {
    console.error(err);
  }
};
const airDropSol = async () => {
  try {
    const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

    const fromAirDropSignature = await connection.requestAirdrop(
      publicKey,
      1.0024 * LAMPORTS_PER_SOL
    );

Output:

Wallet balance is 1.0024 SOL

One thing I notice is that when using 'devnet', it will not allow a denomination higher than 2. Any integer below that will work.

Solution 2:[2]

In all libraries, I think that there are auxiliary operations to perform these conversions, in the library Solnet for .Net we do this operation:

decimal ConvertToSol(ulong lamports)
{
  return decimal.Round((decimal)lamports / 1000000000m, 9);
}

If you translate it to JS it will give you the same result and it works for you

Solution 3:[3]

So you can convert the walletBalance to Javascript's BigInt, so that you can easily divide by BigInt(LAMPORTS_PER_URL)

const {
        Connection,
        PublicKey,
        clusterApiUrl,
        Keypair,
        LAMPORTS_PER_SOL,
      } = require("@solana/web3.js");
      const wallet = new Keypair();
      const publicKey = new PublicKey(wallet._keypair.publicKey);
      const secretKey = wallet._keypair.secretKey;
      
      const getWalletBalance = async () => {
        try {
          const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
          let walletBalance = await connection.getBalance(publicKey);
          **walletBalance = BigInt(walletBalance) / BigInt(LAMPORTS_PER_SOL)**
          console.log(`Wallet balance is ${walletBalance}`);
        } catch (err) {
          console.error(err);
        }
      };
      const airDropSol = async () => {
        try {
          const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
      
          const fromAirDropSignature = await connection.requestAirdrop(
            publicKey,
            2 * LAMPORTS_PER_SOL
          );
      
          await connection.confirmTransaction(fromAirDropSignature);
        } catch (err) {
          console.log(err);
        }
      };
      const main = async () => {
        await getWalletBalance();
        await airDropSol();
        await getWalletBalance();
      };
      main();

Solution 4:[4]

What you are experiencing is due to limitations of airdrop functionality on SOLANA Devnet and Testnet. According to official documentation: "Note that airdrops are only available on Devnet and Testnet. Both are limited to 1 SOL per request."

Reference: https://docs.solana.com/running-validator/validator-start

Interesting fact is that the documentation is inconsistent. Why? Because it states it is limited to 1 SOL, while I'm still able to send 1.9 SOL for example (but not 2 or more).

Example:

const
    {
        Connection,
        PublicKey,
        clusterApiUrl,
        Keypair,
        LAMPORTS_PER_SOL
    } = require("@solana/web3.js")

const wallet = new Keypair()

const publicKey = new PublicKey(wallet._keypair.publicKey)
const secretKey = wallet._keypair.secretKey

const getWalletBalance = async () => {
    try {
        const connection = new Connection(clusterApiUrl('devnet'), 'confirmed')
        const walletBalance = await connection.getBalance(publicKey)
        console.log(`Wallet balance is ${walletBalance / LAMPORTS_PER_SOL} SOL`)
    } catch (err) {
        console.error(err)
    }
}

async function airDropSol(tokenNumber) {
    try {
        const connection = new Connection(clusterApiUrl('devnet'), 'confirmed')
        const fromAirDropSignature = await connection.requestAirdrop(publicKey, tokenNumber * LAMPORTS_PER_SOL)
        await connection.confirmTransaction(fromAirDropSignature)
    } catch (err) {
        console.error(err)
    }
}

const main = async () => {
    await getWalletBalance()
    // argument <= 2.0
    await airDropSol(1.9)
    await getWalletBalance()
}
main()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 user2873003
Solution 2 Moatasem La Kremed
Solution 3 oyinda david
Solution 4 Ozren Cecelja