I am trying to fetch newly created PDA(s) of my devnet deployed (anchor) program via solana-cli but I get AccountNotFound
.
Context:
program:
use anchor_lang::prelude::*;
declare_id!("hqgrvUepLLhFbXCb8woduWM62ps5rqap3TmPHbpuK11");
pub const BOYNC_AUCTION_PDA_SEED: &[u8] = b"auction";
#[program]
pub mod boync_anchor_program {
use super::*;
pub fn initialize(ctx: Context<Initialize>, name: String, token: Pubkey) -> Result<()> {
if name.as_bytes().len() > 64 {
return err!(ErrorCode::UserNameTooLong);
}
let user_data = &mut ctx.accounts.user_data;
user_data.name = name;
user_data.token = token;
user_data.authority = ctx.accounts.authority.key();
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(mut)]
pub authority: Signer<'info>,
#[account(
init,
payer = authority,
space = BOYNC_AUCTION_DATA_LEN,
seeds = [BOYNC_AUCTION_PDA_SEED.as_ref(), authority.key().as_ref()],
bump,
)]
pub user_data: Account<'info, BoyncAuctionData>,
pub system_program: Program<'info, System>,
}
pub const BOYNC_AUCTION_DATA_LEN: usize = 32 + 32 + (64 + 4) + 8;
#[account]
pub struct BoyncAuctionData {
pub authority: Pubkey,
pub token: Pubkey,
pub name: String,
}
#[error_code]
pub enum ErrorCode {
#[msg("User name can only be 64 chars long.")]
UserNameTooLong,
}
client:
const token: PublicKey = new PublicKey(<some_token_public_key>);
const [_bobAuctionPDA, _] = await PublicKey
.findProgramAddress(
[
anchor.utils.bytes.utf8.encode('auction'),
anchorProvider.wallet.publicKey.toBuffer(),
],
program.programId
);
try {
const _bobAuctionData = await program.account.boyncAuctionData.fetch(_bobAuctionPDA);
if (_bobAuctionData != null || typeof _bobAuctionData != "undefined") {
console.log(
`[Anchor] Boync Auction with Bob User PDA ${_bobAuctionPDA.toBase58()} already defined:`
);
return;
}
} catch (error) {
console.log(`[Anchor] Account ${_bobAuctionPDA.toBase58()}, does not exist ... move on to creating it!`);
const tx = await program.methods
.initialize('Bob', token)
.accounts({
authority: anchorProvider.wallet.publicKey,
userData: _bobAuctionPDA,
})
.rpc();
console.log('[Anchor] Done, tx:', tx);
}
Then fetching the newly created account via:
const bobAuctionData = await program.account.boyncAuctionData.fetch(bobAuctionPDA);
console.log('[Anchor] Done.');
console.log(`Auction Data: { name: ${bobAuctionData.name}, authority: ${bobAuctionData.authority.toBase58()}, token: ${bobAuctionData.token.toBase58()}`);
Everything works perfectly here ^^. I get my account with expected data inside it. Solana explorer finds the account too (but none of it's "account data" such as 'owner' and 'token' fields, what's up with that?)
But if I try to fetch it via:
solana account <address>
or
@solana/web3.js -> connection.getAccountInfo
I get AccountNotFound.
What am I missing / doing wrong? Are PDAs special in this regard?
EDIT: Ok, I think that the RPC endpoint spawned by anchor localnet --provider.cluster devnet
does not in fact communicate with the devnet but still hangs on to some local instance.
In my Anchor.toml
:
[features]
seeds = false
[programs.devnet]
boync_anchor_program = "hqgrvUepLLhFbXCb8woduWM62ps5rqap3TmPHbpuK11"
[registry]
url = "https://anchor.projectserum.com"
[provider]
cluster = "devnet"
wallet = "/Users/<username>/.config/solana/id.json"
[scripts]
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"
start = "yarn run ts-node app/client/main.ts"
The node script runs fine but I see no instructions passed to my devnet program hence no PDA being created. The functions inside the script:
await program.account.boyncAuctionData.fetch()
and await program.methods .initialize() ...
seem to work.
I've checked the connection object from my provider and it seem to have the correct rpcEndpoint set:
AnchorProvider]: AnchorProvider {
connection: Connection {
_commitment: 'processed',
_confirmTransactionInitialTimeout: undefined,
_rpcEndpoint: 'https://api.devnet.solana.com',
_rpcWsEndpoint: 'wss://api.devnet.solana.com/',
_rpcClient: ClientBrowser {
options: [Object],
callServer: [AsyncFunction (anonymous)]
},
_rpcRequest: [Function (anonymous)],
_rpcBatchRequest: [Function (anonymous)],
_rpcWebSocket: Client {
_events: [Events <Complex prototype>],
_eventsCount: 10,
webSocketFactory: [Function: _default],
queue: {},
rpc_id: 0,
address: 'wss://api.devnet.solana.com/',
autoconnect: false,
ready: false,
reconnect: true,
reconnect_interval: 1000,
max_reconnects: Infinity,
rest_options: {},
current_reconnects: 0,
generate_request_id: [Function (anonymous)]
},
...
Why is it that I cannot talk to devnet via anchor-cli? Can I only talk to devnet if I connect to solana-wallet-providers (connect to phantom via front)?
Thanks!
solana account <address>
will always return the raw bytes if there is any data on chain. Are you sure you are connected to devnet with the solana cli? Usesolana config get
. Also, solana explorer does not know how to deserialize your custom owner and token fields, hence they will not show there human readable.