'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 walletBalance
inside 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 |