I want to run hardhat tests for local network not on testnet, how to configure it? - ethereum

So the problem is I have defined a hardhat config like this
import { HardhatUserConfig, task } from "hardhat/config";
import "#nomicfoundation/hardhat-toolbox";
import * as dotenv from "dotenv";
dotenv.config();
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
const accounts = await hre.ethers.getSigners();
for (const account of accounts) {
console.log(account.address);
}
})
const config: HardhatUserConfig = {
solidity: "0.8.17",
networks: {
// defined defaultNetwork as hardhat so it would use it for testing.
defaultNetwork: {
url: 'hardhat',
},
hardhat: {},
goerli: {
url: process.env.STAGING_QUICKNODE_KEY,
accounts: [process.env.PRIVATE_KEY!]
}
}
};
export default config;
when I run this command on my local machine npx hardhat test it works fine because I guess maybe I have a .env file, but if I remove this .env file or run this command on GitHub workflow it would give me this error.
Error HH8: There are one or more errors in your config file:
* Invalid value undefined for HardhatConfig.networks.goerli.url - Expected a value of type string.
* Invalid account: #0 for the network: goerli - Expected string, received undefined
now the problem is I don't want to upload my .env file on GitHub because it contains my secret key information. I have seen this answer as well and tried it also How do I use different config for testing vs. deployment hardhat solidity?
so I tried to run this command npx hardhat test --network hardhat but it would the same error as above.
I want to know if there is any way to change this config object at runtime in *.spec.ts files, then I can try that way or if you know of any other hacks, please let me know.

The errors mentioned in your question are related to the fact that the config values are invalid. Hardhat expects the accounts items to be of type string (and in the format of "0x followed by 64 hex characters") but they are undefined.
I'm not sure about the proper solution (anyone else feel free to provide a better answer), but you can use a dummy key as a workaround.
goerli: {
url: process.env.STAGING_QUICKNODE_KEY || "https://dummy.url.com",
accounts: [process.env.PRIVATE_KEY || "0x1234567890123456789012345678901234567890123456789012345678901234"]
}
This validation happens before running the tests. So even if you use the hardhat network for tests, it won't allow you to run them if another part of the config is invalid.
npx hardhat test and npx hardhat test --network hardhat is effectively the same command, as hardhat is the default network.

Related

Github Actions: Build Failing for NEXT JS PWA App

I have set up Unit tests to be run before pushing to the main branch via GitHub-actions. All the Unit tests are running successfully but for some reason during the build:
Ran all test suites.
info - Checking validity of types...
info - Creating an optimized production build...
warn - using beta Middleware (not covered by semver)
After this step, it fails with the error:
> Build error occurred
Error: Service account object must contain a string "project_id" property.
This error comes from the Firebase Admin SDK Configuration file as shown below:
import admin from 'firebase-admin';
const keyString = process.env.FB_ADMIN_PRIVATE_KEY ?? '{"privateKey": ""}';
const { privateKey } = JSON.parse(keyString);
if (privateKey === '') {
console.log('FIREBASE_PRIVATE_KEY is not set');
if (process.env.NODE_ENV === 'development')
throw new Error('FIREBASE_PRIVATE_KEY is not set');
else console.log('Firebase Private Key Error');
}
if (admin.apps.length === 0)
admin.initializeApp({
credential: admin.credential.cert({
clientEmail: process.env.FB_ADMIN_CLIENT_EMAIL,
privateKey: privateKey,
projectId: process.env.NEXT_PUBLIC_FB_CLIENT_PROJECT_ID,
}),
databaseURL: process.env.FB_ADMIN_RTDB_URL,
});
const db = admin.firestore();
const auth = admin.auth();
const storage = admin.storage();
const rdb = admin.database();
const Server = { auth, db, storage, rdb };
export default Server;
However, I am not sure why is this method even called? Since I have my .env secrets stored in the local, the build seems to succeed there and fail in Github actions. What should I do to resolve this error?
Since NEXT JS Generates static pages and so I was using Admin SDK to fetch some metadata at the server-side and that's why the function was triggered causing it to fail in Github Actions, seems like the only way out here will be to somehow mock the data in order for the actions to run smoothly.

