Create wallet instance from existing file system wallet - hyperledger-fabric

In fabric-samples, when you start the application-javascript, it builds a wallet using the following:
const wallet = await buildWallet(walletPath);
I want to use a file system wallet so the walletPath points to, say, /wallet directory. When I restart the network and submit a transaction, I need to create the Gateway first using the wallet. But the walletPath already exists. How do I create a Wallet instance given an existing walletPath? Do I need to call buildWallet again?

The first thing to say is that, if you are using (or can use) Fabric v2.4+, you should use the Fabric Gateway client API instead of the legacy Node SDK. The Fabric Gateway client API does not require a wallet.
With the Node SDK, the Wallet (or rather the WalletStore that backs the Wallet) just provides a storage location for your client credentials. These typically consist of the Member Services Provider (MSP) ID of the organization that your client identity belongs to, an X.509 certificate, and associated private key.
To use existing client credentials, just create a Wallet pointing at the existing location. For a FileSystemWallet, this would be the wallet directory. If you have created a new network with new client credentials, you probably want to create a FileSystemWallet pointing at a new (empty) directory and populate that with your new client credentials. You could pick a different directory name or, if you no longer need the old credentials, delete the old wallet directory to start fresh.
This tutorial might help clarify how wallets work:
https://hyperledger.github.io/fabric-sdk-node/release-2.2/tutorial-wallet.html

Related

Hyperledger Besu - User Account Management

I have recently started to learn the Hyperledger Besu, and what I am trying to do is actually compare Besu with Fabric and see if it is compatible with my already finished Fabric project.
I know from Fabric that using the CA from an organization we can create new users that are under that org. Also, there is the option to name this user with a username and add some custom attributes that can be used in the chaincode like attribute role for example.
Now, in Besu I have only discovered so far that only with some third party tools like MetaMask and the js library web3j we can create accounts. Although, those accounts are in the form of Public Key/Address & Private Key.
Is there something that I have missed out?
Is it possible to have somehow similar user accounts in Besu like Fabric?
Thank you
After my own research I have concluded that these are the only ways to create accounts for Hyperledger Besu:
MetaMask Wallet
web3 js library through javascript
In order to have more specific accounts that may be connected with some user information or roles that could determine various things in the application, the most suitable option is the following:
Use a centralized database to store the user information and associate it with the users address. This database could be used from a client application where the user can login with his/her credentials or using a third-party wallet like MetaMask.
Also, to distinguish the users inside the smart contracts the best option so far seems to be the library of OpenZeppelin Ownable

Login an existing user in hyperledger fabric

