Unable to issue identity card using Hyperledger Composer Javascript API - hyperledger-composer

I am trying to create an identity card using the javascript API of Hyperledger Composer. Here is the code:
const BusinessNetworkConnection = require('composer-
client').BusinessNetworkConnection;
async function identityIssue() {
let businessNetworkConnection = new BusinessNetworkConnection();
try {
await businessNetworkConnection.connect('admin#demoNetwork');
let result = await businessNetworkConnection.issueIdentity('org.acme.demoNetwork.Participant#testUser', 'test');
console.log(`userID = ${result.userID}`);
console.log(`userSecret = ${result.userSecret}`);
await businessNetworkConnection.disconnect();
} catch(error) {
console.log(error);
process.exit(1);
}
}
identityIssue();
I already have a participant testUser.
Although the code succeeds and I get the userID and userSecret, no card is created.
Does anyone have an idea how to do it instead of using the cli?

You haven't imported the card.
eg,
async function importCardForIdentity(cardName, identity) {
const metadata = {
userName: identity.userID,
version: 1,
enrollmentSecret: identity.userSecret,
businessNetwork: businessNetworkName
};
const card = new IdCard(metadata, connectionProfile);
await adminConnection.importCard(cardName, card);
}
See also nodejs test hyperledger composer v0.15 fails with Error: Card not found: PeerAdmin#hlfv1 (answer) it has an example too.
After importing, you should connect with your card to download the cert/key to the wallet eg await businessNetworkConnection.connect(cardName);

Related

How to make an auction with the new metaplex js sdk?

I am working on building a solana marketplace and trying to update from the old solana marketplace to auction house.
code:
const authority = metaplex.identity();
const auctionHouse = await metaplex
.auctions()
.createAuctionHouse({
sellerFeeBasisPoints: 200,
requiresSignOff: false,
treasuryMint: WRAPPED_SOL_MINT,
authority: authority.publicKey,
canChangeSalePrice: true,
feeWithdrawalDestination: publicKey,
treasuryWithdrawalDestinationOwner: publicKey,
})
.run();
const listNft = async () => {
try {
const NFTs = await metaplex.nfts().findAllByOwner(publicKey).run();
console.log(NFTs[4].mintAddress.toString(), " nft");
const auctionHouse = await metaplex
.auctions()
.findAuctionHouseByCreatorAndMint(publicKey, WRAPPED_SOL_MINT)
.run();
const listtx = metaplex
.auctions()
.builders()
.createListing({
mintAccount: NFTs[4].mintAddress,
price: lamports(1 * LAMPORTS_PER_SOL),
auctionHouse: auctionHouse,
});
var rpcClient = await metaplex.rpc().sendTransaction(listtx);
console.log(rpcClient, "listed nft");
} catch (error) {
console.log(error);
}
};
const getListing = async () => {
const NFTs = await metaplex.nfts().findAllByOwner(publicKey).run();
const retrievedAuctionHouse = await metaplex
.auctions()
.findAuctionHouseByCreatorAndMint(publicKey, WRAPPED_SOL_MINT)
.run();
console.log(retrievedAuctionHouse?.address?.toString(), "auction pubkey");
const retrieveListing = await metaplex
.auctions()
.for(retrievedAuctionHouse)
.findListingByAddress(NFTs[4].mintAddress)
.run();
console.log(retrieveListing, "retrieving listings");
};
const bidNft = async () => {
const NFTs = await metaplex.nfts().findAllByOwner(publicKey).run();
const auctionHouse = await metaplex
.auctions()
.findAuctionHouseByCreatorAndMint(publicKey, WRAPPED_SOL_MINT)
.run();
const { bid, buyerTradeState } = await metaplex
.auctions()
.for(auctionHouse)
.bid({
mintAccount: NFTs[5].mintAddress,
price: lamports(0.5 * LAMPORTS_PER_SOL),
});
console.log(bid, buyerTradeState, "bidding");
};
errors:
when trying to list nft:
MetaplexError: AuctionHouseProgram > Account is already initialized"
Source: Program > AuctionHouseProgram [hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk]
Problem: The program [AuctionHouseProgram] at address [hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk] raised an error of code [1] that translates to "Account is already initialized"".
Solution: Check the error message provided by the program.
Caused By: TokenLendingError#AlreadyInitialized: Account is already initialized"
at RpcClient.parseProgramError (RpcClient.mjs?e98e:206:1)
at RpcClient.sendTransaction (RpcClient.mjs?e98e:48:1)
When trying to fetch listings:
Account.mjs?9f45:47 Uncaught (in promise) MetaplexError: Account Not Found
Source: SDK
Problem: The account of type [ListingReceipt] was not found at the provided address [3m517hu6UuV5HjdLmb2GxZkttKTtQ8VseHRCPuUTDJmz].
Solution: Ensure the provided address is correct and that an account exists at this address.
at assertAccountExists (Account.mjs?9f45:47:1)
at eval (Account.mjs?9f45:39:1)
at Object.handle (findListingByAddress.mjs?1810:23:44)
at async eval (Task.mjs?1340:58:1)
at async Disposable.run (Disposable.mjs?b308:22:1)
Found a way around
Instead of using metaplex.auction().builder().createListing i used metaplex.auctions().for(auctionHouse).list().
Then funded the auction fee payer account which is a pda.
Finally in findListingByAddress i passed the sellerTradeState
const { listing, sellerTradeState } = await metaplex
.auctions()
.for(auctionHouse)
.list({
mintAccount: NFTs[1].mintAddress,
price: sol(1.5),
})
.run();
For fetching the listed nft
const retrieveListing = await metaplex
.auctions()
.for(retrievedAuctionHouse)
.findListingByAddress(
sellerTradeState
)
.run();
Just from the information provided above, there are two issues:
You might have run the createAuctionHouse instruction already once which created the Auction house and now that you are running the listNft function which also runs createAuctionHouse instruction, it throws an Account already exists error. You can see why this happens here: https://stackoverflow.com/a/72808405/19264629
You are using the NFTs mint address in findListingByAddress instruction, which is wrong. You have to create a ListingReceipt as stated here: https://docs.metaplex.com/guides/auction-house/#auction-house-receipts while creating the listing itself (this needs to be done in one single transaction). Once this is done, you need to plugin the receipt address in the findListingByAddress to fetch the listings.
Got it to work. The trick was to fund the auction house "Fee Account" as explained above and in Auction House CLI: I cannot execute the sale instruction to list my NFT
const ah = await mx
.auctionHouse()
.findByAddress({ address:ahKey })
.run();
const nft = await mx
.nfts()
.create({
name:"TESTNFT",
symbol: "TESTNFT",
uri: "https://blah.com",
sellerFeeBasisPoints : 100,
creators: [
{
address: wallet.publicKey,
share: 100,
}]
})
.run();
const price = sol(0.1);
const { listing, sellerTradeState } = await mx
.auctionHouse()
.list({
auctionHouse: ah,
mintAccount: nft.mintAddress,
price
})
.run()

How to use TeamsFx useGraph hook to get meeting infos

I would like to use TeamsFx React package to call MS Graph Api.
I tried to do separated component
import { useContext } from "react";
import { useGraph } from "#microsoft/teamsfx-react";
import { TeamsFxContext } from "../Context";
import { TeamsFxProvider } from "#microsoft/mgt-teamsfx-provider";
import { Providers, ProviderState } from "#microsoft/mgt-element";
import * as microsoftTeams from "#microsoft/teams-js";
export function MeetingContext(props: { showFunction?: boolean; environment?: string }) {
const { teamsfx } = useContext(TeamsFxContext);
const { loading, error, data, reload } = useGraph(
async (graph, teamsfx, scope) => {
// Call graph api directly to get user profile information
let profile;
try {
profile = await graph.api("/me").get();
} catch (error) {
console.log(error);
}
// Initialize Graph Toolkit TeamsFx provider
const provider = new TeamsFxProvider(teamsfx, scope);
Providers.globalProvider = provider;
Providers.globalProvider.setState(ProviderState.SignedIn);
let photoUrl = "";
let meeting =null;
try {
const photo = await graph.api("/me/photo/$value").get();
photoUrl = URL.createObjectURL(photo);
microsoftTeams.getContext(async (context)=>{
console.log(context);
try {
meeting = await graph.api(`/me/onlineMeetings/${context.meetingId}`).get();
} catch (error) {
console.error(error);
}
})
} catch {
// Could not fetch photo from user's profile, return empty string as placeholder.
}
console.log(meeting);
return { meeting };
},
{ scope: ["User.Read","User.Read","OnlineMeetingArtifact.Read.All"," OnlineMeetings.Read"], teamsfx: teamsfx }
);
return (
<>
</>
)
}
When I debug my interpreter stops on
profile = await graph.api("/me").get();
Then it does not pass after.
I would like also to know what should I put in scope field ?
Should I put the authorisations listed here ?
Should I also Add them in registered app in Azure Portal ?
Update:
I'm getting response from
Failed to get access token cache silently, please login first: you need login first before get access token.
I'm using the teams toolkit and I'm already logged in . I don't know what Should I do to be considered as logged in ?
Update :
I have updated my app api authorisations in azure portal now I'm not getting anymore this error.
But I'm getting a new error :
meeting = await graph.api(`/me/onlineMeetings/${context.chatId}`).get();
"Invalid meeting id
19:meeting_MzU0MzFhYTQtNjlmOS00NGI4LTg1MTYtMGI3ZTkwOWYwMzk4#thread.v2."
I'll post a new question about this as it not the original problem
You can get the details of an online meeting using videoTeleconferenceId, meeting ID, or joinWebURL.
Instead of ChatID you have to use meeting ID or you have to use filter with videoTeleconferenceId or joinWebURL.
The invalid meeting ID error get because
chatID is not the correct parameter for this graph API.
You can refer below API for getting meeting information.
To get an onlineMeeting using meeting ID with delegated (/me) and app (/users/{userId}) permission:
GET /me/onlineMeetings/{meetingId}
GET /users/{userId}/onlineMeetings/{meetingId}
To get an onlineMeeting using videoTeleconferenceId with app permission*:
GET /communications/onlineMeetings/?$filter=VideoTeleconferenceId%20eq%20'{videoTeleconferenceId}'
To get an onlineMeeting using joinWebUrl with delegated and app permission:
GET /me/onlineMeetings?$filter=JoinWebUrl%20eq%20'{joinWebUrl}'
GET /users/{userId}/onlineMeetings?$filter=JoinWebUrl%20eq%20'{joinWebUrl}'
Ref Doc: https://learn.microsoft.com/en-us/graph/api/onlinemeeting-get?view=graph-rest-1.0&tabs=http

How to create an account on NEAR protocol?

I would like to learn how to create an account using RPC or REST calls on NEAR protocol.
If you want to create a subaccount (a.frol.near when you own frol.near): Submit a transaction with CREATE_ACCOUNT, TRANSFER, ADD_KEY actions. Here is an example of such a transaction.
If you want to create *.near account, you need to submit a transaction with create_account function call on near contract. Here is an example of such a transaction, and here is a code snippet from the tutorial in the docs using near-api-js JS library:
const HELP = `Please run this script in the following format:
node create-testnet-account.js CREATOR_ACCOUNT.testnet NEW_ACCOUNT.testnet AMOUNT
`;
const { connect, KeyPair, keyStores, utils } = require("near-api-js");
const path = require("path");
const homedir = require("os").homedir();
const CREDENTIALS_DIR = ".near-credentials";
const credentialsPath = path.join(homedir, CREDENTIALS_DIR);
const keyStore = new keyStores.UnencryptedFileSystemKeyStore(credentialsPath);
const config = {
keyStore,
networkId: "testnet",
nodeUrl: "https://rpc.testnet.near.org",
};
if (process.argv.length !== 5) {
console.info(HELP);
process.exit(1);
}
createAccount(process.argv[2], process.argv[3], process.argv[4]);
async function createAccount(creatorAccountId, newAccountId, amount) {
const near = await connect({ ...config, keyStore });
const creatorAccount = await near.account(creatorAccountId);
const keyPair = KeyPair.fromRandom("ed25519");
const publicKey = keyPair.publicKey.toString();
await keyStore.setKey(config.networkId, newAccountId, keyPair);
return await creatorAccount.functionCall({
contractId: "testnet",
methodName: "create_account",
args: {
new_account_id: newAccountId,
new_public_key: publicKey,
},
gas: "300000000000000",
attachedDeposit: utils.format.parseNearAmount(amount),
});
}
If you don't need a named account, you can just generate a new ed25519 key-pair, and the hex representation of the public key will be your account id (it won't be recorded on chain until you/someone transfers some NEAR tokens to it, and so it is called "implicit" account). Example for such an account.
Here is a detailed tutorial on how to construct a transaction. Ultimately, you will submit your transaction via JSON RPC broadcast_tx* endpoints.

