Metamask balances

Hello,

I’m currently trying to do the last part of the javascript course and i’m getting the same error over and over:
Web3Api not initialized, run Moralis.start() first

this is my .js code:

//connect to moralis server
Moralis.initialize('0LSCgoM8SLXscypNsGrPIOSauRrz06P1tvm4EwC4'); 
Moralis.serverURL = "https://tgvj9b2fzccq.usemoralis.com:2053/server"  

const $tokenBalaceTBody = document.querySelector('.js-token-balance');


const tokenValue = (value, decimals) => 
    (decimals ? value / Math.pow(10, decimals) :  value)

// MetaMask login
async function login() {
    let user = Moralis.User.current(); 
    if (!user) {    
      user = await Moralis.authenticate()
     } 
     console.log("logged in user: ", user);
     getStats();
  }

  // get your metamask balances
async function getStats(){
    const balances = await Moralis.Web3API.account.getTokenBalances({chain: 'polygon'});
    console.log(balances);
    $tokenBalaceTBody.innerHTML = balances.map((token, index) => `
        <tr>
            <td>${index + 1}</td>
            <td>${token.symbol}</td>
            <td>${tokenValue(token.balance, token.decimals)}</td>
            <td>button</td>
        </tr>
    `).join('')
}
  
  async function logOut() {
    await Moralis.User.logOut();
    console.log("logged out");
  }
  
  document.querySelector("#btn-login").addEventListener('click',login);
  document.getElementById("btn-logout").addEventListener('click',logOut);


async function getTop10Tokens(){
    const response = await fetch('https://api.coinpaprika.com/v1/coins'); 
    const tokens = await response.json();        

    return tokens
            .filter(token => token.rank >= 1 && token.rank <= 30) 
            .map(token => token.symbol) 
}


async function getTickerData(tickerList){
    const response = await fetch('https://api.1inch.exchange/v3.0/137/tokens')
    const tokens = await response.json();
    const tokenList = Object.values(tokens.tokens);

    return tokenList.filter(token => tickerList.includes(token.symbol))

}


getTop10Tokens()
    .then(getTickerData)
    .then(console.log);

I don’t see a problem in your .js file. Can you send your html file too.

hey @Maki,

here is my html file:

<!DOCTYPE html>
<html>
  <head>
    <title>My first DEX</title>
    <script src="https://unpkg.com/moralis@1.5.0/dist/moralis.js"></script>
  </head>

  <body>
    <div>
      <h1>Moralis Swap</h1>
      <button id="btn-login">Moralis Metamask Login</button>
      <button id="btn-logout">Logout</button>

      <table>
          <thead>
              <tr>
                  <th>#</th>
                  <th>Symbol</th>
                  <th>Amount</th>
                  <th>Action</th>
              </tr>
          </thead>
          <tbody class="js-token-balance"></tbody>
      </table>
      <div>
        <br />
        <span id="myethAddress"> </span>
      </div>
    </div>
    <script type="text/javascript" src="./DEX.js"></script>
  </body>
</html>

You forget to add Moralis sdk

//Add this before your .js script.
 <!-- Moralis SDK code -->
    <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
    <script src="https://unpkg.com/moralis/dist/moralis.js"></script>

:man_facepalming:

Thanks a lot!

1 Like

Hello,

I don’t know why it doesn’t work anymore. Yesterday everything worked, but today nothing.
Can you help me one more time please!

my HTML file:

<!DOCTYPE html>
<html>
  <head>
    <title>My first DEX</title>
    <script src="https://unpkg.com/moralis@1.5.0/dist/moralis.js"></script>
  </head>

  <body>
    <div>
      <h1>Moralis Swap</h1>
      <button id="btn-login">Moralis Metamask Login</button>
      <button id="btn-logout">Logout</button>

      <table>
          <thead>
              <tr>
                  <th>#</th>
                  <th>Symbol</th>
                  <th>Amount</th>
                  <th>Action</th>
              </tr>
          </thead>
          <tbody class="js-token-balance"></tbody>
      </table>
      <div>
        <br />
        <span id="myethAddress"> </span>
      </div>
    </div>
    <!-- Moralis SDK code -->
    <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
    <script src="https://unpkg.com/moralis/dist/moralis.js"></script>
    <script type="text/javascript" src="./DEX.js"></script>
  </body>