I want to create a UI where i want to login the user which is already created in fabric.Tried using this(https://github.com/hyperledger/fabric-samples/tree/release-1.3/balance-transfer) but as per the login request sample API, it is always creating a new user.
Any sample or ideas to login the existing users with fabric node SDK.
The new user will be created if it does not find the same user in the wallet. Make sure when you create a user, you are keeping the identity in the wallet.

How to get Google Ads API for getting account list

How to query api to get the list of accounts for a customer using Nodejs.
Customer details can be fetched by https://googleads.googleapis.com/v3/customers/xxxxxxxxx/. but How can I fetch all the account for a particular customer?
Yes, accounts list can be accessible. ListAccessibleCustomers returns resource names of customers directly accessible by some Google Account. You might filter manager accounts from the response and list all client accounts for manager accounts.
Since clients customers might be managers too you might need some kind of recursion to build an accounts tree.
Apply a GET request to the below URL:
URL:
'https://googleads.googleapis.com/v1/customers:listAccessibleCustomers?key=XXXXXX'
For more details, you can check the documentation
The CustomerService.ListAccessibleCustomers is to retrieve only the list of accounts that are directly accessible by your OAuth credentials.
This being said, even if your OAuth credentials have direct access to your MCC, this service will not include the sub-accounts under your MCC unless your OAuth credentials have direct access to your sub-accounts as well.
Edit: Using manager account credentials to authenticate your API call, you can use ManagedCustomerService.get to retrieve a list of all accounts under your manager account.
As per documentation: Your developer token can belong to Root Manager Account 1, or even a different manager account in another hierarchy: It doesn't affect which accounts you can target, as long as you supply the client customer ID for the targeted account.
To make API calls against Client account A, you can use the OAuth2 credentials of a login associated with Client account A, and set the clientCustomerId request header to the customer ID of either Client A, Manager Account 2, or Root Manager Account 1.
In this structure, OAuth2 credentials for a login associated with Manager Account 3 can make calls only against Client Account C. These credentials cannot make calls targeting Client Account A or B, because it doesn't manage them. OAuth2 credentials of a login associated with Root Manager Account 1 can make calls against any of the accounts in the hierarchy.
Calls made with the credentials of a manager account can only target the manager account or accounts that are beneath it in the hierarchy. Thus, in this hierarchy, only Root Manager Account 1 can make calls against Client Account D.
If you use either of the manager accounts, then set the clientCustomerId to that manager account, or one of its child accounts.
To read more about the ManagedCustomerService here is an official Link
If you still have an issue with this, could you please share the request and response logs so I can take a closer look?
assuming what you want is the sub accounts, aka "client accounts", for the MCC, you can get them by running a report. Here's some code using the nodejs good-ads-api library:
let client = new GoogleAdsApi({ client_id: clientId, client_secret: clientSecret, developer_token: devToken })
let main = await client.listAccessibleCustomers(refreshToken)
let mainId = main.resource_names?.[0]?.split('/').pop()
let mcc = client.Customer({
customer_id: mainId,
refresh_token: refreshToken,
login_customer_id: mainId,
})
let clusterClients = await mcc.report({
entity: 'customer_client',
attributes: ['customer_client.id', 'customer_client.resource_name', 'customer_client.descriptive_name'],
})

how to make a user upload private key file before any transaction in hyperledger fabric?

I understand that Hyperledger stores private key of users in a directory called keystore. i don't want my network to store it rather user should upload this file before any transaction.
How to do it.
I don't have a full code to provide to you and I don't have time to write it. However, here is a flow you can follow:
FRONT END: Allow user to upload files (Example (assuming you are building a web application): http://reusableforms.com/d/o3/html5-contact-form-with-file-upload)
BACK END: Retrieve the file from the request.
BACK END: Create the user context from these files
BACK END: Build/send transaction
FABRIC: Process transaction
BACK END: If transaction is VALID, delete all the information about the user (private key in particular)
BACK END: Send response back to FRONT END
I do not know what is your scenario, but:
I think having the user manage its own keys is a risk, as he can lose it or someone may "hack" the user device to get it.
Having private keys moving on the network may be a security issue, has someone may be able to intercept it.
But as I said, I don't know your scenario. If you are in a closed network then transfering PK might not be a problem. If your client application manages the keys for the user, it may be ok too, but what if the user deletes it by mistake? Or what if the device is broken?
I think there's a misunderstanding of what the keystore folder accomplishes and what you want to accomplish here.
In the context of an MSP, the keystore folder does store private keys. It stores the private keys of the identities represented by the MSP. However, this is highly unique to the node that the MSP is running on.
On a peer, the keystore would store the certificate for the peer and the key for the peer identity. It would not store the keys for any other identity, as that node is not meant to act as that identity (remember that ownership of private = able to act as that identity). It would also store the certificates (not private keys) of the identities meant to act as administrators of that peer.
What exactly are you trying to do by allowing users to upload the private key? If you are trying to allow users to identify themselves to the network, providing their key is not the solution. If it's something else, try and edit your post to explain your use case more clearly so we can help.

Dropbox integration for application

I'm super confused on how to create proper integrations from my web app to dropbox.
I want to list and create files from within the application.
I'm using NodeJS and the Dropbox JS SDK, so far so good.
But I'm not understanding on how to set up the authentication/authorization.
I've created a Dropbox application, generated an API key.
I pass the API Key in my call to the dropbox SDK:
var dbx = new Dropbox({
accessToken:
"ABC_MY_KEY_123"
});
dbx
.filesListFolder({ path: "" })
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
I'm getting the following error back:
status: 400,
[0] error: 'Error in call to API function "files/list_folder": This API function operates on a single Dropbox account, but the OAuth 2 access token you provided is for an entire Dropbox Business team. Since your API app key has team member file access permissions, you can operate on a team member\'s Dropbox by providing the "Dropbox-API-Select-User" HTTP header or "select_user" URL parameter to specify the exact user https://www.dropbox.com/developers/documentation/http/teams
So, should my App have it's own user and then authenticate using that user?
Or is there an API which is Dropbox business wise ?
When first registering a Dropbox app, you choose between either the "Dropbox API" or the "Dropbox Business API". The former will give you an app for connecting to individual user accounts, and the latter will give you an app for connecting to entire Business teams.
The filesListFolder method you're trying to use is a user-specific method, i.e., it operates on a specific user account, and not a Business team entirely.
The error message is indicating that your access token is for a Business team, and so it doesn't know which user to operate on.
If you want any user to connect to your app, you should register a "Dropbox API" app instead.
Or, if you do want to connect to entire Dropbox Business teams only (and selected the "team member file access" permission), you can still use the user endpoints with an access token for a Dropbox Business API app. To do so, you need to specify the desired member ID in the selectUser parameter when making your Dropbox object.

Resources