Reading User Wallets
Fetch a wallet's data and see what tokens are inside.
Fetching wallets is crucial because it allows you to see the contents of a wallet, including all tokens held within.
This is especially important in gaming and app development as it enables you to assign specific utilities or benefits to certain tokens.
For example, if a user has a particular token in their wallet, they might gain access to exclusive in-game items or features within an app, enhancing the user experience and adding value to the tokens.
What you'll need:
Best Practices
- Only pull data from the collections you need. This will improve performance and ensure your backend infrastructure remains scalable.
- Always read and check the balance. Sometimes, the player may appear to hold the token but the balance is actually zero, for instance, if the token has been burned. These burned tokens should not have in-game utility.
- Consider whether you want NFTs that are listed on a marketplace to have utility in your game. Items that are listed for sale don't show up in regular token balance and show up in reserved balance instead. If you want them to have utility, you can check the reserved balance and include the reserved supply.
- Consider if you need to use pagination. Users can have hundreds of tokens, in this situation you will need to read them in multiple calls.
- If you plan to utilize metadata from on-chain or external sources, it's important to also read the token's attributes. Typically, you'll find a "uri" attribute that points to the external location of this metadata.
- When accessing external metadata or media, make sure to do so asynchronously and think about storing it in a local cache for faster retrieval.
Fetching a wallet with the Enjin API
Fetching wallet's Enjin Coin balance
Use the GetWallet
query and include the the balances
in the query response to see how much ENJ a wallet holds.
Query:
query FetchWalletBalance{
GetWallet(account: "cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f"){ #Specify the account address
balances{
free
reserved
}
}
}
curl --location 'https://platform.canary.enjin.io/graphql' \
-H 'Content-Type: application/json' \
-H 'Authorization: enjin_api_key' \
-d '{"query":"query FetchWalletBalance($account: String!) {\r\n GetWallet(account: $account) {\r\n balances {\r\n free\r\n reserved\r\n }\r\n }\r\n}","variables":{"account":"cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f"}}'
using System.Text.Json;
using Enjin.Platform.Sdk;
// Setup the query
var getWallet = new GetWallet()
.SetAccount("cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f");
// Define and assign the return data fragment to the query
var walletFragment = new WalletFragment()
.WithBalances(new BalancesFragment()
.WithFree()
.WithReserved()
);
getWallet.Fragment(walletFragment);
// Create and auth a client to send the request to the platform
var client = PlatformClient.Builder()
.SetBaseAddress("https://platform.canary.enjin.io")
.Build();
client.Auth("Your_Platform_Token_Here");
// Send the request and write the output to the console.
// Only the fields that were requested in the fragment will be filled in,
// other fields which weren't requested in the fragment will be set to null.
var response = await client.SendGetWallet(getWallet);
Console.WriteLine(JsonSerializer.Serialize(response.Result.Data));
#include "EnjinPlatformSdk/CoreQueries.hpp"
#include <iostream>
using namespace enjin::platform::sdk;
using namespace std;
int main() {
// Set up the query
GetWallet getWallet = GetWallet()
.SetAccount(make_shared<SerializableString>("cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f"));
// Define and assign the return data fragments to the query
WalletFragment walletFragment = WalletFragment();
BalancesFragment balancesFragment = BalancesFragment()
.WithFree()
.WithReserved();
walletFragment.WithBalances(make_shared<BalancesFragment>(balancesFragment));
getWallet.SetFragment(make_shared<WalletFragment>(walletFragment));
// Create and auth a client to send the request to the platform
unique_ptr<PlatformClient> client = PlatformClient::Builder()
.SetBaseAddress("https://platform.canary.enjin.io")
.Build();
client->Auth("Your_Platform_Token_Here");
// Send the request then get the response and write the output to the console.
// Only the fields that were requested in the fragment will be filled in,
// other fields which weren't requested in the fragment will be set to null.
future<PlatformResponsePtr<GraphQlResponse<Wallet>>> futureResponse = SendGetWallet(*client, getWallet);
// Get the platform response holding the HTTP data
PlatformResponsePtr<GraphQlResponse<Wallet>> response = futureResponse.get();
// Get the result, a GraphQL response, holding the GraphQL data
const optional<GraphQlResponse<Wallet>>& gqlResult = response->GetResult();
// Write the result data to the console
if (gqlResult.has_value() && gqlResult->IsSuccess())
{
const optional<Wallet>& getWalletResult = gqlResult->GetData()->GetResult();
std::cout << getWalletResult->GetBalances()->GetFree().value() << std::endl;
}
// Write any error messages to the console
if (gqlResult.has_value() && gqlResult->HasErrors())
{
const optional<vector<GraphQlError>>& errors = gqlResult->GetErrors();
for (const GraphQlError& error : errors.value()) {
std::cout << error.GetMessage().value() << std::endl;
}
}
client.reset();
return 0;
}
fetch('https://platform.canary.enjin.io/graphql', {
method: 'POST',
headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'},
body: JSON.stringify({
query: `
query FetchWalletBalance($account: String!) {
GetWallet(account: $account) {
balances{
free
reserved
}
}
}
`,
variables: {
account: "cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f" //Specify the account address
}
}),
})
.then(response => response.json())
.then(data => console.log(data));
const axios = require('axios');
axios.post('https://platform.canary.enjin.io/graphql', {
query: `
query FetchWalletBalance($account: String!) {
GetWallet(account: $account) {
balances{
free
reserved
}
}
}
`,
variables: {
account: "cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f" //Specify the account address
}
}, {
headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
import requests
query = '''
query FetchWalletBalance($account: String!) {
GetWallet(account: $account) {
balances{
free
reserved
}
}
}
'''
variables = {
'account': "cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f" #Specify the account address
}
response = requests.post('https://platform.canary.enjin.io/graphql',
json={'query': query, 'variables': variables},
headers={'Content-Type': 'application/json', 'Authorization': 'Your_Platform_Token_Here'}
)
print(response.json())
Response:
{
"data": {
"GetWallet": {
"balances": {
"free": "86010842630734264894", //~86.01084... ENJ
"reserved": "13900475000000000000" //~13.90047... ENJ
}
}
}
}
Balances Format
API balances fields are formatted as u128 number type.
to get decimal value, divide the value by 10^18.
Fetch a wallet's collections
Use the GetWallet
query and include the the collectionAccounts
in the query response to see what collections a wallet holds.
Query:
query FetchingWalletCollections{
GetWallet(account: "cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f"){ #Specify the account address
collectionAccounts{
edges{
node{
collection{
collectionId
attributes{
key
value
}
}
}
}
}
}
}
curl --location 'https://platform.canary.enjin.io/graphql' \
-H 'Content-Type: application/json' \
-H 'Authorization: enjin_api_key' \
-d '{"query":"query FetchingWalletCollections($account: String!) {\r\n GetWallet(account: $account) {\r\n collectionAccounts {\r\n edges {\r\n node {\r\n collection {\r\n collectionId\r\n attributes {\r\n key\r\n value\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}","variables":{"account":"cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f"}}'
using System.Text.Json;
using Enjin.Platform.Sdk;
// Setup the query
var getWallet = new GetWallet()
.SetAccount("cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f");
// Define and assign the return data fragment to the query
var walletFragment = new WalletFragment()
.WithCollectionAccounts(new ConnectionFragment<CollectionAccountFragment>()
.WithEdges(new EdgeFragment<CollectionAccountFragment>()
.WithNode(new CollectionAccountFragment()
.WithCollection(new CollectionFragment()
.WithCollectionId()
.WithAttributes(new AttributeFragment()
.WithKey()
.WithValue()
)
)
)
)
);
getWallet.Fragment(walletFragment);
// Create and auth a client to send the request to the platform
var client = PlatformClient.Builder()
.SetBaseAddress("https://platform.canary.enjin.io")
.Build();
client.Auth("Your_Platform_Token_Here");
// Send the request and write the output to the console.
// Only the fields that were requested in the fragment will be filled in,
// other fields which weren't requested in the fragment will be set to null.
var response = await client.SendGetWallet(getWallet);
Console.WriteLine(JsonSerializer.Serialize(response.Result.Data));
#include "EnjinPlatformSdk/CoreQueries.hpp"
#include <iostream>
using namespace enjin::platform::sdk;
using namespace std;
int main() {
// Set up the query
GetWallet getWallet = GetWallet()
.SetAccount(make_shared<SerializableString>("cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f"));
// Define and assign the return data fragments to the query
AccountFragment accountFragment = AccountFragment()
.WithAddress();
WalletFragment walletFragment = WalletFragment()
.WithAccount(make_shared<AccountFragment>(accountFragment));
AttributeFragment attributeFragment = AttributeFragment()
.WithKey()
.WithValue();
CollectionFragment collectionFragment = CollectionFragment()
.WithCollectionId()
.WithAttributes(make_shared<AttributeFragment>(attributeFragment));
CollectionAccountFragment collectionAccountFragment = CollectionAccountFragment()
.WithCollection(make_shared<CollectionFragment>(collectionFragment));
EdgeFragment<CollectionAccountFragment> edgeFragment = EdgeFragment<CollectionAccountFragment>()
.WithNode(make_shared<CollectionAccountFragment>(collectionAccountFragment));
ConnectionFragment<CollectionAccountFragment> connectionFragment = ConnectionFragment<CollectionAccountFragment>()
.WithEdges(make_shared<EdgeFragment<CollectionAccountFragment>>(edgeFragment));
walletFragment.WithCollectionAccounts(make_shared<ConnectionFragment<CollectionAccountFragment>>(connectionFragment));
getWallet.SetFragment(make_shared<WalletFragment>(walletFragment));
// Create and auth a client to send the request to the platform
unique_ptr<PlatformClient> client = PlatformClient::Builder()
.SetBaseAddress("https://platform.canary.enjin.io")
.Build();
client->Auth("Your_Platform_Token_Here");
// Send the request then get the response and write the output to the console.
// Only the fields that were requested in the fragment will be filled in,
// other fields which weren't requested in the fragment will be set to null.
future<PlatformResponsePtr<GraphQlResponse<Wallet>>> futureResponse = SendGetWallet(*client, getWallet);
// Get the platform response holding the HTTP data
PlatformResponsePtr<GraphQlResponse<Wallet>> response = futureResponse.get();
// Get the result, a GraphQL response, holding the GraphQL data
const optional<GraphQlResponse<Wallet>>& gqlResult = response->GetResult();
// Write the result data to the console
if (gqlResult.has_value() && gqlResult->IsSuccess())
{
const optional<Wallet>& getWalletResult = gqlResult->GetData()->GetResult();
std::cout << getWalletResult->GetAccount()->GetAddress().value() << std::endl;
}
// Write any error messages to the console
if (gqlResult.has_value() && gqlResult->HasErrors())
{
const optional<vector<GraphQlError>>& errors = gqlResult->GetErrors();
for (const GraphQlError& error : errors.value()) {
std::cout << error.GetMessage().value() << std::endl;
}
}
client.reset();
return 0;
}
fetch('https://platform.canary.enjin.io/graphql', {
method: 'POST',
headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'},
body: JSON.stringify({
query: `
query FetchingWalletCollections($account: String!) {
GetWallet(account: $account) {
collectionAccounts{
edges{
node{
collection{
collectionId
attributes{
key
value
}
}
}
}
}
}
}
`,
variables: {
account: "cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f" //Specify the account address
}
}),
})
.then(response => response.json())
.then(data => console.log(data));
const axios = require('axios');
axios.post('https://platform.canary.enjin.io/graphql', {
query: `
query FetchingWalletCollections($account: String!) {
GetWallet(account: $account) {
collectionAccounts{
edges{
node{
collection{
collectionId
attributes{
key
value
}
}
}
}
}
}
}
`,
variables: {
account: "cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f" //Specify the account address
}
}, {
headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
import requests
query = '''
query FetchingWalletCollections($account: String!) {
GetWallet(account: $account) {
collectionAccounts{
edges{
node{
collection{
collectionId
attributes{
key
value
}
}
}
}
}
}
}
'''
variables = {
'account': "cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f" #Specify the account address
}
response = requests.post('https://platform.canary.enjin.io/graphql',
json={'query': query, 'variables': variables},
headers={'Content-Type': 'application/json', 'Authorization': 'Your_Platform_Token_Here'}
)
print(response.json())
Response:
{
"data": {
"GetWallet": {
"collectionAccounts": {
"edges": [
{
"node": {
"collection": {
"collectionId": "33866",
"attributes": []
}
}
},
{
"node": {
"collection": {
"collectionId": "36105",
"attributes": [
{
"key": "name",
"value": "My test collection"
}
]
}
}
},
{
"node": {
"collection": {
"collectionId": "36623",
"attributes": [
{
"key": "name",
"value": "Docs Testing Collection"
}
]
}
}
}
]
}
}
}
}
Using Pagination
The response may be displayed on several pages. To view all of it, you may need to follow steps for pagination which allows you to flip through the pages.
Fetch a wallet's tokens
Use the GetWallet
query and include the the tokenAccounts
in the query response to see what tokens a wallet holds.
Query:
query FetchingWalletTokens{
GetWallet(account: "cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f"){ #Specify the account address
tokenAccounts{
edges{
node{
balance
token{
tokenId
collection{
collectionId
}
attributes{
key
value
}
}
}
}
}
}
}
curl -X POST "https://platform.enjin.io/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: enjin_api_key" \
-d '{"query": "query FetchingWalletTokens { GetWallet(account: \"cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f\") { tokenAccounts { edges { node { balance token { tokenId collection { collectionId } attributes { key value } } } } } } }"}'
using System.Text.Json;
using Enjin.Platform.Sdk;
// Setup the query
var getWallet = new GetWallet()
.SetAccount("cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f");
// Define and assign the return data fragment to the query
var walletFragment = new WalletFragment()
.WithTokenAccounts(new ConnectionFragment<TokenAccountFragment>()
.WithEdges(new EdgeFragment<TokenAccountFragment>()
.WithNode(new TokenAccountFragment()
.WithBalance()
.WithToken(new TokenFragment()
.WithTokenId()
.WithCollection(new CollectionFragment()
.WithCollectionId()
)
.WithAttributes(new AttributeFragment()
.WithKey()
.WithValue()
)
)
)
)
);
getWallet.Fragment(walletFragment);
// Create and auth a client to send the request to the platform
var client = PlatformClient.Builder()
.SetBaseAddress("https://platform.canary.enjin.io")
.Build();
client.Auth("Your_Platform_Token_Here");
// Send the request and write the output to the console.
// Only the fields that were requested in the fragment will be filled in,
// other fields which weren't requested in the fragment will be set to null.
var response = await client.SendGetWallet(getWallet);
Console.WriteLine(JsonSerializer.Serialize(response.Result.Data));
#include "EnjinPlatformSdk/CoreQueries.hpp"
#include <iostream>
using namespace enjin::platform::sdk;
using namespace std;
int main() {
// Set up the query
GetWallet getWallet = GetWallet()
.SetAccount(make_shared<SerializableString>("cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f"));
// Define and assign the return data fragments to the query
AccountFragment accountFragment = AccountFragment()
.WithAddress();
WalletFragment walletFragment = WalletFragment()
.WithAccount(make_shared<AccountFragment>(accountFragment));
AttributeFragment attributeFragment = AttributeFragment()
.WithKey()
.WithValue();
CollectionFragment collectionFragment = CollectionFragment()
.WithCollectionId();
TokenFragment tokenFragment = TokenFragment()
.WithTokenId()
.WithCollection(make_shared<CollectionFragment>(collectionFragment))
.WithAttributes(make_shared<AttributeFragment>(attributeFragment));
TokenAccountFragment tokenAccountFragment = TokenAccountFragment()
.WithBalance()
.WithToken(make_shared<TokenFragment>(tokenFragment));
EdgeFragment<TokenAccountFragment> edgeFragment = EdgeFragment<TokenAccountFragment>()
.WithNode(make_shared<TokenAccountFragment>(tokenAccountFragment));
ConnectionFragment<TokenAccountFragment> connectionFragment = ConnectionFragment<TokenAccountFragment>()
.WithEdges(make_shared<EdgeFragment<TokenAccountFragment>>(edgeFragment));
walletFragment.WithTokenAccounts(make_shared<ConnectionFragment<TokenAccountFragment>>(connectionFragment));
getWallet.SetFragment(make_shared<WalletFragment>(walletFragment));
// Create and auth a client to send the request to the platform
unique_ptr<PlatformClient> client = PlatformClient::Builder()
.SetBaseAddress("https://platform.canary.enjin.io")
.Build();
client->Auth("Your_Platform_Token_Here");
// Send the request then get the response and write the output to the console.
// Only the fields that were requested in the fragment will be filled in,
// other fields which weren't requested in the fragment will be set to null.
future<PlatformResponsePtr<GraphQlResponse<Wallet>>> futureResponse = SendGetWallet(*client, getWallet);
// Get the platform response holding the HTTP data
PlatformResponsePtr<GraphQlResponse<Wallet>> response = futureResponse.get();
// Get the result, a GraphQL response, holding the GraphQL data
const optional<GraphQlResponse<Wallet>>& gqlResult = response->GetResult();
// Write the result data to the console
if (gqlResult.has_value() && gqlResult->IsSuccess())
{
const optional<Wallet>& getWalletResult = gqlResult->GetData()->GetResult();
std::cout << getWalletResult->GetAccount()->GetAddress().value() << std::endl;
}
// Write any error messages to the console
if (gqlResult.has_value() && gqlResult->HasErrors())
{
const optional<vector<GraphQlError>>& errors = gqlResult->GetErrors();
for (const GraphQlError& error : errors.value()) {
std::cout << error.GetMessage().value() << std::endl;
}
}
client.reset();
return 0;
}
fetch('https://platform.canary.enjin.io/graphql', {
method: 'POST',
headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'},
body: JSON.stringify({
query: `
query FetchingWalletTokens($account: String!) {
GetWallet(account: $account) {
tokenAccounts{
edges{
node{
balance
token{
tokenId
collection{
collectionId
}
attributes{
key
value
}
}
}
}
}
}
}
`,
variables: {
account: "cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f" //Specify the account address
}
}),
})
.then(response => response.json())
.then(data => console.log(data));
const axios = require('axios');
axios.post('https://platform.canary.enjin.io/graphql', {
query: `
query FetchingWalletTokens($account: String!) {
GetWallet(account: $account) {
tokenAccounts{
edges{
node{
balance
token{
tokenId
collection{
collectionId
}
attributes{
key
value
}
}
}
}
}
}
}
`,
variables: {
account: "cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f" //Specify the account address
}
}, {
headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
import requests
query = '''
query FetchingWalletTokens($account: String!) {
GetWallet(account: $account) {
tokenAccounts{
edges{
node{
balance
token{
tokenId
collection{
collectionId
}
attributes{
key
value
}
}
}
}
}
}
}
'''
variables = {
'account': "cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f" #Specify the account address
}
response = requests.post('https://platform.canary.enjin.io/graphql',
json={'query': query, 'variables': variables},
headers={'Content-Type': 'application/json', 'Authorization': 'Your_Platform_Token_Here'}
)
print(response.json())
Response:
{
"data": {
"GetWallet": {
"tokenAccounts": {
"edges": [
{
"node": {
"balance": "1",
"token": {
"tokenId": "0",
"collection": {
"collectionId": "33866"
},
"attributes": []
}
}
},
{
"node": {
"balance": "1",
"token": {
"tokenId": "0",
"collection": {
"collectionId": "36105"
},
"attributes": [
{
"key": "Name",
"value": "Awesome Token!"
}
]
}
}
},
{
"node": {
"balance": "6",
"token": {
"tokenId": "1",
"collection": {
"collectionId": "36105"
},
"attributes": [
{
"key": "name",
"value": "Awesome Token 2!"
}
]
}
}
}
]
}
}
}
}
Using Pagination
The response may be displayed on several pages. To view all of it, you may need to follow steps for pagination which allows you to flip through the pages.
Explore More Arguments
For a comprehensive view of all available arguments for queries and mutations, please refer to our API Reference. This resource will guide you on how to use the GraphiQL Playground to explore the full structure and functionality of our API.
Updated 24 days ago