Skip to content

Instantly share code, notes, and snippets.

@anilhelvaci
Last active May 18, 2023 15:58
Show Gist options
  • Save anilhelvaci/09be0be21b47e75e8e8a25a8b7366e4f to your computer and use it in GitHub Desktop.
Save anilhelvaci/09be0be21b47e75e8e8a25a8b7366e4f to your computer and use it in GitHub Desktop.
Chainboard x Agoric Bootcamp: Assignment 4 Contract Rewrite
import { AmountMath, AssetKind } from '@agoric/ertp';
import { E } from '@endo/eventual-send';
import { offerTo } from '@agoric/zoe/src/contractSupport/zoeHelpers.js';
import { Far } from '@endo/marshal';
// Define NFts supply
const DEFINED_NFTS = harden([
{
id: 1n,
name: 'NFT 1',
description: 'This is the first NFT',
},
{
id: 2n,
name: 'NFT 2',
description: 'This is the second NFT',
},
{
id: 3n,
name: 'NFT 3',
description: 'This is the third NFT',
},
]);
/**
*
* @param {ZCF} zcf
* @return {Promise<void>}
*/
const start = async (zcf) => {
const {
issuers: { Asset: sellIssuer },
tokenKeyword = 'NFT',
} = zcf.getTerms();
const nftMint = await zcf.makeZCFMint(tokenKeyword, AssetKind.SET);
const { issuer: nftIssuer, brand: nftBrand } = nftMint.getIssuerRecord();
const { zcfSeat: nftSeat } = zcf.makeEmptySeatKit();
const amountToMint = AmountMath.make(nftBrand, DEFINED_NFTS);
nftMint.mintGains({ [tokenKeyword]: amountToMint }, nftSeat);
const zoe = zcf.getZoeService();
let sellItemPublicFacet;
const createBuyerInvitation = () => {
return E(sellItemPublicFacet).makeBuyerInvitation();
};
const sell = async (userSeat, offerArgs) => {
const { nftIds, pricePerNFT, sellItemInstallation } = offerArgs;
console.log({
balance: nftSeat.getCurrentAllocation(),
amountToMint,
})
const nftsForSell = harden(
DEFINED_NFTS.filter((nft) => nftIds.includes(nft.id)),
);
const nftForSellAmount = AmountMath.make(nftBrand, nftsForSell);
console.log({nftsForSell})
const issuerKeywordRecord = harden({
Items: nftIssuer,
Money: sellIssuer,
});
const sellItemsTerms = harden({
pricePerItem: pricePerNFT,
});
const { creatorInvitation, publicFacet } = await E(
zoe,
).startInstance(sellItemInstallation, issuerKeywordRecord, sellItemsTerms);
sellItemPublicFacet = publicFacet;
const proposal = harden({
give: { Items: nftForSellAmount },
});
const keywordMapping = harden({
[tokenKeyword]: 'Items',
});
const { userSeatPromise: sellItemsCreatorSeat, deposited } = await offerTo(
zcf,
creatorInvitation,
keywordMapping,
proposal,
nftSeat,
userSeat,
);
deposited
.then(() => userSeat.exit())
.catch(err => console.log("ERROR DEPOSIT", err));
return {
status: 'success',
deposited,
sellItemsCreatorSeat,
};
};
const creatorFacet = Far('creatorFacet', {
getIssuer: () => nftIssuer,
makeSellInvitation: () => zcf.makeInvitation(sell, 'sell nft'),
availableNfts: () => nftSeat.getAmountAllocated(tokenKeyword, nftBrand),
});
const publicFacet = Far('publicFacet', {
getIssuer: () => nftIssuer,
getBrand: () => nftBrand,
createBuyerInvitation,
});
return harden({ creatorFacet, publicFacet });
};
harden(start);
export {start};
// Test for the above code
test('anil-test', async t => {
const {
zoe,
sellItemsInstallation,
moolaIssuerKit
} = t.context;
const bundle = await bundleSource(anilContractPath);
const installation = E(zoe).install(bundle);
const { publicFacet, creatorFacet } = await E(zoe).startInstance(
installation,
harden({ Asset: moolaIssuerKit.issuer }),
);
const availableNftsBeforeSell = await E(creatorFacet).availableNfts();
t.deepEqual(availableNftsBeforeSell.value.length, 3);
const invitation = E(creatorFacet).makeSellInvitation();
const seat = E(zoe).offer(invitation, undefined, undefined, {
sellItemInstallation: sellItemsInstallation,
pricePerNFT: AmountMath.make(moolaIssuerKit.brand, 1n),
// for sell 2 nfts
nftIds: [1n, 2n],
});
const { status, sellItemsCreatorSeat } = await E(seat).getOfferResult();
const [sellItemsOfferResult, availableNftsAfterSell] = await Promise.all([
E(sellItemsCreatorSeat).getOfferResult(),
E(creatorFacet).availableNfts(),
]);
t.deepEqual(sellItemsOfferResult, defaultAcceptanceMsg);
t.deepEqual(status, 'success');
t.deepEqual(availableNftsAfterSell.value.length, 1);
const buyInvitation = await E(publicFacet).createBuyerInvitation();
const nftBrand = await E(publicFacet).getBrand();
const nftToBuy = harden([
{
id: 1n,
name: 'NFT 1',
description: 'This is the first NFT',
},
{
id: 2n,
name: 'NFT 2',
description: 'This is the second NFT',
},
]);
const proposal = harden({
give: {
// Give to 2 moola for 2 nft
// 2nft * 1moola/nft = 2moola
Money: AmountMath.make(moolaIssuerKit.brand, 2n),
},
want: {
Items: AmountMath.make(nftBrand, nftToBuy),
},
});
const paymentKeywordRecord = harden({
Money: moolaIssuerKit.mint.mintPayment(
AmountMath.make(moolaIssuerKit.brand, 2n),
),
});
const buySeat = E(zoe).offer(buyInvitation, proposal, paymentKeywordRecord);
const buyResult = await E(buySeat).getOfferResult();
t.deepEqual(buyResult, defaultAcceptanceMsg);
const sellerPayout = await E(seat).getPayout('Money');
t.deepEqual(sellerPayout, paymentKeywordRecord.Money);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment