UNPKG

@silvana-one/nft

Version:
334 lines 11.1 kB
import { __decorate, __metadata } from "tslib"; import { AccountUpdate, method, Permissions, PublicKey, State, state, UInt64, SmartContract, Bool, Field, Struct, VerificationKey, } from "o1js"; /** * The BulletinBoard contract serves as a centralized event emitter for NFT marketplace activities. * It provides a standardized way to broadcast and track various marketplace events such as: * - New collection listings * - Offers made on NFTs * - Offer cancellations * - Bids placed on NFTs * - Bid cancellations * - Completed sales * * While anyone can emit events through this contract, all events are prefixed with "BB_" to * distinguish them from events emitted directly by NFT contracts. This helps maintain clarity * in event tracking and marketplace activity monitoring. * * The BulletinBoard does not handle any NFT transfers or escrow - it purely exists as an * event broadcasting mechanism to help indexers and UIs track marketplace activity. */ export { BB_NewCollectionEvent, BB_OfferEvent, BB_CancelOfferEvent, BB_BidEvent, BB_CancelBidEvent, BB_SaleEvent, BB_UpgradeVerificationKeyEvent, BB_ChangeAdminEvent, BulletinBoard, }; class BB_NewCollectionEvent extends Struct({ /** The collection address. */ collection: PublicKey, }) { } class BB_OfferEvent extends Struct({ /** The collection address. */ collection: PublicKey, /** The NFT address. */ nft: PublicKey, /** The offer address. */ offer: PublicKey, /** The price. */ price: UInt64, }) { } class BB_CancelOfferEvent extends Struct({ /** The collection address. */ collection: PublicKey, /** The NFT address. */ nft: PublicKey, }) { } class BB_BidEvent extends Struct({ /** The collection address. */ collection: PublicKey, /** The NFT address. */ nft: PublicKey, /** The bid address. */ bid: PublicKey, /** The price. */ price: UInt64, }) { } class BB_CancelBidEvent extends Struct({ /** The collection address. */ collection: PublicKey, /** The NFT address. */ nft: PublicKey, /** The bid address. */ bid: PublicKey, }) { } class BB_SaleEvent extends Struct({ /** The collection address. */ collection: PublicKey, /** The NFT address. */ nft: PublicKey, /** The buyer address. */ buyer: PublicKey, /** The price. */ price: UInt64, }) { } class BB_UpgradeVerificationKeyEvent extends Struct({ /** The new verification key. */ vk: Field, }) { } class BB_ChangeAdminEvent extends Struct({ /** The new admin. */ admin: PublicKey, }) { } /** * The BulletinBoard contract serves as a centralized event emitter for NFT marketplace activities. * It provides a standardized way to broadcast and track various marketplace events such as: * - New collection listings * - Offers made on NFTs * - Offer cancellations * - Bids placed on NFTs * - Bid cancellations * - Completed sales * * While anyone can emit events through this contract, all events are prefixed with "BB_" to * distinguish them from events emitted directly by NFT contracts. This helps maintain clarity * in event tracking and marketplace activity monitoring. */ class BulletinBoard extends SmartContract { constructor() { super(...arguments); this.admin = State(); this.fee = State(); this.events = { newCollection: BB_NewCollectionEvent, offer: BB_OfferEvent, cancelOffer: BB_CancelOfferEvent, bid: BB_BidEvent, cancelBid: BB_CancelBidEvent, sale: BB_SaleEvent, upgradeVerificationKey: BB_UpgradeVerificationKeyEvent, changeAdmin: BB_ChangeAdminEvent, withdraw: UInt64, setFee: UInt64, }; } async deploy(args) { await super.deploy(args); this.admin.set(args.admin); this.fee.set(args.fee ?? UInt64.from(100_000_000)); this.account.permissions.set({ ...Permissions.default(), send: Permissions.proof(), setVerificationKey: Permissions.VerificationKey.proofDuringCurrentVersion(), setPermissions: Permissions.impossible(), }); } /** * Pays the fee to prevent spamming the BulletinBoard with fake events. */ async payFee() { const fee = this.fee.getAndRequireEquals(); const sender = this.sender.getUnconstrained(); const feeUpdate = AccountUpdate.createSigned(sender); feeUpdate.body.useFullCommitment = Bool(true); // Prevent memo and fee change feeUpdate.balance.subInPlace(fee); this.balance.addInPlace(fee); return feeUpdate; } /** * Emits a new collection event. * @param collection - The collection address. */ async newCollection(collection) { await this.payFee(); this.emitEvent("newCollection", new BB_NewCollectionEvent({ collection, })); } /** * Emits an offer event. * @param collection - The collection address. * @param nft - The NFT address. * @param offer - The offer address. * @param price - The price. */ async offer(collection, nft, offer, price) { await this.payFee(); this.emitEvent("offer", new BB_OfferEvent({ collection, nft, offer, price })); } /** * Emits a cancel offer event. * @param collection - The collection address. * @param nft - The NFT address. */ async cancelOffer(collection, nft) { await this.payFee(); this.emitEvent("cancelOffer", new BB_CancelOfferEvent({ collection, nft })); } /** * Emits a bid event. * @param collection - The collection address. * @param nft - The NFT address. * @param bid - The bid address. * @param price - The price. */ async bid(collection, nft, bid, price) { await this.payFee(); this.emitEvent("bid", new BB_BidEvent({ collection, nft, bid, price })); } /** * Emits a cancel bid event. * @param collection - The collection address. * @param nft - The NFT address. * @param bid - The bid address. */ async cancelBid(collection, nft, bid) { await this.payFee(); this.emitEvent("cancelBid", new BB_CancelBidEvent({ collection, nft, bid })); } /** * Emits a sale event. * @param collection - The collection address. * @param nft - The NFT address. * @param buyer - The buyer address. * @param price - The price. */ async sale(collection, nft, buyer, price) { await this.payFee(); this.emitEvent("sale", new BB_SaleEvent({ collection, nft, buyer, price })); } /** * Ensures that the transaction is authorized by the contract owner. * @returns A signed `AccountUpdate` from the admin. */ async ensureOwnerSignature() { const admin = this.admin.getAndRequireEquals(); const adminUpdate = AccountUpdate.createSigned(admin); adminUpdate.body.useFullCommitment = Bool(true); // Prevent memo and fee change return adminUpdate; } /** * Changes the contract's admin * @param admin - The new admin. */ async changeAdmin(admin) { await this.ensureOwnerSignature(); // Set the new admin this.admin.set(admin); // Emit the change admin event this.emitEvent("changeAdmin", new BB_ChangeAdminEvent({ admin })); } /** * Changes the contract's fee * @param fee - The new fee. */ async setFee(fee) { await this.ensureOwnerSignature(); // Set the new fee this.fee.set(fee); // Emit the change fee event this.emitEvent("setFee", fee); } /** * Upgrades the contract's verification key after validating with the upgrade authority. * @param vk - The new verification key to upgrade to. */ async upgradeVerificationKey(vk) { await this.ensureOwnerSignature(); // Set the new verification key this.account.verificationKey.set(vk); // Emit the upgrade event this.emitEvent("upgradeVerificationKey", new BB_UpgradeVerificationKeyEvent({ vk: vk.hash })); } /** * Withdraws the fee by admin */ async withdraw(amount) { const adminUpdate = await this.ensureOwnerSignature(); adminUpdate.balance.addInPlace(amount); this.balance.subInPlace(amount); this.emitEvent("withdraw", amount); } } __decorate([ state(PublicKey), __metadata("design:type", Object) ], BulletinBoard.prototype, "admin", void 0); __decorate([ state(UInt64), __metadata("design:type", Object) ], BulletinBoard.prototype, "fee", void 0); __decorate([ method, __metadata("design:type", Function), __metadata("design:paramtypes", [PublicKey]), __metadata("design:returntype", Promise) ], BulletinBoard.prototype, "newCollection", null); __decorate([ method, __metadata("design:type", Function), __metadata("design:paramtypes", [PublicKey, PublicKey, PublicKey, UInt64]), __metadata("design:returntype", Promise) ], BulletinBoard.prototype, "offer", null); __decorate([ method, __metadata("design:type", Function), __metadata("design:paramtypes", [PublicKey, PublicKey]), __metadata("design:returntype", Promise) ], BulletinBoard.prototype, "cancelOffer", null); __decorate([ method, __metadata("design:type", Function), __metadata("design:paramtypes", [PublicKey, PublicKey, PublicKey, UInt64]), __metadata("design:returntype", Promise) ], BulletinBoard.prototype, "bid", null); __decorate([ method, __metadata("design:type", Function), __metadata("design:paramtypes", [PublicKey, PublicKey, PublicKey]), __metadata("design:returntype", Promise) ], BulletinBoard.prototype, "cancelBid", null); __decorate([ method, __metadata("design:type", Function), __metadata("design:paramtypes", [PublicKey, PublicKey, PublicKey, UInt64]), __metadata("design:returntype", Promise) ], BulletinBoard.prototype, "sale", null); __decorate([ method, __metadata("design:type", Function), __metadata("design:paramtypes", [PublicKey]), __metadata("design:returntype", Promise) ], BulletinBoard.prototype, "changeAdmin", null); __decorate([ method, __metadata("design:type", Function), __metadata("design:paramtypes", [UInt64]), __metadata("design:returntype", Promise) ], BulletinBoard.prototype, "setFee", null); __decorate([ method, __metadata("design:type", Function), __metadata("design:paramtypes", [VerificationKey]), __metadata("design:returntype", Promise) ], BulletinBoard.prototype, "upgradeVerificationKey", null); __decorate([ method, __metadata("design:type", Function), __metadata("design:paramtypes", [UInt64]), __metadata("design:returntype", Promise) ], BulletinBoard.prototype, "withdraw", null); //# sourceMappingURL=bb.js.map