How to call the Home Graph API with gRPC on Node.js - node.js

Given the protocol buffers definition available at: https://github.com/googleapis/googleapis/blob/master/google/home/graph/v1/homegraph.proto
How can one call the Home Graph API RPC endpoint using gRPC on Node.js to multiplex concurrent API method calls over a single connection?

You can use #grpc-js in combination with Application Default Credentials to initialize the credentials.
$ npm install #grpc/grpc-js
$ npm install google-auth-library
$ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account-key.json
const grpc = require('#grpc/grpc-js');
const { GoogleAuth } = require('google-auth-library');
async function getCredentials() {
const sslCredentials = grpc.credentials.createSsl();
const googleAuth = new GoogleAuth({
scopes: 'https://www.googleapis.com/auth/homegraph'
});
const authClient = await googleAuth.getClient();
const callCredentials = grpc.credentials.createFromGoogleCredential(
authClient
);
const credentials = grpc.credentials.combineChannelCredentials(
sslCredentials,
callCredentials
);
return credentials;
}
Use google-proto-files with #grpc/proto-loader to load the Home Graph service protobuf definition with its dependencies.
const protoLoader = require('#grpc/proto-loader');
const protos = require('google-proto-files');
async function getHomegraph() {
const homegraphProto = await protoLoader.load(
protos.getProtoPath('home/graph', 'v1', 'homegraph.proto'), {
includeDirs: [protos.getProtoPath('..')]
}
);
const homegraph = grpc.loadPackageDefinition(
homegraphProto
).google.home.graph.v1;
return homegraph;
}
And finally initialize client stubs to call the HomeGraphApiService methods.
(async function() {
const credentials = await getCredentials();
const homegraph = await getHomegraph();
const homegraphService = new homegraph.HomeGraphApiService(
'homegraph.googleapis.com', credentials
);
homegraphService.sync({
agentUserId: 'AGENT_USER_ID'
}, function(err, result) {
if (err) {
console.error(err);
} else {
console.log(result);
}
});
// homegraphService.query();
// homegraphService.requestSyncDevices();
// homegraphService.reportStateAndNotification();
// homegraphService.deleteAgentUser();
})();
Note that by default the Channel implementation will reuse existing channels from a global pool if the parameters (address, credentials and options) are the same. You can alter this behavior with the grpc.use_local_subchannel_pool option.

Related

Issue leveraging keycloak-verify to instantiate keyclock object verifier

I'm leveraging this library here (https://www.npmjs.com/package/keycloak-verify)
For some reason.. requiring the class and then trying to instantiate gives me an error
TypeError: Keycloak is not a function
My code is below, I have also tried to print out the Keycloak object from the const and it gives me
{ default: [Function: Keycloak] }
Shouldn't just calling Keycloak() leverage that default function instead of giving me an error?
Thanks!
const Keycloak = require('keycloak-verify');
const run = async() => {
console.log(Keycloak)
const config = { realm: 'users', authServerUrl: 'localhost://8080' };
const keycloak = Keycloak(config);
const accessToken = '12312';
try {
const user = await keycloak.verifyOnline(accessToken);
console.log(user);
} catch(e) {
console.log(e);
}
}
run();
Looking at the compiled index.js it shows
var Keycloak = function Keycloak(config) {
return {
verifyOnline: verifyOnline(config),
verifyOffline: verifyOffline(config)
};
};
var _default = Keycloak;
exports["default"] = _default;

Web3 smart contract instance is not able to listen Transfer events

I have a NFT deployed on the mainnet, and I want to listen any mint event by watching the Transfer event via web3js. But unfortunately I am not able to retrieve any Transfer event happening. But the thing is that, when I try to getPastEvents, I successfully retrieve the correct data so it is most likely not due to another part of the code.
Here is my relevant piece of code:
const Web3 = require('web3')
const nodeClient = require('node-rest-client-promise').Client()
const dotenv = require('dotenv')
dotenv.config()
const CONTRACT_ADDRESS = '0x8d4B648F7fAB1c72d1690b42693fb7525ce3025e'
const projectId = process.env.INFURA_KEY
const etherscanKey = process.env.ETHERSCAN_KEY
const etherscan_url = `http://api.etherscan.io/api?module=contract&action=getabi&address=${CONTRACT_ADDRESS}&apikey=${etherscanKey}`
async function getContractAbi() {
const etherscan_response = await nodeClient.getPromise(etherscan_url)
const CONTRACT_ABI = JSON.parse(etherscan_response.data.result);
return CONTRACT_ABI;
}
async function handleTransferEvent(event) {
try{
const fromAddress = event.returnValues.from
const tokenId = event.returnValues.tokenId
console.log("SOMEONE TRANSFERED NFT!")
if(fromAddress == '0x0000000000000000000000000000000000000000') {
console.log("Minted:\n", event.returnValues)
/* Do stuff */
}
}
catch(err) {
console.log(err)
console.log("ERROR WHILE HANDLING TRANSFER EVENT")
}
}
const init = async () => {
var web3 = new Web3('wss://mainnet.infura.io/ws/v3/' + projectId)
console.log("Connected to mainnet")
const CONTRACT_ABI = await getContractAbi()
console.log("Retrieved contract abi")
const contract = new web3.eth.Contract(
CONTRACT_ABI,
CONTRACT_ADDRESS
)
contract.events.Transfer({})
.on('data', handleTransferEvent)
.on('error', console.error)
console.log('Started listening minting events...')
}
init()
You can check the smart contract from https://etherscan.io/address/0x8d4b648f7fab1c72d1690b42693fb7525ce3025e#code
EDIT: I think problem might be related to calling listen event inside a function.

