Hardhat: how to deploy using a custom signer - deployment

Normally, to deploy contracts to a network, we specify the private keys in accounts section of the network config, Like below, and these accounts get used in signing the transactions.
module.exports = {
defaultNetwork: "rinkeby",
networks: {
hardhat: {
},
rinkeby: {
url: "https://eth-rinkeby.alchemyapi.io/v2/1234",
accounts: [privateKey1, privateKey2, ...]
}
},
But we need to use a custom signer that will sign the transactions instead. All transactions that are part of the deployment process needs to be signed via this custom signer.
How do I do this using Hardhat/ethers.js ?

You have to modify the deployment script to attach your custom signer to the contract factory (https://docs.ethers.io/v4/api-contract.html):
async function main() {
const HelloBar = await ethers.getContractFactory("HelloBar");
const signer = createYourCustomSigner();
// attach the signer to the factory
HelloBar = HelloBar.connect(signer);
const hellobar = await HelloBar.deploy();
await hellobar.deployed();
console.log("Address:", hellobar.address);
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Then run the script with:
npx hardhat run --network localhost scripts/deploy.js

Related

My 'deployed' contract still won't show up on Etherscan. Been about 1.5 hours

need help figuring out why my supposedly 'deployed' contract will still not appear in Etherscan.
Overview:
I used hardhat with following code and got back confirmation:
$ npx hardhat run scripts/deployRoboPunksNFT.js --network rinkeby
RoboPunksNFT deployed to: 0xaBDe0c1A9F7589f21818287287885a2Fef32E3f0
Clearly, it confirms as fully deployed but when I check this contract address at Etherscan (Rinkeby)...nothing: https://rinkeby.etherscan.io/address/0xaBDe0c1A9F7589f21818287287885a2Fef32E3f0
The deployment script used:
const hre = require("hardhat");
async function main() {
const RoboPunksNFT = await hre.ethers.getContractFactory("RoboPunksNFT");
const roboPunksNFT = await RoboPunksNFT.deploy();
await roboPunksNFT.deployed();
console.log("RoboPunksNFT deployed to:", roboPunksNFT.address);
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
My hardhat.config.js
require("#nomiclabs/hardhat-waffle");
const dotenv = require("dotenv");
require("#nomiclabs/hardhat-etherscan");
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);
}
});
/**
* #type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: "0.8.4",
networks: {
rinkeby: {
url: process.env.REACT_APP_RINKEBY_RPC_URL,
accounts: [process.env.REACT_APP_PRIVATE_KEY]
},
},
etherscan: {
apiKey: process.env.REACT_APP_ETHERSCAN_KEY,
}
};
I got so frustrated that I deployed it again (Code above is 2nd attempt/2nd deployed contract. The first deployed contract address was at 0x9F6040234728493121BCB9A1EaFDBa5E494bB3ed.
Please let me know if anyone sees something that I missed. Hopefully there's enuf info I've submitted here to determine...
Thanks very much!
Problem solved. Rinkeby happened to be down for 6 whole hours. But once it came back up, had 2 freshly deployed contracts on Rinkeby ready to go...

Android Enterprises Device Enrollment Stuck with NodeJs Generated QR Code with Service Account Authentication

As mentioned in the google documents i have tested the following process
URL to quick start: https://colab.research.google.com/github/google/android-management-api-samples/blob/master/notebooks/quickstart.ipynb#scrollTo=pjHfDSb8BoBP
Create Enterprise
Create Policy
Enroll the device
Then I have used the NODEJS API of Android Enterprises to develop the server based solution, which is working fine as per the documentation for all the functions such as get, create, delete the policy, devices, enterprises.
The issue i am facing is with the QR code generated from NODE application, when i scan the QR code generated from NODEJS application, the device got stuck at system update.
Following is my Policy update function
router.post('/update/:id', async function(req, res) {
const {title,policy_body,update_mask,enroll_url} = req.body;
// here we are callng the android managment API to and then the response we will update to database
const amApiBody = {
name: policy_body.name,
updateMask:update_mask,
requestBody:policy_body
}
const policy_update_response = await amApi.updatePolicy(amApiBody);
const p = await policyModel.update(req.params.id,title,policy_update_response,enroll_url);
res.json(p)
});
AmAPI file
this.updatePolicy = async function (body)
{
const auth = new google.auth.GoogleAuth({
scopes: ['https://www.googleapis.com/auth/androidmanagement'],
});
const authClient = await auth.getClient();
google.options({auth: authClient});
// Get the list of available policies
const res = await androidmanagement.enterprises.policies.patch(body);
console.log('requestFinalBody=',body);
return res.data;
}
Following is my policy data obtained by running above function
policy_create_response= {
name: 'enterprises/LC019rjnor/policies/policy1',
version: '14',
applications: [
{
packageName: 'com.google.samples.apps.iosched',
installType: 'FORCE_INSTALLED',
autoUpdateMode: 'AUTO_UPDATE_HIGH_PRIORITY'
},
{
packageName: 'com.dekaisheng.courier',
installType: 'FORCE_INSTALLED',
autoUpdateMode: 'AUTO_UPDATE_HIGH_PRIORITY'
}
],
keyguardDisabledFeatures: [ 'KEYGUARD_DISABLED_FEATURE_UNSPECIFIED' ],
defaultPermissionPolicy: 'GRANT',
uninstallAppsDisabled: true,
keyguardDisabled: true,
tetheringConfigDisabled: true,
dataRoamingDisabled: true,
networkEscapeHatchEnabled: true,
bluetoothDisabled: true,
debuggingFeaturesAllowed: true,
funDisabled: true,
kioskCustomLauncherEnabled: true
}
Note i have exported the variable to the terminal as follows before running the app, the auth.json is the service account credential file.
export GOOGLE_APPLICATION_CREDENTIALS="/Users/Mac/Projects/wajid/mdm/server/env/auth.json"
Thanks for the help in advance
I figured out that in nodeJS API I was passing wrong property name of Policy value in the request body.
Code before fix
parent: this.getParent(policyName),
requestBody:{
“name”: “my_policy"
}
Code after fix
parent: this.getParent(policyName),
requestBody:{
"policyName”: “my_policy"
}

Firebase rules test does not pass even when using lockdown

I'm trying to test my firebase rules, but they seem to not pass even when I use lock down mode. I followed the guide at https://firebase.google.com/docs/firestore/security/test-rules-emulator
const firebase = require('#firebase/rules-unit-testing');
const fs = require('fs');
const projectId = 'test-judge';
function getAuthedFirestore(auth) {
return firebase.initializeAdminApp({
projectId: projectId,
auth: auth
}).firestore();
}
beforeEach(async () => {
await firebase.clearFirestoreData({ projectId });
});
before(async () => {
const rules = fs.readFileSync('firestore.rules', 'utf8');
await firebase.loadFirestoreRules({
projectId: projectId,
rules: rules
});
});
after(async () => {
await Promise.all(firebase.apps().map(app => app.delete()));
});
describe('locked down', () => {
it("require users to log in before creating a profile", async () => {
const db = getAuthedFirestore(null);
const profile = db.collection("users").doc("alice");
await firebase.assertFails(profile.set({ birthday: "January 1" }));
});
});
here is my firebase.json
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
}
}
and my package.json
{
"devDependencies": {
"firebase-admin": "^9.11.0",
"#firebase/app": "^0.6.29",
"#firebase/rules-unit-testing": "^1.3.12",
"mocha": "^9.0.3",
"fs-extra": "^10.0.0"
},
"scripts": {
"test": "mocha"
}
}
and here is firestore.rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
It doesn't seem to me like I'm doing anything wrong, but if I run npm test the test fails. I expect it to pass since asserFails is used and in the rules I return false
I should not be able to set the value the test should pass
here is my output
Warning: FIRESTORE_EMULATOR_HOST not set, using default value localhost:8080
locked down
1) require users to log in before creating a profile
0 passing (324ms)
1 failing
1) locked down
require users to log in before creating a profile:
Error: Expected request to fail, but it succeeded.
at C:\Users\Moneer\Desktop\judge_rules\node_modules\#firebase\rules-unit-testing\dist\index.cjs.js:581:31
at async Context.<anonymous> (test\test.js:33:9)
npm ERR! Test failed. See above for more details.
This is expected behavior, Security Rules are what protect your backend services from malicious Client requests. The "AdminApp" is in relation to the Admin-SDK which is a service tool that interacts with the Firebase services directly behind the Security Rules.
For reference, you will notice that the Admin-SDK would normally require Service Account credentials which allows the SDK to authenticate with the GCP IAM services
Just realized I should be using initializeTestApp not initializeAdminApp

NestJS: e2e testing using an axios-based client is not working as expected

I have a NestJS application that exposes some endpoints, and I have written a client application that I plan on releasing as an NPM package to work with the nest server. I am attempting to write end-to-end tests that start the nest server, connect it to a test database in a local docker container, and test it using the client. Here are some snippets of what I'm attempting to do:
Controller:
#Controller('/api/v1/messages')
export class MessagesController {
constructor(
private messagesService: MessagesService
) {}
#Get()
#UsePipes(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true }))
private findAll(
#Query() searchCriteria: MessageSearchDto
): Promise<MessageDto[]> {
if (Object.keys(searchCriteria).length > 0)
return this.messagesService.search(searchCriteria);
return this.messagesService.findAll();
}
}
Client:
const http = require('axios');
const dotenv = require('dotenv');
dotenv.config();
export class MessageClient {
public baseUri: string = process.env.MessageClientTarget ?? './';
constructor() {}
public async findAll() {
return await http.get(this.baseTarget());
}
private baseTarget() {
return `${this.baseUri}/api/v1/messages`;
}
}
e2e Test:
describe('MessageController (e2e)', () => {
let app: INestApplication;
let client: MessageClient = new MessageClient();
beforeAll(async () => {
let moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule, MessagesModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
afterAll(async () => {
await app.close();
});
it('/ (GET)', async done => {
const { data: messages } = await client.findAll()
expect(messages).toEqual([]);
done();
});
});
And .env:
MessageClientTarget=http://localhost:3000
When I attempt to run this, I get the following error: "connect ECONNREFUSED 127.0.0.1:3000"
From what I understand, this is because the createNestApplication method doesn't actually start a server but instead creates a mocked version of the application.
My question is how can I work with INestApplication or TestingModule in order to start the application or what other way do I have to programmatically start a NestJS application. It is important to me that I perform the e2e testing with the Axios based client rather than supertest as a way of testing both the client and the server.
I have verified that the server is supposed to start on port 3000 locally, and I have verified that the client has the correct baseUri set. The address used by the client during testing is: http://localhost:3000/api/v1/messages and was verified by outputting the value to the console during the test. Also, only the database currently lives in a docker container and I have that running correctly. The whole application works perfectly when ran locally and it is only in the test that it is failing.
Please make sure that the test environment where you are running tests is set to node. Add testEnvironemnt:'node' jest parameter in your jest configuration file.
You can run e2e tests with any client of your choice regardless of whether or not you are running a nestjs testing module or the actual nestjs application instance.
I personally use testing module as it makes very easy to mock any third-party dependencies of the application when testing it (that is the main purpose of the testing module, providing an elegant manner to substitute or mock any component that you may want to).

Why isn't my Firebase app connecting to Google Secret Manager?

I can't figure out why I keep getting the error: Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.
firebase login from my command line returns that I am already logged in and
I have configured my-app#appspot.gserviceaccount.com to be a Secret Manager Secret Accessor in the GCP IAM admin dashboard within the same project.
Here's the code I'm using:
const { SecretManagerServiceClient } = require("#google-cloud/secret-manager");
const client = new SecretManagerServiceClient();
const gcpSecretsLoader = async (secretName: string) => {
try {
const secret = await client.accessSecretVersion({
name: `projects/my-app/secrets/${secretName}/versions/latest`,
});
const payload = secret.payload.data.toString("utf8");
console.info(`Payload: ${payload}`);
} catch (err) {
console.log(err);
}
};
gcpSecretsLoader("CLIENT_ID"); // CLIENT_ID matched a secret name within the secret manager