Since items can only be minted by the marketplace authority, the buyVirtual method requires a signature from the marketplace authority (and the new mint). The transactions.buyVirtual method can be used to generate a signed transaction to be sent back to the buyer for their signature.
// ...User requests a buy virtual transaction
// Backend
const collectionConfigPDA = carbon.pdas.collectionConfig(collectionMintAddress)
const collectionConfig = await carbon.program.account.collectionConfig.fetch(collectionConfigPDA)
const listingPDA = carbon.pdas.listing(itemId)
const listing = await carbon.program.account.listing.fetch(listingPDA)
const {transaction} = await carbon.transactions.buyVirtual({
buyer,
collectionConfig,
listing,
metadata: { // Generated based on what this item is
name,
uri
}
})
const responseBody = {
tx: transaction.serialize({
// Buyer still needs to sign
requireAllSignatures: false,
verifySignatures: false
}).toString('base64'),
}
// ...Send responseBody back to buyer for signature
// Frontend
const tx = Transaction.from(Buffer.from(responseBody.tx, 'base64'));
const signedTx = await anchorWallet.signTransaction(tx)
const serialized = signedTx.serialize()
const signature = await conn.sendRawTransaction(serialized)
With Custody
Depending on your use case, you may want to also ensure the item is put in the marketplace authority's control via delegation. In this case use the transactions.buyVirtualAndCustody method to custody the new mint.
Buying NFTs
When buying an item that's already been minted as an NFT, it's much more straightforward. Similarly with the above example, we can also use the buyNftAndCustody method to also custody the item.