0

I'm trying to make a web3 wallet with Moralis with Fasitify in back and VueJS in front.

(I would like to say that I already do this in web client (vuejs) and everything works well!)

In my back, I fetch all the asset from user. It works, I get them all well and I can send them back to the front

But I need to process/sort the data to recover only part of it and send it to the front to avoid doing too much treatment at the front and reduce your workload.

I do that :

*handlers/token.js*

const getTokenBalances = async () => {
  let userTokens;
  const options = {
    chain: "bsc",
    address: "0x935A438C29bd810c9aBa2F3Df5144d2dF4F3c0A0",
  };
  userTokens = await Moralis.Web3API.account.getTokenBalances(options);
 
  return userTokens;
};

and if I return userTokens, I had it in Postman. But now, I do something like :

const getTokenBalances = async (tokens) => {
  let userTokens;
  let userBalances = [];
  const options = {
    chain: "bsc",
    address: "0x935A438C29bd810c9aBa2F3Df5144d2dF4F3c0A0",
  };
  userTokens = await Moralis.Web3API.account.getTokenBalances(options);
  userTokens.forEach((token) => {
    if (
      !token.name.match(/^.*\.io/) &&
      !token.name.match(/^.*\.IO/) &&
      !token.name.match(/^.*\.net/) &&
      !token.name.match(/^.*\.Net/) &&
      !token.name.match(/^.*\.com/) &&
      !token.name.match(/^.*\.org/)
    ) {
      getTokenPair(token).then((value) => {
        if (value > 2) {
          checkTokenPrice(token).then((price) => {
            if (price > 0.001) {
              userBalances.push(token);
            }
          });
        }
      });
    }
  });
  userBalances.sort((a, b) => {
    return b.total_value_usd - a.total_value_usd;
  });

  return userBalances;
};
   

userBalances its always empty in my response in Postman (And I don't understand why ?)

The getTokenPair function :

const getTokenPair = async (token) => {
  const BNBTokenAddress = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"; //BNB
  const options = {
    token0_address: token.token_address,
    token1_address: BNBTokenAddress,
    exchange: "pancakeswapv2",
    chain: "bsc",
  };
  try {
    const pairAddress = await Moralis.Web3API.defi.getPairAddress(options);
    let amount = 0;
    //console.log("token pairAddress : " + pairAddress.pairAddress);
    if (pairAddress.token1.symbol === "BUSD") {
      try {
        let reserve = await getPairReserves(pairAddress.pairAddress);
        amount += reserve / 10 ** 18;
      } catch (err) {
        console.log("error getReservesBUSD : " + err);
      }
    }
    if (pairAddress.token1.symbol === "WBNB") {
      try {
        let reserve = await getPairReserves(pairAddress.pairAddress);
        amount += reserve / 10 ** 18;
      } catch (err) {
        console.log("error getReservesWBNB : " + err);
      }
    }
    //console.log("amount : " + amount)
    return amount;
  } catch (err) {
    console.log("error getPair : " + err);
  }
};

and the checkTokenPrice function :

const checkTokenPrice = async (token) => {
  let price;
  const options = {
    address: token.token_address,
    chain: "bsc",
    exchange: "PancakeSwapv2",
  };
  try {
    const priceToken = await Moralis.Web3API.token.getTokenPrice(options);
    price = priceToken.usdPrice.toFixed(7);
    token.price = priceToken.usdPrice.toFixed(7);
    token.balance = insertDecimal(token.balance, token.decimals);

    token.total_value_usd = (token.balance * token.price).toFixed(2);

    return price;
  } catch (err) {
    console.log("error tokenPrice : " + err);
  }
};

They are await method in all the function I use so maybe there is a connection.

Thanks for you help !

**** EDIT *****

I solve my problem like this :

const getTokenBalances = async () => {
  let userTokens;
  let userBalances = [];
  const options = {
    chain: "bsc",
    address: "0x935A438C29bd810c9aBa2F3Df5144d2dF4F3c0A0",
  };
  userTokens = await Moralis.Web3API.account.getTokenBalances(options);

  for (token of userTokens) {
    if (
      !token.name.match(/^.*\.io/) &&
      !token.name.match(/^.*\.IO/) &&
      !token.name.match(/^.*\.net/) &&
      !token.name.match(/^.*\.Net/) &&
      !token.name.match(/^.*\.com/) &&
      !token.name.match(/^.*\.org/)
    ) {
      let value = await getTokenPair(token);
      if(value > 2) {
        let price = await checkTokenPrice(token);
        if (price > 0.001) {
          userBalances.push(token);
        }
      }
    }
  }
 
  return userBalances;
};

Thanks for the help ! ;)

TylerH
  • 20,799
  • 66
  • 75
  • 101
Jo Le Belge
  • 137
  • 1
  • 2
  • 14
  • It does not help me too much to put -1 without explanation... – Jo Le Belge Nov 20 '21 at 14:18
  • 2
    `getTokenPair(token).then(` is async, but you are trying to return the result without waiting. Your way of nesting `then` calls is also questionable, as it makes waiting hard. See [how-to-return-the-response-from-an-asynchronous-call](https://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call). To avoid a potential follow-up pitfall, [using-async-await-with-a-foreach-loop](https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop) is probably also relevant. I did not read the entirety of your code for potential additional problems – ASDFGerte Nov 20 '21 at 14:33
  • ^ This. Also don't use .then when you already use await, this just makes control flow more confusing. "I already do this in web client (vuejs)" - what exactly? Do you use the very same code in Node and Vue app? Currently the question isn't related to Vue, it's unclear what vue tag is for – Estus Flask Nov 20 '21 at 15:29
  • Ok ok I see... Thanks for your answer and I try to test it in best way. @EstusFlask yes, I use "particaly" the same code but in other app ! Not in this one ofc... (I'm newbie in back end js development) thanks again – Jo Le Belge Nov 20 '21 at 15:51
  • 1
    @ASDFGerte I solved my problem ! Thanks for the help ! ;) – Jo Le Belge Nov 22 '21 at 08:56

0 Answers0