Receiving "Phantom - RPC Error: Transaction creation failed" while building solana escrow with #solana/web3.js

I am trying to replicate https://github.com/dboures/solana-random-number-betting-game
Although when I try to initiate my the Escrow I receive the following error:
Phantom - RPC Error: Transaction creation failed.
Uncaught (in promise) {code: -32003, message: 'Transaction creation failed.'}
I am using Phantom Wallet with Solana RPC.
const transaction = new Transaction({ feePayer: initializerKey })
let recentBlockHash = await connection.getLatestBlockhash();
transaction.recentBlockhash = await recentBlockHash.blockhash;
const tempTokenAccount = Keypair.generate();
// Create Temp Token X Account
transaction.add(
SystemProgram.createAccount({
programId: TOKEN_PROGRAM_ID,
fromPubkey: initializerKey,
newAccountPubkey: tempTokenAccount.publicKey,
space: AccountLayout.span,
lamports: await connection.getMinimumBalanceForRentExemption(AccountLayout.span )
})
);
const { signature } = await wallet.signAndSendTransaction(transaction);
let txid = await connection.confirmTransaction(signature);
console.log(txid);
You're trying to create an account without signing with the keypair of that account to prove ownership.
You have to add the keypair as a signer like such:
await wallet.signAndSendTransaction(transaction, {signers: [tempTokenAccount]})
I was able to solve my problem by using the following code:
const signed = await wallet.request({
method: "signTransaction",
params: {
message: bs58.encode(transaction.serializeMessage())
}
});
const signature = bs58.decode(signed.signature)
transaction.addSignature(initializerKey, signature);
transaction.partialSign(...[tempTokenAccount]);
await connection.sendRawTransaction(transaction.serialize())
instead of:
await wallet.signAndSendTransaction(transaction, {signers: [tempTokenAccount]})
Basically at first I was using one simple function to perform all the above steps, however, for some reason it was not working and throwing the subjected error. When I used this breakdown code it worked!. The cause of the error is still mysterious to me.
Thank you.

