Via CLI, this works: NEAR_ENV=testnet near view dev-1643292007908-55838431863482 nft_tokens_for_owner '{"account_id": "hatchet.testnet"}'
and produces the expected result.
I'm now trying to do the same thing via near-api-js but am getting:
Unhandled Runtime Error
Error: Querying [object Object] failed: wasm execution failed with error: FunctionCallError(HostError(GuestPanic { panic_msg: "panicked at 'Failed to deserialize input from JSON.: Error(\"the account ID is invalid\", line: 1, column: 17)', src/contract/nft.rs:65:1" })).
{
"error": "wasm execution failed with error: FunctionCallError(HostError(GuestPanic { panic_msg: \"panicked at 'Failed to deserialize input from JSON.: Error(\\\"the account ID is invalid\\\", line: 1, column: 17)', src/contract/nft.rs:65:1\" }))",
"logs": [],
"block_height": 81208522,
"block_hash": "5vWcrkVjshewYgLZTTHTZgLN7SF3qpYPovnPUUM1ucBt"
}
Call Stack
JsonRpcProvider.query
node_modules/near-api-js/lib/providers/json-rpc-provider.js (123:0)
async Account.viewFunction
node_modules/near-api-js/lib/account.js (366:0)
I've tried multiple totally separate approaches using near-api-js, and they both result in this error.
My current approach is:
export type NFT = Contract & {
nft_mint: (args: any, gas: any, depositAmount: any) => Promise<any>; // TODO Add types
nft_token: (args: any) => Promise<any>;
nft_tokens_for_owner: (args: any) => Promise<any>;
};
export function getNftContract(account: Account) {
const contract = new Contract(
account, // the account object that is connecting
certificateContractName,
{
viewMethods: ['nft_token', 'nft_tokens_for_owner'], // view methods do not change state but usually return a value
changeMethods: ['nft_mint'], // change methods modify state
},
);
return contract;
}
async function getCertificates(accountId: string): Promise<string[]> {
const keyStore = new BrowserLocalStorageKeyStore();
const near = await getNearConnection(keyStore);
const account = new Account(near.connection, ''); // account_id not required for 'view' call
const contract = getNftContract(account);
const response = await (contract as NFT).nft_tokens_for_owner({ account_id: accountId });
console.log({ account, accountId, response });
return []; // TODO
}
I'm using testnet, and the accountId I'm passing is hatchet.testnet
.
This was a good lesson for me.
I started looking at the source code of https://docs.rs/near-sdk/3.1.0/src/near_sdk/json_types/account.rs.html#63 and https://docs.rs/near-sdk/3.1.0/src/near_sdk/environment/env.rs.html#816-843
I homed in on that "The account ID is invalid" error message.
But I knew I was passing a valid account ID.
It turns out the problem had nothing to do with NEAR. It was a Next.js / React problem:
My component's account_id was temporarily empty and trying to call nft_tokens_for_owner
too soon (i.e. before account_id had been populated with a value).