trying to deploy a todolist in blockchain, when adding a new task, I get invalid address error - ethereum

I am making a simple block chain using the ETH blockchain technology.
I am making a simple todolist, following this tutorial.
My todolist works fine and I can see the tasks in there, how ever when I try to add a new task I get this following error:
Uncaught (in promise) Error: invalid address
v http://localhost:3000/js/web3.min.js:2
l http://localhost:3000/js/web3.min.js:2
formatInput http://localhost:3000/js/web3.min.js:2
formatInput http://localhost:3000/js/web3.min.js:2
toPayload http://localhost:3000/js/web3.min.js:2
e http://localhost:3000/js/web3.min.js:2
sendTransaction http://localhost:3000/js/web3.min.js:2
execute http://localhost:3000/js/web3.min.js:2
synchronizeFunction http://localhost:3000/vendor/truffle-contract/dist/truffle-contract.js:206
synchronizeFunction http://localhost:3000/vendor/truffle-contract/dist/truffle-contract.js:157
promise callback*synchronizeFunction/< http://localhost:3000/vendor/truffle-contract/dist/truffle-contract.js:156
createTask http://localhost:3000/js/app.js:124
onsubmit http://localhost:3000/:1
web3.min.js:2:4288
createTask http://localhost:3000/js/app.js:125
AsyncFunctionThrow self-hosted:696
(Async: async)
onsubmit http://localhost:3000/:1
​
this is my app.js
App = {
loading: false,
contracts: {},
load: async () => {
await App.loadWeb3();
await App.loadAccount();
await App.loadContract();
await App.render();
},
// https://medium.com/metamask/https-medium-com-metamask-breaking-change-injecting-web3-7722797916a8
loadWeb3: async () => {
if (typeof web3 !== "undefined") {
App.web3Provider = web3.currentProvider;
web3 = new Web3(web3.currentProvider);
} else {
window.alert("Please connect to Metamask.");
}
// Modern dapp browsers...
if (window.ethereum) {
window.web3 = new Web3(ethereum);
try {
// Request account access if needed
await ethereum.enable();
// Acccounts now exposed
web3.eth.sendTransaction({
/* ... */
});
} catch (error) {
// User denied account access...
}
}
// Legacy dapp browsers...
else if (window.web3) {
App.web3Provider = web3.currentProvider;
window.web3 = new Web3(web3.currentProvider);
// Acccounts always exposed
web3.eth.sendTransaction({
/* ... */
});
}
// Non-dapp browsers...
else {
console.log(
"Non-Ethereum browser detected. You should consider trying MetaMask!"
);
}
},
loadAccount: async () => {
// Set the current blockchain account
App.account = web3.eth.accounts[0];
console.log(App.account);
},
loadContract: async () => {
// Create a JavaScript version of the smart contract
const todoList = await $.getJSON("TodoList.json");
App.contracts.TodoList = TruffleContract(todoList);
App.contracts.TodoList.setProvider(App.web3Provider);
// Hydrate the smart contract with values from the blockchain
App.todoList = await App.contracts.TodoList.deployed();
// console.log(todoList);
},
render: async () => {
// Prevent double render
if (App.loading) {
return;
}
// Update app loading state
App.setLoading(true);
// Render Account
$("#account").html(App.account);
// Render Tasks
await App.renderTasks();
// Update loading state
App.setLoading(false);
},
renderTasks: async () => {
// Load the total task count from the blockchain
const taskCount = await App.todoList.taskCount();
const $taskTemplate = $(".taskTemplate");
// Render out each task with a new task template
for (var i = 1; i <= taskCount; i++) {
// Fetch the task data from the blockchain
const task = await App.todoList.tasks(i);
const taskId = task[0].toNumber();
const taskContent = task[1];
const taskCompleted = task[2];
// Create the html for the task
const $newTaskTemplate = $taskTemplate.clone();
$newTaskTemplate.find(".content").html(taskContent);
$newTaskTemplate
.find("input")
.prop("name", taskId)
.prop("checked", taskCompleted)
.on("click", App.toggleCompleted);
// Put the task in the correct list
if (taskCompleted) {
$("#completedTaskList").append($newTaskTemplate);
} else {
$("#taskList").append($newTaskTemplate);
}
// Show the task
$newTaskTemplate.show();
}
},
createTask: async () => {
App.setLoading(true);
const content = $("#newTask").val();
await App.todoList.createTask(content);
window.location.reload();
},
toggleCompleted: async (e) => {
App.setLoading(true);
const taskId = e.target.name;
await App.todoList.toggleCompleted(taskId);
window.location.reload();
},
setLoading: (boolean) => {
App.loading = boolean;
const loader = $("#loader");
const content = $("#content");
if (boolean) {
loader.show();
content.hide();
} else {
loader.hide();
content.show();
}
},
};
$(() => {
$(window).load(() => {
App.load();
});
});
in console it shows me the address to be: 0xc5cfa0a0345f74e26cecfd8ec3a5cfa3843955ac
I am using metamask and genache, and I tried to connect my smart contacrt to my memask wallet, so I know I am connected, but I am not sure why I am getting this error.
SHould I delete my metamask and do it again?
I tried to look for this solution here, but the solutions are mostly old and doesnt make scnese what I need to do.
Help would be really apperciated.