</html>

my .js file:

Moralis.initialize('0LSCgoM8SLXscypNsGrPIOSauRrz06P1tvm4EwC4');
Moralis.serverURL = "https://tgvj9b2fzccq.usemoralis.com:2053/server"  

const $tokenBalaceTBody = document.querySelector('.js-token-balance');


const tokenValue = (value, decimals) => 
    (decimals ? value / Math.pow(10, decimals) :  value)

async function login() {
    let user = Moralis.User.current(); 
    if (!user) {    
      user = await Moralis.authenticate()
     } 
     console.log("logged in user: ", user);
     getStats();
  }

  
async function getStats(){
    const balances = await Moralis.Web3API.account.getTokenBalances({chain: 'polygon'});
    console.log(balances);
    $tokenBalaceTBody.innerHTML = balances.map((token, index) => `
        <tr>
            <td>${index + 1}</td>
            <td>${token.symbol}</td>
            <td>${tokenValue(token.balance, token.decimals)}</td>
            <td>button</td>
        </tr>
    `).join('')
}
  
  async function logOut() {
    await Moralis.User.logOut();
    console.log("logged out");
  }
  
  document.querySelector("#btn-login").addEventListener('click',login);
  document.getElementById("btn-logout").addEventListener('click',logOut);


async function getTop10Tokens(){
    const response = await fetch('https://api.coinpaprika.com/v1/coins'); 
    const tokens = await response.json();       

    return tokens
            .filter(token => token.rank >= 1 && token.rank <= 30) 
            .map(token => token.symbol)    
}


async function getTickerData(tickerList){
    const response = await fetch('https://api.1inch.exchange/v3.0/137/tokens') 
    const tokens = await response.json();
    const tokenList = Object.values(tokens.tokens); 

    return tokenList.filter(token => tickerList.includes(token.symbol)) 

}


getTop10Tokens()
    .then(getTickerData)
    .then(console.log);
1 Like

Hey @Heyns, hope you are well.

The only error i got is that moralis has not been started, you are using the old way to initialize the server, instead you can do the following:

/* Moralis init code */
const serverUrl = "https://tgvj9b2fzccq.usemoralis.com:2053/server";
const appId = "0LSCgoM8SLXscypNsGrPIOSauRrz06P1tvm4EwC4";
 
Moralis.start({ serverUrl, appId });

I just removed the 1st two lines from your js file,

Moralis.initialize('0LSCgoM8SLXscypNsGrPIOSauRrz06P1tvm4EwC4');
Moralis.serverURL = "https://tgvj9b2fzccq.usemoralis.com:2053/server"

Then i just changed with the code above, you can read more about it here: https://docs.moralis.io/moralis-dapp/connect-the-sdk/connect-with-js

Carlos Z

How do I incorporate the new Moralis function for converting token value from WEI, into the getStats() function?

Here’s the new tokenValue function as shown in the Moralis docs:

const tokenValue = Moralis.Units.FromWei("2000000000000000000");

Which I expect to do the same as the function used in the tutorial:

const tokenValue = (value, decimals) => 
    (decimals ? value / Math.pow(10, decimals) :  value)

Here’s what the function is looking like atm:

async function getStats() {
    const balances = await Moralis.Web3API.account.getTokenBalances({chain:"polygon"});
    console.log(balances);
    $tokenBalanceTBody.innerHTML = balances.map( (token, index) => `
        <tr>
            <td>${index + 1}.</td>
            <td>${token.symbol}</td>
                  // This is the problematic line (I think so anyway)
            <td>${tokenValue}, ${token.balances, token.decimals}</td>
            <td>button</td>
        </tr>
    `).join('');
  }

Ofc, I can just use the one Zsolt used, but I want to get the same results using the newer function. Moralis has changed a lot since and I have managed to adapt the new Moralis code to generate the same results as Zsolt up until now!

