Last active
May 18, 2023 15:58
-
-
Save anilhelvaci/09be0be21b47e75e8e8a25a8b7366e4f to your computer and use it in GitHub Desktop.
Chainboard x Agoric Bootcamp: Assignment 4 Contract Rewrite
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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