fixed it, in the app.js you have to replace this line:
App.account = web3.eth.accounts[0];
with the following line:
web3.eth.defaultAccount=web3.eth.accounts[0]

Related

VRFCoordinatorV2Mock's fulfillRandomWords not being called in hardhat local deployment

I'm building a smart contract that generates 3 random numbers using Chainlink VRF. My contract (SlotMachine.sol) implements the VRFConsumerBaseV2 and the constructor has 2 parameters: _subscriptionId and _vrfCoordinator:
constructor(
uint64 _subscriptionId,
address _vrfCoordinator
) payable VRFConsumerBaseV2(_vrfCoordinator)
I have a play() function which calls the requestRandonWords through the vrfCoordinator and I overrided the fulfillRandomWord function to use the generated random words.
I want to do 2 things: 1) create the unit tests in slotmachine.js and 2) test my contract in the hardhat network (chainId = 31337) through deploy.js
For this I'm using the VRFCoordinatorV2Mock which helps me mock an oracle's behavior (as I understand).
My unit tests in slotmachine.js are working well. The fulfillRandomWords is called and then my tests are passing. However when I add a similar logic to the deploy.js file (deploy the mock contract and then the slot machine contract) the fulfillRandomWords is not being called when I call the play() function (which has the requestRandomWords inside it) from my deployed contract.
slotmachine.js
const { ethers } = require("hardhat");
const { expect } = require("chai");
const { BigNumber } = require("ethers");
const provider = ethers.getDefaultProvider();
describe("Decentralized Slot Machine", async function () {
let myContract;
let hardhatVrfCoordinatorV2Mock;
describe("Testing Decentralized Slot Machine", function () {
//1. Contract deployment
it("Should deploy Slot Machine Contract", async function () {
const SlotMachine = await ethers.getContractFactory("SlotMachine");
let vrfCoordinatorV2Mock = await ethers.getContractFactory(
"VRFCoordinatorV2Mock"
);
hardhatVrfCoordinatorV2Mock = await vrfCoordinatorV2Mock.deploy(0, 0);
await hardhatVrfCoordinatorV2Mock.createSubscription();
await hardhatVrfCoordinatorV2Mock.fundSubscription(
1,
ethers.utils.parseEther("7")
);
myContract = await SlotMachine.deploy(
1,
hardhatVrfCoordinatorV2Mock.address,
{
value: ethers.utils.parseEther("100"),
}
);
await hardhatVrfCoordinatorV2Mock.addConsumer(1, myContract.address);
});
//2. Play
describe("First Play - First Player", function () {
it("Contract should receive random numbers", async () => {
const [account1, account2] = await ethers.getSigners();
let tx = await myContract.play(ethers.constants.AddressZero, {
value: ethers.utils.parseEther("1"),
});
let { events } = await tx.wait();
let [reqId] = events.filter((x) => x.event === "RequestedRandomness")[0]
.args;
await expect(
hardhatVrfCoordinatorV2Mock.fulfillRandomWords(
reqId,
myContract.address
)
).to.emit(myContract, "ReceivedRandomness");
let round = await myContract.rounds(reqId);
expect(round.userAddress).to.be.equal(account1.address);
expect(round.number1).to.be.equal(1);
expect(round.number2).to.be.equal(9);
expect(round.number3).to.be.equal(6);
});
});
});
});
deploy.js
const { ethers } = require("hardhat");
const localChainId = "31337";
module.exports = async ({ getNamedAccounts, deployments, getChainId }) => {
const { deploy } = deployments;
const { deployer } = await getNamedAccounts();
const chainId = await getChainId();
await deploy("VRFCoordinatorV2Mock", {
from: deployer,
args: [0, 0],
log: true,
waitConfirmations: 5,
});
const hardhatVrfCoordinatorV2Mock = await ethers.getContract(
"VRFCoordinatorV2Mock",
deployer
);
await hardhatVrfCoordinatorV2Mock.createSubscription();
await hardhatVrfCoordinatorV2Mock.fundSubscription(
1,
ethers.utils.parseEther("7")
);
const myContract = await deploy("SlotMachine", {
from: deployer,
args: [1, hardhatVrfCoordinatorV2Mock.address],
log: true,
waitConfirmations: 5,
});
await hardhatVrfCoordinatorV2Mock.addConsumer(1, myContract.address);
console.log("Contract address: ", myContract.address);
};
module.exports.tags = ["SlotMachine"];
Question
Can I deploy my contract in the hardhat network with the expected behavior of the VRFCoordinatorV2Mock which is to call automatically fulfillRandomWords? If so, how can I do this? What do I have to change in my code? If the answer is no, is there another alternative than deploying to a testnet?

