4

I am currently trying to 'listen events' emitted from my smart contract. I am able to run my scripts created by using the node command and it works as intended, and I want to host it on a server. I have a few questions about how to host it on a server:

What is the proper way to invoke the function that creates listeners?

Currently I am implementing this method:

app.get("/", (req, res) => {
  if (!on) {
    on = true;
    main();
    res.status(200).json({ message: "Setup the listeners" });
  } else {
    res.status(200).json({ message: "Already operating" });
  }
});

By calling 'main', I am setting up the listeners as such:

 const contract = new ethers.Contract(marketAddress, ABI, provider);
  console.log("Listening");

  contract.on("NewListing", async (listingId, event) => {...}

I would like to know the correct way to setup the listeners, to send a get request to the server, including if the server went to sleep.

Is there any free server hosting platforms that would keep the websocket connection open (or what would be my best bet to maintain the connection)?

1 Answer 1

2

Yes, you have some alternatives, we can write the API that will serve as a layer between our frontend application and our smart contract, currently there are a subscription method to do that with web3.js.

But remember that you need a web-socket endpoint to use subscriptions in web3.js

Inside your project folder, create files routes.js, server.js, and config.js.

server.js is the main file that runs as Node.js server. We are requiring all of the dependencies at the beginning of the file, using cors and Express, we can check for Web3.js and make it interact with blockchain network by providing a localhost address.

const express = require('express');
const app = express();
const cors = require('cors');
const routes = require('./routes');
const Web3 = require('web3');
const mongodb = require('mongodb').MongoClient;
const contract = require('@truffle/contract');
const artifacts = require('./build/contracts/Contacts.json');
const CONTACT_ABI = require('./config');
const CONTACT_ADDRESS = require('./config');

app.use(cors());
app.use(express.json());

if (typeof web3 !== 'undefined') {
        var web3 = new Web3(web3.currentProvider); 
} else {

This is an example connecting to a MongoDB ready to use in the future, so inside the callback function of the mongodb.connect(), we connect with Cluster0 and getting accounts from the Ethereum blockchain network.

Using the 'web3 Contract function', open the config.js file where we pass CONTACT_ABI and CONTACT_ADDRESS we have connected with the smart contract.

const CONTACT_ADDRESS = '0xB7fC6C3DFebD24EAe16E307Ea39EdF7c93ff7866';

const CONTACT_ABI = [
        {
    "inputs": [],
    "stateMutability": "nonpayable",
    "type": "constructor"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "name": "contacts",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "id",
        "type": "uint256"
      },
      {
        "internalType": "string",
        "name": "name",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "phone",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function",
    "constant": true
  },
  {
    "inputs": [],
    "name": "count",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function",
    "constant": true
  },
  {
    "inputs": [
      {
        "internalType": "string",
        "name": "_name",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "_phone",
        "type": "string"
      }
    ],
    "name": "createContact",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  }
];

module.exports = {
        CONTACT_ABI,
        CONTACT_ADDRESS,
};

Then we will call routes() with all the parameters, creating this routes function in routes.js to listen the app on 'port 3000'.

function routes(app, db, accounts, contactList) {
        app.get('/contacts', async (request, response) => {
                let cache = [];
                const COUNTER = await contactList.methods.count().call();

                for (let i = 1; i <= COUNTER; i++) {
      const contact = await contactList.methods.contacts(i).call();
      cache = [...cache, contact];
    }

    response.json(cache);
  });
}

module.exports = routes

We loop through all the COUNTER and get contacts one-by-one from contactList, which we place in the cache variable and finally send to the frontend in response.

Run the server which is now ready to receive requests from React app.

$ nodemon server.js

You can find more based in the web3.eth.contract official documentation and web3.eth.accounts, including this related post using 'Chainlink' or Polygon as another option.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.