Using MATIC with Web3 and MetaMask: "Error: Returned error: unknown account"

Hey all, I am new to MATIC but not development in general. I have a server-client DApp that I’ve tested working fine on an Ethereum test network. But due to gas fees, I want to use a L2, in this case I chose Polygon (MATIC). Basic app is reading and writing text posts to a website, the smart contract stores them.

I have successfully deployed on MATIC using remix.ethereum.org, and from Remix I can write transactions to the contract. On my localhost web app, I can read transactions, but my writing is not working from the client.

Here is the server.js

const WEB3_PROVIDER = "https://polygon-rpc.com" 
// https://blog.polygon.technology/polygon-rpc-gateway-will-provide-a-free-high-performance-connection-to-the-polygon-pos-blockchain/

//"https://cloudflare-eth.com"; //"HTTP://127.0.0.1:7545"
if (typeof web3 !== 'undefined') {
    web3 = new Web3(web3.currentProvider);
    console.log("web3 already initialized.");
} else {
    // set the provider you want from Web3.providers
    web3 = new Web3(new Web3.providers.HttpProvider(WEB3_PROVIDER));
    console.log("New web3 object initialized.");
}

app.post('/add-post', async (req, res) => {
    const post = req.body;
    
    try {
    	console.log(post);

    	MyContract.methods.addNewPost(post['name'], post['post'], post['date']).send({from: post['addr'], gas:3000000}).then(function(result) {
    		const output_response = "add-post successful :: ";//+String(result);
        	res.send(output_response);
    	}).catch(function(err) {
    		const output_response = "add-post failed :: "+String(err);
        	res.send(output_response);
    	});
        
    } catch (e) { throw e; }
});

And here is the snippet in client.js where I am adding a post, by grabbing the html input form and then passing to the following:

const web3 = new Web3(window.ethereum);

async function addPost(post_input) {
	stringify_post_input = JSON.stringify(post_input);
	const post_response = await fetch('/add-post', {method: 'POST', body: stringify_post_input, headers: { "content-type": "application/json" } });
	var post_response_text = await post_response.text();
	console.log(post_response_text);
}

Now this usually works flawlessly on ethereum test network, where all I change is the web3 initialization in server.js. But now on the MATIC network I get, in my client browser,

add-post failed :: Error: Returned error: unknown account

This is really confusing to me, because

  1. I can manually add posts in remix.ethereum.org, where I deployed this exact same MyContract
  2. I have other server-side calls that read from MyContract and work fine (i.e. I can read existing posts I added from Remix).

So my client can read but not write, i.e. no MetaMask pop-up asking me to confirm to pay gas fees.

This is my first time trying to use a L2, so I have no idea if all the web3 code should be the same. I’ve been under the impression that I only need to swap the networks and log into my MetaMask and it should all be fine. But I don’t really understand web3 that deeply, so I’m not sure.

Help much appreciate - ideally when I try and write with MyContract.methods...(), I should get a MetaMask pop-up in my client browser asking me to confirm paying gas fees.

1 Like

Hey Annie, sure thing just send a message to that support bubble asking for a dev to take a look. I really look forward to getting my first DApp on the Matic network up and running!

Plus this seems like an important type of question to help other developers migrating over from Ethereum with existing web3.js code/app, which is basically the gist of my question.

Cheers

Oh, odd… good to know I guess. OK I’ll give that a look, thanks.