'Airdropping Solana to a Specific Account
I would like to airdrop sols into a specific account to get my smart contract to fire an anchor test. Whenever I run my test I come across the error Error: Account BdFchxtKbEaWtsbuFX2nbKyZCjhz5LN8vyPukQzJQrME has insufficient funds for spend (1.30250136 SOL) + fee (0.000945 SOL) There was a problem deploying: Output { status: ExitStatus(ExitStatus(256)), stdout: "", stderr: "" }.
The error is self-explanatory but how do I airdrop tokens to that specific account, I can run solana airdrop 5
but then it airdrops it to another account GgRbD2AdibdAtBrQMJJEooco9gKt48Sd98Gn7vZQ1nJK.
I even tried transferring the tokens from one account to another using solana transfer BdFchxtKbEaWtsbuFX2nbKyZCjhz5LN8vyPukQzJQrME 5 --allow-unfunded-recipient
but the transaction is just hanging.
Below is my smart contract in Rust using Anchor:
use anchor_lang::prelude::*;
use anchor_lang::solana_program::system_program;
declare_id!("BNDCEb5uXCuWDxJW9BGmbfvR1JBMAKckfhYrEKW2Bv1W");
#[program]
pub mod solana_twitter {
use super::*;
pub fn send_tweet(ctx: Context<SendTweet>, topic: String, content: String) -> ProgramResult {
let tweet: &mut Account<Tweet> = &mut ctx.accounts.tweet;
let author: &Signer = &ctx.accounts.author;
let clock: Clock = Clock::get().unwrap();
if topic.chars().count() > 50 {
return Err(ErrorCode::TopicTooLong.into())
}
if content.chars().count() > 280 {
return Err(ErrorCode::ContentTooLong.into())
}
tweet.author = *author.key;
tweet.timestamp = clock.unix_timestamp;
tweet.topic = topic;
tweet.content = content;
Ok(())
}
}
#[derive(Accounts)]
pub struct SendTweet<'info> {
#[account(init, payer = author, space = Tweet::LEN)]
pub tweet: Account<'info, Tweet>,
#[account(mut)]
pub author: Signer<'info>,
#[account(address = system_program::ID)]
pub system_program: AccountInfo<'info>,
}
#[account]
pub struct Tweet {
pub author: Pubkey,
pub timestamp: i64,
pub topic: String,
pub content: String,
}
#[error]
pub enum ErrorCode {
#[msg("The provided topic should be 50 characters long maximum.")]
TopicTooLong,
#[msg("The provided content should be 280 characters long maximum.")]
ContentTooLong,
}
And below is my test in Typescript:
import * as anchor from '@project-serum/anchor';
import { Program } from '@project-serum/anchor';
import { SolanaTwitter } from '../target/types/solana_twitter';
import * as assert from "assert";
import * as bs58 from "bs58";
describe('solana-twitter', () => {
// Configure the client to use the local cluster.
anchor.setProvider(anchor.Provider.env());
const program = anchor.workspace.SolanaTwitter as Program<SolanaTwitter>;
it('can send a new tweet', async () => {
// Call the "SendTweet" instruction.
const tweet = anchor.web3.Keypair.generate();
await program.rpc.sendTweet('veganism', 'Hummus, am I right?', {
accounts: {
tweet: tweet.publicKey,
author: program.provider.wallet.publicKey,
systemProgram: anchor.web3.SystemProgram.programId,
},
signers: [tweet],
});
// Fetch the account details of the created tweet.
const tweetAccount = await program.account.tweet.fetch(tweet.publicKey);
// Ensure it has the right data.
assert.equal(tweetAccount.author.toBase58(), program.provider.wallet.publicKey.toBase58());
assert.equal(tweetAccount.topic, 'veganism');
assert.equal(tweetAccount.content, 'Hummus, am I right?');
assert.ok(tweetAccount.timestamp);
});
it('can send a new tweet without a topic', async () => {
// Call the "SendTweet" instruction.
const tweet = anchor.web3.Keypair.generate();
await program.rpc.sendTweet('', 'gm', {
accounts: {
tweet: tweet.publicKey,
author: program.provider.wallet.publicKey,
systemProgram: anchor.web3.SystemProgram.programId,
},
signers: [tweet],
});
// Fetch the account details of the created tweet.
const tweetAccount = await program.account.tweet.fetch(tweet.publicKey);
// Ensure it has the right data.
assert.equal(tweetAccount.author.toBase58(), program.provider.wallet.publicKey.toBase58());
assert.equal(tweetAccount.topic, '');
assert.equal(tweetAccount.content, 'gm');
assert.ok(tweetAccount.timestamp);
});
it('can send a new tweet from a different author', async () => {
// Generate another user and airdrop them some SOL.
const otherUser = anchor.web3.Keypair.generate();
const signature = await program.provider.connection.requestAirdrop(otherUser.publicKey, 1000000000);
await program.provider.connection.confirmTransaction(signature);
// Call the "SendTweet" instruction on behalf of this other user.
const tweet = anchor.web3.Keypair.generate();
await program.rpc.sendTweet('veganism', 'Yay Tofu!', {
accounts: {
tweet: tweet.publicKey,
author: otherUser.publicKey,
systemProgram: anchor.web3.SystemProgram.programId,
},
signers: [otherUser, tweet],
});
// Fetch the account details of the created tweet.
const tweetAccount = await program.account.tweet.fetch(tweet.publicKey);
// Ensure it has the right data.
assert.equal(tweetAccount.author.toBase58(), otherUser.publicKey.toBase58());
assert.equal(tweetAccount.topic, 'veganism');
assert.equal(tweetAccount.content, 'Yay Tofu!');
assert.ok(tweetAccount.timestamp);
});
it('cannot provide a topic with more than 50 characters', async () => {
try {
const tweet = anchor.web3.Keypair.generate();
const topicWith51Chars = 'x'.repeat(51);
await program.rpc.sendTweet(topicWith51Chars, 'Hummus, am I right?', {
accounts: {
tweet: tweet.publicKey,
author: program.provider.wallet.publicKey,
systemProgram: anchor.web3.SystemProgram.programId,
},
signers: [tweet],
});
} catch (error) {
assert.equal(error.msg, 'The provided topic should be 50 characters long maximum.');
return;
}
assert.fail('The instruction should have failed with a 51-character topic.');
});
it('cannot provide a content with more than 280 characters', async () => {
try {
const tweet = anchor.web3.Keypair.generate();
const contentWith281Chars = 'x'.repeat(281);
await program.rpc.sendTweet('veganism', contentWith281Chars, {
accounts: {
tweet: tweet.publicKey,
author: program.provider.wallet.publicKey,
systemProgram: anchor.web3.SystemProgram.programId,
},
signers: [tweet],
});
} catch (error) {
assert.equal(error.msg, 'The provided content should be 280 characters long maximum.');
return;
}
assert.fail('The instruction should have failed with a 281-character content.');
});
it('can fetch all tweets', async () => {
const tweetAccounts = await program.account.tweet.all();
assert.equal(tweetAccounts.length, 3);
});
it('can filter tweets by author', async () => {
const authorPublicKey = program.provider.wallet.publicKey
const tweetAccounts = await program.account.tweet.all([
{
memcmp: {
offset: 8, // Discriminator.
bytes: authorPublicKey.toBase58(),
}
}
]);
assert.equal(tweetAccounts.length, 2);
assert.ok(tweetAccounts.every(tweetAccount => {
return tweetAccount.account.author.toBase58() === authorPublicKey.toBase58()
}))
});
it('can filter tweets by topics', async () => {
const tweetAccounts = await program.account.tweet.all([
{
memcmp: {
offset: 8 + // Discriminator.
32 + // Author public key.
8 + // Timestamp.
4, // Topic string prefix.
bytes: bs58.encode(Buffer.from('veganism')),
}
}
]);
assert.equal(tweetAccounts.length, 2);
assert.ok(tweetAccounts.every(tweetAccount => {
return tweetAccount.account.topic === 'veganism'
}))
});
});
Update
Simply airdropping to the specific account helped, solana airdrop 3 <Account Address>
. Another related problem was that my local cluster was hanging, to resolve this I followed the steps below:
- Checked if local chain was running ps au
- killed local solana-test-validator process
- Cleaned out the workspace cargo clean
- Deleted node_modules rm -rf node_modules
- Reinstalled node modules yarn install
- Re-ran tests anchor test
Solution 1:[1]
first of all, try to ensure that the provider section of your anchor.toml set to testnet like this
[provider]
cluster = "testnet"
wallet = "/home/yourname/.config/solana/id.json"
also, use this command to set cluster for testnet
solana config set --url https://api.testnet.solana.com
check active account in your solana running node with
solana address
it should show your running node active account public key
also, check account balance with
solana balance
and if you don't have enough sol to run your test or deploy(after test) you can airdrop sol by running
solana airdrop 1
the point is trying to airdrop 1 sol at a time(multiple times)
now you can run the anchor test again(after anchor build)
Solution 2:[2]
You have to specify the url when airdropping. I think max you can airdrop 2
solana airdrop 2 2QdQZvax3uzxRWc58PR4weAX4e1AZb3c9Wfn5NtzK7Sb --url devnet
If this hangs or fails that is because solana devnet server is going down very often. Visit this https://api.devnet.solana.com/
and click on What's the status of this server?
if server is down you will see error message
if not you see 200 Ok
message
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 | Setmax |
Solution 2 |