Testing contracts using time from OpenZepplin library: Error: Invalid JSON RPC response: ""

I increase time the same way as described in OpenZepplin samples in the test below:
it("should revert claim drawing with 'Android: bad state'", async () => {
const [owner, signer1] = await ethers.getSigners();
let duration = time.duration.seconds(3);
await time.increase(duration);
await truffleAssert.reverts(
android.claimPainting(1),
'Android: bad state'
);
});
And it fails with Error: Invalid JSON RPC response: "". How can i fix it?
time is imported as const { time } = require("#openzeppelin/test-helpers"); + "#openzeppelin/test-helpers": "0.5.15" in package.json.
I also use ethers from hardhat, don't know if this could cause the problem.
You will need to execute Hardhat local node server and try again.
"npx hardhat node"
Hope this works on your side.
Install web3 and the hardhat-web3 plugin.
npm install --save-dev #nomiclabs/hardhat-web3 web3
Then add the following line to your hardhat config
import "#nomiclabs/hardhat-web3";

How to run Amazon polly on Firebase Functions?

I got working code on local NodeJs server, then I tried to run same code on Firebase Function and failed.
Here is my code split into 2 files:
// index.js
const functions = require("firebase-functions");
const polly = require("./polly");
exports.pollySynth = functions.https.onCall((req, res) => {
return polly.speak()
});
// polly.js
const AWS = require("aws-sdk");
// Create an Polly client
const Polly = new AWS.Polly({
signatureVersion: "v4",
region: "my-region",
accessKeyId: "keyId,
secretAccessKey: "access key",
});
// Params
const params = {
Text: "Hello world. This is the word of speech!",
OutputFormat: "json",
};
// prettier-ignore
const synthSpeech = function() {
Polly.synthesizeSpeech(params, function(err, res) {
if (err) {
console.log("err", err);
return err;
} else if (res && res.AudioStream instanceof Buffer) {
return res.AudioStream;
}
});
};
module.exports = {speak: synthSpeech};
When trying to deploy this function, I'm getting this error:
Functions deploy had errors with the following functions: pollySynth(us-central1)
I'm not pro coder, so maybe it's just some dumb error in my code.. Please help me :)
That took around half day to solve this issue. The root of the problem was that for some reason, firebase didn't provide detailed error logs. It just said that there is some error in the code.
Only running this command through the command line helped me to understand what's wrong:
firebase functions:log --only pollySynth
I found that command only at StackOverflow, and official documentation didn't mention it.
Log looked this way:
Did you list all required modules in the package.json dependencies?
2021-08-20T12:04:51.823Z ? speechSynth:
Detailed stack trace: Error: Cannot find module 'aws-sdk'
Now I understand that problem is that npm modules was not installed. It worked locally with an emulator, but deploy was throwing an error 🤯
I tried to install aws sdk using commands like this again and again. Tried to add module into package.json manually as well, but nothing worked...
npm install aws-sdk
npm install --save
Then I looked into "node_modules" folder inside the "functions" folder and didn't find that package!
Then I looked at the folder structure installed by default:
- root
- functions
- node modules
- public
It seems like the terminal is running the command on the root folder, and "node_modules" is placed inside the "functions" folder.
So I opened the terminal, moved to the "functions" folder, and installed aws sdk.
cd functions
npm install aws-sdk
And successfully deployed the function!
The next problem was that the function return null. I needed to use a promise to wait for aws server response.
And that code worked for me:
const createSpeech = function() {
return Polly.synthesizeSpeech(params)
.promise()
.then((audio) => {
if (audio.AudioStream instanceof Buffer) {
return audio.AudioStream;
} else {
throw new Error("AudioStream is not a Buffer.");
}
});
};
Now everything works correctly, and I can move to the next steps.

Trigger a cloud build pipeline using Cloud Function