Any help on this would be great! @thecil @zsolt-nagy @Maki

You can also do this:

<td>${tokenValue}, ${Moralis.Units.FromWei(token.balances, token.decimals)}</td>

Carlos Z

Hey @thecil ! Thanks for yore reply!

I tried to implement your suggestion but it didn’t work. I was met with this error:

This is what my dex.js code looks like:

/* Moralis init code */
const serverUrl = "Hidden";
const appId = "Hidden";
Moralis.start({ serverUrl, appId });

const $tokenBalanceTBody = document.querySelector('.js-token-balances')

//Convert token value to ETH style with 18 decimals
//If you do not specify decimals, 18 decimals will be automatically used
const tokenValue = Moralis.Units.FromWei("2000000000000000000");

/* Authentication code */
async function login() {
  let user = Moralis.User.current();
  if (!user) {
    user = await Moralis.authenticate({
      signingMessage: "Log in using Moralis",
    })
      .then(function (user) {
        console.log("logged in user:", user);
        console.log(user.get("ethAddress"));
      })
      .catch(function (error) {
        console.log(error);
      });
  }
  getStats();
}

async function getStats() {
    const balances = await Moralis.Web3API.account.getTokenBalances({chain:"polygon"});
    console.log(balances);
    $tokenBalanceTBody.innerHTML = balances.map( (token, index) => `
        <tr>
            <td>${index + 1}.</td>
            <td>${token.symbol}</td>
            <td>${tokenValue}, ${Moralis.Units.FromWei(token.balances, token.decimals)}</td>
            <td>button</td>
        </tr>
    `).join('');
  }

async function logOut() {
  await Moralis.User.logOut();
  console.log("logged out");
}

document.querySelector("#btn-login").addEventListener('click', login);
document.getElementById("btn-logout").addEventListener('click', logOut);

async function getTop10Coins() {
    const response = await fetch('https://api.coinpaprika.com/v1/coins')
    const tokens = await response.json();

    return tokens
        .filter(token => token.rank <= 30 && token.rank >= 1)
        .map(token => token.symbol);
}

async function getTickerData(tickerList) {
    const response = await fetch('https://api.1inch.exchange/v3.0/137/tokens');
    const tokens = await response.json();
    const tokenList = Object.values(tokens.tokens)
    
    return tokenList.filter(token => tickerList.includes(token.symbol));
}

getTop10Coins()
    .then(getTickerData)
    .then(console.log);

What do I do from here?

Thanks for your help! :slight_smile:

1 Like

Sorry, i forgot to also change balances, it should be balance, because thats the object property:
image

So it should be

<td>${tokenValue}, ${Moralis.Units.FromWei(token.balance, token.decimals)}</td>

Carlos Z

Yeahhhh that produces similar results to that from the tutorial:

This code:

async function getStats() {
    const balances = await Moralis.Web3API.account.getTokenBalances({chain:"polygon"});
    console.log(balances);
    $tokenBalanceTBody.innerHTML = balances.map( (token, index) => `
        <tr>
            <td>${index + 1}.</td>
            <td>${token.symbol}</td>
            <td>${tokenValue}, ${Moralis.Units.FromWei(token.balance, token.decimals)}</td>
            <td>button</td>
        </tr>
    `).join('');
  }

Produces this result:

However, I notice that the tokenValue variable causes a “2” to appear next to the balance… when I get rid of "${tokenValue}" and just keep <td>${Moralis.Units.FromWei(token.balance, token.decimals)}</td>, the results show the balance alone.

I even found out that I can just use
<td>${Moralis.Units.FromWei("token.balance, token.decimals")}</td>

without declaring:
const tokenValue = Moralis.Units.FromWei("2000000000000000000"); at the top,
and it will still work as intended.

Ofc, this solves the issue, but I’m wondering why can’t the same results come about when using the variable name "${tokenValue}" in the <td> element. Was there any point of declaring the tokenValue variable if it can’t be used?

Thanks once again for you help! I want to make sure I understand this properly before moving on :smiley: