use /state

This commit is contained in:
zramsay 2025-03-25 15:20:45 -04:00
parent aa1987b37e
commit 19534ab07c

View File

@ -413,14 +413,18 @@ export const getTokenBalance = async (): Promise<number> => {
// The REST endpoint for Sei testnet
const restEndpoint = NETWORKS.testnet.restUrl;
// Create a simple query parameter with the wallet address
// This approach uses a GET request which is more CORS-friendly
// Based on the reference data, we can directly query the contract state
// which includes base64 encoded balances
// Construct the REST API URL for the contract query using simple GET request
// Use the bank module to check the account balance which has fewer CORS restrictions
const queryUrl = `${restEndpoint}/cosmos/bank/v1beta1/balances/${currentAddress}`;
// Log the info we have
console.log('Current wallet address:', currentAddress);
console.log('Token contract address:', tokenContractAddress);
console.log('REST endpoint:', restEndpoint);
console.log(`Querying token balance at: ${queryUrl}`);
// Query the contract state directly - this endpoint works and returns the balance data
const queryUrl = `${restEndpoint}/cosmwasm/wasm/v1/contract/${tokenContractAddress}/state`;
console.log(`Querying contract state at: ${queryUrl}`);
// Make a simple GET request to check the account balances
// This typically has fewer CORS issues than POST requests with complex JSON body
@ -436,31 +440,89 @@ export const getTokenBalance = async (): Promise<number> => {
console.log('Raw response data:', data);
// Extract the balance from the cosmos bank balances endpoint
console.log('Full response structure:', JSON.stringify(data, null, 2));
// This endpoint returns the entire contract state, which may be large
// Log the full structure to understand what we're working with
console.log('Full contract state:', JSON.stringify(data, null, 2));
// The bank module returns an array of balances for all tokens the account holds
if (data && data.balances && Array.isArray(data.balances)) {
// Find our WILD token in the balances array
// Looking for our token by denom
const wildToken = data.balances.find((balance: any) =>
// Our token is likely listed with a denom like "uwild" or similar
balance.denom === 'uwild' ||
balance.denom === 'wild' ||
balance.denom?.toLowerCase().includes('wild')
);
try {
// Based on the reference data, we know the contract state includes base64 encoded balances
// The key pattern is "AAdiYWxhbmNl" + base64(address)
if (wildToken && wildToken.amount) {
// Convert from micro units (1e6) to whole tokens
const balanceInMicro = parseInt(wildToken.amount);
const balance = balanceInMicro / 1_000_000;
console.log(`Real token balance for ${currentAddress}: ${balance} WILD`);
return balance;
// Check if we have models in the response
if (data && data.models && Array.isArray(data.models)) {
console.log(`Found ${data.models.length} state models in contract`);
// Look for our address balance
// The key format from the reference is: "AAdiYWxhbmNl" + base64(walletAddress)
// Example: "AAdiYWxhbmNlc2VpMWp3ZTQ0NHdmeXRlN2xzcWR4Y3J3eHJuenBnaDRrcjhjczVtMzI1"
// The key prefix "AAdiYWxhbmNl" is the base64 encoding of "\x00\x07balance"
// which is the storage prefix for balances in the CW20 contract
// Search for a model with our wallet address in the key
// We know from the reference that the key contains the address in readable form
for (const model of data.models) {
if (model.key && model.key.includes(currentAddress.replace('sei', 'c2Vp'))) {
console.log('Found matching balance entry:', model);
// The value is base64 encoded JSON string with the balance
const decodedValue = atob(model.value);
console.log('Decoded value:', decodedValue);
// The balance is a string wrapped in quotes, e.g. "120000000"
// Remove the quotes and parse as integer
const balanceStr = decodedValue.replace(/^"|"$/g, '');
const balanceInMicro = parseInt(balanceStr);
// Convert from micro units (1e6) to whole tokens
const balance = balanceInMicro / 1_000_000;
console.log(`Found token balance for ${currentAddress}: ${balance} WILD`);
return balance;
}
}
// Alternative approach - look for any key that starts with balance prefix
// and then check if the decoded key contains our address
for (const model of data.models) {
if (model.key && model.key.startsWith('AAdiYWxhbmNl')) {
try {
// Try to decode the key to see if it contains our address
const decodedKey = atob(model.key);
if (decodedKey.includes(currentAddress)) {
console.log('Found balance by decoded key:', model);
// The value is base64 encoded JSON string with the balance
const decodedValue = atob(model.value);
console.log('Decoded value:', decodedValue);
// The balance is a string wrapped in quotes, e.g. "120000000"
// Remove the quotes and parse as integer
const balanceStr = decodedValue.replace(/^"|"$/g, '');
const balanceInMicro = parseInt(balanceStr);
// Convert from micro units (1e6) to whole tokens
const balance = balanceInMicro / 1_000_000;
console.log(`Found token balance for ${currentAddress}: ${balance} WILD`);
return balance;
}
} catch (decodeError) {
console.warn('Error decoding key:', decodeError);
}
}
}
// If we checked all models and didn't find our address, they likely have 0 balance
console.log('No balance entry found for this address, assuming 0 balance');
return 0;
}
// If we couldn't find the WILD token, the user probably has 0 balance
console.log('No WILD tokens found in balances, assuming 0 balance');
return 0;
// If we got a valid response with no models, assume 0 balance
if (data && Object.keys(data).length > 0) {
console.log('No balance models found in contract state, assuming 0 balance');
return 0;
}
} catch (parseError) {
console.error('Error processing transaction data:', parseError);
}
// If the response structure is different than expected