I'm trying to create a cloud function listening to cloudbuilds topic and making an API call to trigger the build. I think I'm missing something in my index.js file (I'm new to Node.js). Can you provide a sample example of a Cloud Function making an API call to the Cloud Build API?
Here is my function:
const request = require('request')
const accessToken = '$(gcloud config config-helper --format='value(credential.access_token)')';
request({
url: 'https://cloudbuild.googleapis.com/v1/projects/[PROJECT_ID]/builds',
auth: {
'bearer': accessToken
},
method: 'POST',
json: {"steps": [{"name":"gcr.io/cloud-builders/gsutil", "args": ['cp','gs://adolfo-test-cloudbuilds/cloudbuild.yaml', 'gs://adolfo-test_cloudbuild/cloudbuild.yaml']}]},
},
module.exports.build = (err, res) => {
console.log(res.body);
});
I was executing the command gcloud config config-helper --format='value(credential.access_token)', copying the token, and putting it as a value to the variable accessToken. But this didn't work for me.
Here is the error: { error: { code: 403, message: 'The caller does not have permission', status: 'PERMISSION_DENIED' } }
I had the same exact problem and I have solved it by writing a small package, you can use it or read the source code.
https://github.com/MatteoGioioso/google-cloud-build-trigger
With this package you can run a pre-configured trigger from cloud build.
You can also extend to call other cloud build API endpoints.
As my understanding cloud build API requires either OAuth2 or a service account. Make sure you gave the right permission to cloud build in the gcp console under IAM. After that you should be able to download the service-account.json file.

web3.eth.accounts.create method doesn't actually create new account

I try to create an eth account via RPC in private network.
What I have done so far are:
launch geth node and create private network.
create simple javascript program using web3 1.0.0, typescript
run and get result as below but the account isn't created
Code:
const result = await web3.eth.personal.unlockAccount(senderId, senderPassword, duration)
if (result === true) {
// const newAccountResult = await web3.eth.personal.newAccount('password')
const newAccountResult = await web3.eth.accounts.create('user01')
console.log(newAccountResult)
}
Result:
web3.eth.accounts.create returns the following result
{ address: '0xf10105f862C1cB10550F4EeB38697308c7A290Fc',
privateKey: '0x5cba6b397fc8a96d006988388553ec17a000f7da9783d906979a2e1c482e7fcb',
signTransaction: [Function: signTransaction],
sign: [Function: sign],
encrypt: [Function: encrypt] }
But web3.eth.getAccounts method returns only 1 account.
[ '0xaf0034c41928Db81E570061c58c249f61CFF57f2' ]
Seems web3.eth.accounts.create method has succeeded as the result includes account address and private key.
But I don't understand why web3.eth.getAccounts method doesn't include the created account.
I also checked geth via console, the result is same.
> eth.accounts
["0xaf0034c41928db81e570061c58c249f61cff57f2"]
And eth.personal.newAccount didn't work.
Do I need to do something after web3.eth.accounts.create?
I appreciate any help.
If i got it right, web.eth.accounts.create is a way to create accounts without storing them on the local node, so its basically a way to get a valid keypair on-the-fly without storing anything on the keystore)
web3.eth.personal.newAccount() should be availabel if you have the personal-API activated on your geth node (which is default behavior for ganache, with geth you need to activate it via geth --dev/testnet --rpc --rpcapi eth,web3,personal (note: of course you should be very careful with allowing personal-API on mainnet, make sure that RPC access is restricted so only you/privileged users can access it)
(async () => {
let newAccount = await web3.eth.personal.newAccount();
console.log(newAccount);
let accounts = await web3.eth.getAccounts();
console.log(accounts);
})();
Should give something like
0xb71DCf0191E2B90efCD2638781DE40797895De66
[
...
'0xb71DCf0191E2B90efCD2638781DE40797895De66' ]
Refs https://medium.com/#andthentherewere0/should-i-use-web3-eth-accounts-or-web3-eth-personal-for-account-creation-15eded74d0eb