Webhook error on Dialog Flow ES when trying to communicate (save data) between Google Sheets and Dialog Flow

I have a problem with connecting dialog flow with any database. In this case, it is for Google sheets. I followed up this video for connecting dialog flow with google sheets:
"[https://www.youtube.com/watch?v=FVPRAnJ5jRk&t=785s]".
So, when I communicate with the bot, and when I finish filling in the information that I specified in the fulfillment, the Diagnostic Info displays an error:
"message": "Webhook call failed. Error: UNAVAILABLE, State: URL_UNREACHABLE, Reason: UNREACHABLE_5xx, HTTP status code: 500."
Please, can anyone help me with this. Really, I tried every database to integrate with Dialog Flow, but none worked. I don't know what is happening with Dialog Flow.
Bellow is my code that I have written in fulfillment at index.js:
`
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
const axios = require('axios');
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
function welcome(agent) {
agent.add(`Welcome to my agent!`);
}
function fallback(agent) {
return new Promise((resolve, reject) => {
const queryText = request.body.queryResult.queryText;
axios.post('https://sheetdb.io/api/v1/jv8fq8y7xucpf?sheet=failed', {
"data": {
"content": queryText
}
});
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
});
}
function appointment(agent) {
const doctor = agent.parameters.doctor.name;
const date = agent.parameters.date;
const name = agent.parameters.name;
const phone = agent.parameters.phone;
return new Promise((resolve, reject) => {
axios.get(`https://sheetdb.io/api/v1/jv8fq8y7xucpf/search?name=*${doctor}*`).then(function(response) {
let doctor = response.data[0];
if (doctor) {
axios.post('https://sheetdb.io/api/v1/jv8fq8y7xucpf?sheet=appointments', {
"data": {
"doctor": doctor.name,
"patient": name,
"patient_phone": phone,
"date": date,
"created": new Date()
}
});
agent.add("Ok your appointment is set up for you");
} else {
agent.add(`Unfortuneatly we did not find ${doctor} in our doctors`);
}
resolve();
});
});
}
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
intentMap.set('AppointmentIntent', appointment);
agent.handleRequest(intentMap);
});
`

cannot connect client app with web3js to metamask

I am a dapp beginner. This is a demo app for a todolist
I am unable to get a connection to the blockchain in web3js. Websocket connection error
localhost is localhost:8545
using web3js CDN : https://cdn.jsdelivr.net/npm/web3#latest/dist/web3.min.js
this is my app.js
App = {
loading: false,
contracts: {},
load: async () => {
console.log('app loading ...')
console.log(web3);
await App.loadWeb3()
await App.loadAccount()
// await App.loadContract()
// await App.render()
},
// https://medium.com/metamask/https-medium-com-metamask-breaking-change-injecting-web3-7722797916a8
loadWeb3: async () => {
let web3 = new Web3('ws://localhost:8545');
if (typeof web3 !== 'undefined') {
App.web3Provider = web3.currentProvider
web3.setProvider('ws://localhost:8546');
web3.eth.getAccounts().then(console.log);
} else {
window.alert("Please connect to Metamask.")
}
// Modern dapp browsers...
if (window.ethereum) {
window.web3 = new Web3(ethereum)
try {
// Request account access if needed
await ethereum.enable()
// Acccounts now exposed
web3.eth.sendTransaction({/* ... */})
console.log('MetaMask is installed!');
} catch (error) {
// User denied account access...
}
}
// Legacy dapp browsers...
else if (window.web3) {
App.web3Provider = web3.currentProvider
window.web3 = new Web3(web3.currentProvider)
// Acccounts always exposed
web3.eth.sendTransaction({/* ... */})
}
// Non-dapp browsers...
else {
console.log('Non-Ethereum browser detected. You should consider trying MetaMask!')
}
},
loadAccount: async () => {
// Set the current blockchain account
App.account = web3.eth.accounts[0]
console.log(App.account)
// web3 set up by loadWeb3, includes all accounts, loading first one via MetaMask
},
loadContract: async () => {
// Create a JavaScript version of the smart contract
const todoList = await $.getJSON('TodoList.json')
App.contracts.TodoList = TruffleContract(todoList)
App.contracts.TodoList.setProvider(App.web3Provider)
// Hydrate the smart contract with values from the blockchain
App.todoList = await App.contracts.TodoList.deployed()
},
render: async () => {
// Prevent double render
if (App.loading) {
return
}
// Update app loading state
App.setLoading(true)
// Render Account
$('#account').html(App.account)
// Render Tasks
await App.renderTasks()
// Update loading state
App.setLoading(false)
},
renderTasks: async () => {
// Load the total task count from the blockchain
const taskCount = await App.todoList.taskCount()
const $taskTemplate = $('.taskTemplate')
// Render out each task with a new task template
for (var i = 1; i <= taskCount; i++) {
// Fetch the task data from the blockchain
const task = await App.todoList.tasks(i)
const taskId = task[0].toNumber()
const taskContent = task[1]
const taskCompleted = task[2]
// Create the html for the task
const $newTaskTemplate = $taskTemplate.clone()
$newTaskTemplate.find('.content').html(taskContent)
$newTaskTemplate.find('input')
.prop('name', taskId)
.prop('checked', taskCompleted)
.on('click', App.toggleCompleted)
// Put the task in the correct list
if (taskCompleted) {
$('#completedTaskList').append($newTaskTemplate)
} else {
$('#taskList').append($newTaskTemplate)
}
// Show the task
$newTaskTemplate.show()
}
},
createTask: async () => {
App.setLoading(true)
const content = $('#newTask').val()
await App.todoList.createTask(content)
window.location.reload()
},
toggleCompleted: async (e) => {
App.setLoading(true)
const taskId = e.target.name
await App.todoList.toggleCompleted(taskId)
window.location.reload()
},
setLoading: (boolean) => {
App.loading = boolean
const loader = $('#loader')
const content = $('#content')
if (boolean) {
loader.show()
content.hide()
} else {
loader.hide()
content.show()
}
}
}
$(() => {
$(window).load(() => {
App.load()
})
})
I get this error in the console :
Again I am a total newbie, any help is appreciated.
Any source of info did not help
Hey after metamask update , it no longer injects web3 .
You can check the blog below , It has shown how to connect metamask with our project .
https://dapp-world.com/blogs/01/how-to-connect-metamask-with-dapp--1616927367052
Only thing is its web application , you can relate it with your project .
Hope it works !

cloud function for sending fcm notifications to a collection of tokens

I am trying to send a notification whenever a new update to my database takes place. I have the onUpdate side working but I am new to FCM and I am stuck at the sending the notification.
The structure of the devices collection is:
+devices/
+tokenId/
-tokenId:njurhvnlkdnvlksnvlñaksnvlkak
-userId:nkjnjfnwjfnwlknlkdwqkwdkqwdd
The function that I have right now that gets stuck with an empty value of token is:
const functions = require('firebase-functions');
const admin = require("firebase-admin");
admin.initializeApp();
const db = admin.firestore();
const settings = { timestampsInSnapshots: true };
db.settings(settings);
.....
exports.fcmSend = functions.firestore
.document(`chats/{chatId}`).onUpdate((change, context) => {
const messageArray = change.after.data().messages;
const message = messageArray[(messageArray.length-1)].content
if (!change.after.data()) {
return console.log('nothing new');
}
const payload = {
notification: {
title: "nuevo co-lab",
body: message,
}
};
return admin.database().ref(`/devices`)
.once('value')
.then(token => token.val())
.then(userFcmToken => {
console.log("Sending...", userFcmToken);
return admin.messaging().sendToDevice(userFcmToken, payload)
})
.then(res => {
console.log("Sent Successfully", res);
})
.catch(err => {
console.log("Error: ", err);
});
});
I am not able to get the token from the database. It is null or undefined. Can anyone help me with this second part of the function?
Thanks a lot in advance!
Thanks Frank for the tip!
I managed to solve the problem with this code in case anybody needs it:
const payload = {
notification: {
title: "nuevo mensaje de co-lab",
body: message,
}
};
// Get the list of device tokens.
const allTokens = await admin.firestore().collection('devices').get();
const tokens = [];
allTokens.forEach((tokenDoc) => {
tokens.push(tokenDoc.id);
});
if (tokens.length > 0) {
// Send notifications to all tokens.
return await admin.messaging().sendToDevice(tokens, payload);
}else {
return null;
}

How to know when the feathers-client is connected to a service

I'm trying to test an event filter however there's a timing issue that I'm not sure how to resolve. Other than wrapping the REST request in a setTimeout, how could I get this working?
const app = require('../../src/app');
const feathers = require('feathers/client')
const socketio = require('feathers-socketio/client');
const hooks = require('feathers-hooks');
const io = require('socket.io-client');
const rp = require('request-promise');
const service = app.service('users');
let server = null;
describe('\'users\' service', () => {
beforeEach((done) => {
server = app.listen('3030');
server.once('listening', done);
});
afterEach((done) => {
server.close(done);
});
it('returns stuff #test', (done) => {
const socket = io('http://localhost:3030');
const app = feathers()
.configure(hooks())
.configure(socketio(socket));
const messageService = app.service('users');
messageService.on('created', message => {
console.log('Created a message', message);
done();
});
socket.on('connection', () => {
//
// The messageService is not connected yet
// so messages.filters.js will not fire
//
// Giving it a chance to connect with setTimeout does work...
// setTimeout(() => {
rp({
method: 'POST',
url: 'http://localhost:3030/users',
body: {
test: 'Message from REST'
},
json: true
});
// }, 500);
});
});
});
I have tried replacing the socket.on with these as well:
messageService.on('connection'
service.on('connection' (based on Node.js EventEmitter)
and so on...
Edit
I have since found service.on('newListener' works however it is being triggered many times. I need to track down the single connection:
const messageService = app.service('users');
messageService.on('created', message => {
console.log('Created a message', message);
done();
});
It's simply service.on('newListener'.
https://nodejs.org/api/events.html#events_event_newlistener
Listeners registered for the 'newListener' event will be passed the event name and a reference to the listener being added.
However, when I implemented this I found that it is listening to 5 different events. So, you need to filter those down:
service.on('newListener', (event, listener) => {
if (event === 'created') {
rp({
method: 'POST',
url: 'http://localhost:3030/users',
body: {
test: 'Message from REST'
},
json: true
});
}
});