NODEJS Google Admin Api Error: native promise missing, set fetch.Promise to your favorite alternative

I spent a lot of days to find way to authentificate to google admin api with service account. Now I have new error message:
Error: native promise missing, set fetch.Promise to your favorite alternative
Here my code:
require('../global')
const fs = require('fs');
const {google} = require('googleapis');
const KEYFILE = global.service_account;
const SCOPES = global.scopes;
(async function run() {
async function readPrivateKey() {
const content = fs.readFileSync(KEYFILE);
return JSON.parse(content.toString());
}
async function authenticate(key) {
const jwtClient = new google.auth.JWT(
key.client_email,
null,
key.private_key,
SCOPES
);
await jwtClient.authorize();
return jwtClient;
}
async function createEvent(auth) {
let admin = google.admin({ version: 'directory_v1' });
await admin.users.list({
customer:'my_customer',
maxResults: 500
});
}
// MAIN
try {
const key = await readPrivateKey();
console.log(key)
const auth = await authenticate(key);
await createEvent(auth);
} catch (e) {
console.log('Error: ' + e);
}
})();
This means you're using an older version of Node (< 6.0.0) that doesn't have Promise functionality and should upgrade to a newer version, otherwise you have to use a library like Bluebird to provide Promise functionality.

How to fetch list of transactions using hyperledger fabric node sdk

I want to fetch list of transaction using the node sdk, but I couldn't find any reference for that, I'm using high level node sdk of the fabric.
Below is my code that I have used to connect to the network:
'use strict';
const { FileSystemWallet, Gateway } = require('fabric-network');
const fs = require('fs');
const path = require('path');
const ccpPath = path.resolve(__dirname, 'connection.json');
const ccpJSON = fs.readFileSync(ccpPath, 'utf8');
const ccp = JSON.parse(ccpJSON);
async function main() {
const identity = 'testuser';
try {
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
// Check to see if we've already enrolled the user.
const userExists = await wallet.exists(identity);
if (!userExists) {
console.log(`An identity for the user "${identity}" does not exist in the wallet`);
console.log('Run the registerUser.js application before retrying');
return;
}
// Create a new gateway for connecting to our peer node.
const gateway = new Gateway();
await gateway.connect(ccp, { wallet, identity: identity, discovery: { enabled: false } });
// Get the network (channel) our contract is deployed to.
const network = await gateway.getNetwork('mychannel');
} catch (error) {
console.error(`Error: ${error}`);
process.exit(1);
}
}
main();
I'm connected to the network, but don't what function to use to fetch recent transactions and paginate.
Any help is appreciated, thanks.
see https://fabric-sdk-node.github.io/release-1.4/Channel.html#queryBlock - and the block info (with the tx_ids inside the data array) is described here -> https://fabric-sdk-node.github.io/release-1.4/global.html#Block

google-api-nodejs-client is not fetching details

I am using google-api-nodejs-client oauth2.js and console is not showing any errors but no profile details are getting fetched of the signed in user in console. Here, is my code where "Hey there.2" is the last line that is getting displayed in console. Can someone point me the incorrect part?
I have included oauth2.keys.json in the directory.
Edit: I just found that Hey there.3 got displayed but after a very big time interval.
'use strict';
const fs = require('fs');
const path = require('path');
const http = require('http');
const url = require('url');
const opn = require('opn');
const destroyer = require('server-destroy');
const {google} = require('googleapis');
const plus = google.plus('v1');
console.log("Hey there.1");
/**
* To use OAuth2 authentication, we need access to a a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI. To get these credentials for your application, visit https://console.cloud.google.com/apis/credentials.
*/
const keyPath = path.join(__dirname, 'oauth2.keys.json');
let keys = {redirect_uris: ['']};
if (fs.existsSync(keyPath)) {
keys = require(keyPath).web;
}
/**
* Create a new OAuth2 client with the configured keys.
*/
const oauth2Client = new google.auth.OAuth2(
keys.client_id,
keys.client_secret,
keys.redirect_uris[0]
);
/**
* This is one of the many ways you can configure googleapis to use authentication credentials.
In this method, we're setting a global reference for all APIs.
Any other API you use here, like google.drive('v3'), will now use this auth client.
You can also override the auth client at the service and method call levels.
*/
google.options({auth: oauth2Client});
/**
* Open an http server to accept the oauth callback.
The only request to our webserver is to /callback?code=<code>
*/
async function authenticate(scopes) {
return new Promise((resolve, reject) => {
// grab the url that will be used for authorization
const authorizeUrl = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: scopes.join(' '),
});
console.log("Hey there.2");
const server = http
.createServer(async (req, res) => {
try {
console.log("Hey there.3");
if (req.url.indexOf('google') > -1) {
//const qs = querystring.parse(url.parse(req.url).query);
const qs = new url.URL(req.url).searchParams;
res.end('Authentication successful! Please return to the console.');
server.destroy();
//const {tokens} = await oauth2Client.getToken(qs.code);
const {tokens} = await oauth2Client.getToken(qs.get('code'));
oauth2Client.credentials = tokens;
resolve(oauth2Client);
console.log("Hey there.4");
}
} catch (e) {
console.log(e);
reject(e);
}
})
.listen(3000, () => {
// open the browser to the authorize url to start the workflow
opn(authorizeUrl, {wait: false}).then(cp => cp.unref())
;
});
destroyer(server);
});
}
async function runSample() {
// retrieve user profile
const res = await plus.people.get({userId: 'me'});
console.log(res.data);
console.log("Hey there.5");
console.log(userId);
}
const scopes = ['https://www.googleapis.com/auth/plus.login'];
authenticate(scopes)
.then(client => runSample(client))
.catch(console.error);

Resources