Stripe returns a "No such token" error (Plaid Integration)

I am getting this error from Stripe when I try to create a new source for the selected bank account. I am using the new (beta) version of the Plaid Node SDK. Here is my code:
let user;
const mode = "sandbox";
const dsService = new CaspioDsService();
// Load the user if not already loaded by cognitoAuth
if (!req.user) {
user = new User(
dsService,
new CaspioRefDataService(),
new AuthUserService({
organizationId: res.locals.organization.Organization_ID,
isAuthenticated: res.locals.isAuthenticated,
})
);
await user.load(req.params.userId);
} else {
user = req.user.userObject;
}
const configuration = new Configuration({
basePath: PlaidEnvironments[mode],
baseOptions: {
headers: {
"PLAID-CLIENT-ID": config.plaid.clientId,
"PLAID-SECRET": mode === "sandbox" ? config.plaid.secretSandbox : config.plaid.secretProduction,
"Plaid-Version": "2020-09-14",
},
},
});
const plaidClient = new PlaidApi(configuration);
console.log(configuration.basePath); // https://sandbox.plaid.com
// Exchange the public token for the Plaid access token
const plaidTokenRes = await plaidClient.itemPublicTokenExchange({
public_token: req.body.publicToken,
});
const accessToken = plaidTokenRes.data.access_token;
console.log(accessToken); // access-sandbox-d92396c2-1f49-4780-9ae9-23d50645f364
// Get the Stripe bank account token from Plaid
const stripeTokenRes = await plaidClient.processorStripeBankAccountTokenCreate({
access_token: accessToken,
account_id: req.body.accountId
});
const bankAccountToken = stripeTokenRes.data.stripe_bank_account_token;
console.log(bankAccountToken); // btok_1JFMGwGq7ejZoSiwGmM8WSSm
let stripeCustomerId = user.getStripeToken();
const stripeClient = await StripeHelper.getStripeClient(mode); // Get Stripe client in sandbox mode
console.log(stripeCustomerId); // cus_Jt7AWZjC8rHPzt
// Add the source to the Stripe customer and get the bank account info
const bankAccount = await stripeClient.customers.createSource(stripeCustomerId, {
source: bankAccountToken,
}); // Error: No such token: 'btok_1JFMGwGq7ejZoSiwGmM8WSSm'
Any ideas what I might be doing wrong? I expect the issue is with my code, or possibly Plaid (I don't think it is a Stripe problem).
It sounds like you're getting a token from Plaid, but Stripe is rejecting it, which suggests a problem with the relationship between your Plaid and Stripe setups. Are you sure that you enabled the Plaid/Stripe integration in the Plaid dashboard and that the client id / secret you're using matches the Plaid account where the integration is enabled? The Plaid docs also suggest that this error can be caused by using a mismatched set of environments (e.g. using Production with Stripe but Sandbox with Plaid).
The problem was that we had the wrong Stripe account connected. Silly one, but I'm posting this in case anyone else makes the same mistake.

Resources