Skip to main content

Working with CW20 Data

Users will receive CW20 tokens as rewards in the game. How can we find out how many CW20 tokens each user has? You can use LCDClient to send a Query and retrieve CW20 token data. Let's fetch information about the CW20 token you created in the previous step. The contract address for the MCT token used in the example is xpla1xljvdrtyn86kv7hrdhae4qxdy8krajah3w7xhtyrt0n69und9xdqdhrasc.

Preview

Here's how you can fetch CW20 token data using JavaScript. In the code below, replace the contract address you've created on line 9, and on line 10, put the wallet address that holds the CW20 tokens. Give it a moment, and you'll see the execution results on the right side. Just tweak those lines, and you're good to go!

const { LCDClient } = require("@xpla/xpla.js");

const lcd = new LCDClient({
  chainID: 'cube_47-5',
  URL: 'https://cube-lcd.xpla.dev'
});

async function main() {
    const contractAddress = "xpla1xljvdrtyn86kv7hrdhae4qxdy8krajah3w7xhtyrt0n69und9xdqdhrasc";
    const userAddress = "xpla1cwduqw0z8y66mnfpev2mvrzzzu98tuexepmwrk";
    const msg = {
        balance : {
            address : userAddress
        }
    };

    const balance = await lcd.wasm.contractQuery(contractAddress, msg);
    console.log(balance);
}
main()

We were able to use LCDClient to send a query and find out how many CW20 tokens a specific wallet address holds. As a result, we can discover how many CW20 tokens the game users possess.

You can also send queries to the contract using the XPLA Explorer. Search for the CW20 token contract address on the XPLA Explorer and navigate to the Init Msg tab. This way, you can explore the CW20 token contract address through the XPLA Explorer and access the Init Msg tab.

https://explorer.xpla.io/testnet/address/xpla1xljvdrtyn86kv7hrdhae4qxdy8krajah3w7xhtyrt0n69und9xdqdhrasc#InitMsg
vaultimgcard

Afterwards, if you click the Query button on the right side, you'll see a popup that allows you to compose a Query message. Through this, you can easily send a query to the contract without any hassle.

https://explorer.xpla.io/testnet/address/xpla1xljvdrtyn86kv7hrdhae4qxdy8krajah3w7xhtyrt0n69und9xdqdhrasc#InitMsg
vaultimgcard

When sending a query from XPLA Explorer, write it in JSON format.

One thing to keep in mind is that unlike writing messages in JavaScript code, you should compose it in the JSON format as shown below.

{
"balance" : {
"address" : "xpla1cwduqw0z8y66mnfpev2mvrzzzu98tuexepmwrk"
}
}
How should I format the contract query message?

You can explore the CW20 contract on GitHub to see what kind of queries you can send to it. Just remember, even though the message names in QueryMsg are written in Camel Case, you need to send them in Snake Case when actually sending the query. For the parameters, you input them exactly as they appear in the code.

For example, let's take a look at the Balance and TokenInfo messages on the CW20 GitHub page.

pub enum Cw20QueryMsg {
/// Returns the current balance of the given address, 0 if unset.
/// Return type: BalanceResponse.
Balance { address: String },
/// Returns metadata on the contract - name, decimals, supply, etc.
/// Return type: TokenInfoResponse.
TokenInfo {},

When sending a Balance query, you should change the Camel Case Balance to Snake Case, which becomes balance. As for the parameter, which is { address: String }, you input the wallet address you want to check the balance for as a String.

So, the final format of the query message would be like this:

{
balance : {
address : "xpla1cwduqw0z8y66mnfpev2mvrzzzu98tuexepmwrk"
}
}

Sending a TokenInfo query is the same. You change the Camel Case TokenInfo to Snake Case, which becomes token_info. Since there are no parameters in this case, the final format of the query message would be:

{
token_info : {}
}

Feel free to use these examples to send various queries to your contract!


We've learned how to send a query to the contract and how to compose a query message. Now, let's delve into analyzing the Preview Code. If you've understood the Preview Code, feel free to skip reading the following content and proceed directly to the next step.

Fetching CW20 Data with Javascript

Let's check how much CW20 tokens a specific wallet address holds using JavaScript code.

Running the Code

  1. Please create a file named "example-query-cw20.js".

  2. Copy and paste the code below into the "example-query-cw20.js" file, then save it.

    const { LCDClient } = require("@xpla/xpla.js");

    const lcd = new LCDClient({
    chainID: 'cube_47-5',
    URL: 'https://cube-lcd.xpla.dev'
    });

    async function main() {
    const contractAddress = "xpla1xljvdrtyn86kv7hrdhae4qxdy8krajah3w7xhtyrt0n69und9xdqdhrasc";
    const userAddress = "xpla1cwduqw0z8y66mnfpev2mvrzzzu98tuexepmwrk";
    const msg = {
    balance : {
    address : userAddress
    }
    };

    const balance = await lcd.wasm.contractQuery(contractAddress, msg);
    console.log(balance);
    }
    main()
  3. Instead of xpla1xljvdrtyn86kv7hrdhae4qxdy8krajah3w7xhtyrt0n69und9xdqdhrasc on line 9, enter the contract address of the CW20 token you created. Also, replace xpla1cwduqw0z8y66mnfpev2mvrzzzu98tuexepmwrk on line 10 with the wallet address that holds the CW20 tokens.

  4. Enter the following command in the VSCode Terminal.

    node example-query-cw20.js
  5. Check the results in the Terminal. You'll be able to see how many CW20 tokens the userAddress wallet holds.

Explanation

The desired query message is placed in the msg variable.

const msg = {
balance : {
address : userAddress
}
};
How should I format the contract query message?

You can explore the CW20 contract on GitHub to see what kind of queries you can send to it. Just remember, even though the message names in QueryMsg are written in Camel Case, you need to send them in Snake Case when actually sending the query. For the parameters, you input them exactly as they appear in the code.

For example, let's take a look at the Balance and TokenInfo messages on the CW20 GitHub page.

pub enum Cw20QueryMsg {
/// Returns the current balance of the given address, 0 if unset.
/// Return type: BalanceResponse.
Balance { address: String },
/// Returns metadata on the contract - name, decimals, supply, etc.
/// Return type: TokenInfoResponse.
TokenInfo {},

When sending a Balance query, you should change the Camel Case Balance to Snake Case, which becomes balance. As for the parameter, which is { address: String }, you input the wallet address you want to check the balance for as a String.

So, the final format of the query message would be like this:

{
balance : {
address : "xpla1cwduqw0z8y66mnfpev2mvrzzzu98tuexepmwrk"
}
}

Sending a TokenInfo query is the same. You change the Camel Case TokenInfo to Snake Case, which becomes token_info. Since there are no parameters in this case, the final format of the query message would be:

{
token_info : {}
}

Feel free to use these examples to send various queries to your contract!


We're using the contractQuery function of LCDClient to send a query to the contract. Based on the query message we've provided, we can receive data from the contract. Let's check if the user's balance is being displayed correctly in the logs.

const balance = await lcd.wasm.contractQuery(contractAddress, msg);
console.log(balance);

Wrapping Up

We've gone through the process of sending queries to the CW20 contract, which has enabled us to find out how much CW20 tokens a specific wallet address holds.

By referring to the CW20 GitHub, you can delve deeper into the queries that can be sent to the CW20 contract. Adapt the process to fetch CW20 data from the contract according to your game's needs, and let's make the game more enjoyable for the users.