@silvana-one/nft
Version:
Mina NFT library
132 lines • 6.07 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { AccountUpdate, method, Permissions, PublicKey, State, state, UInt64, SmartContract, Bool, Field, } from "o1js";
import { UInt64Option, NFTTransactionContext, TransferExtendedParams, TransferEvent, } from "../interfaces/index.js";
/**
* Creates a new NFT Collection Contract class.
*
* @param params - Constructor parameters including admin and upgrade contracts, and network ID.
* @returns The Collection class extending TokenContract and implementing required interfaces.
*/
export function OfferFactory(params) {
const { collectionContract } = params;
class NonFungibleTokenOfferContract extends SmartContract {
constructor() {
super(...arguments);
this.owner = State();
// @state(Whitelist) whitelist = State<Whitelist>();
this.price = State();
this.collection = State();
this.nft = State();
this.insideBuy = State();
this.events = {
buy: TransferEvent,
};
}
async deploy(args) {
await super.deploy(args);
this.owner.set(args.owner);
// this.whitelist.set(args.whitelist);
this.price.set(args.price);
this.collection.set(args.collection);
this.nft.set(args.nft);
this.insideBuy.set(Bool(false));
this.account.permissions.set({
...Permissions.default(),
send: Permissions.proof(),
setVerificationKey: Permissions.VerificationKey.impossibleDuringCurrentVersion(),
setPermissions: Permissions.impossible(),
});
}
getCollectionContract(address) {
const CollectionContract = collectionContract();
return new CollectionContract(address);
}
async buy(buyer) {
const insideBuy = this.insideBuy.getAndRequireEquals();
insideBuy.assertFalse("Already inside buy method");
this.insideBuy.set(Bool(true));
const collectionAddress = this.collection.getAndRequireEquals();
const nftAddress = this.nft.getAndRequireEquals();
const price = this.price.getAndRequireEquals();
const collection = this.getCollectionContract(collectionAddress);
await collection.transferByProof({
address: nftAddress,
from: this.address,
to: buyer,
price: UInt64Option.fromValue(price),
context: new NFTTransactionContext({
custom: [Field(0), Field(0), Field(0)],
}),
});
}
// @method async sellWithApproval(nftAddress: NFTAddress, price: UInt64) {
// await this._sell(nftAddress, price);
// const buyer = this.buyer.getAndRequireEquals();
// const collection = new Collection(nftAddress.collection);
// await collection.sellWithApproval(nftAddress.nft, price, buyer);
// }
async canTransfer(params) {
this.insideBuy.requireEquals(Bool(true));
// We do not set the insideBuy to false here as buy() can be called once only
// and then the offer is accepted and not valid anymore for other buyers
const collectionAddress = this.collection.getAndRequireEquals();
const nftAddress = this.nft.getAndRequireEquals();
const owner = this.owner.getAndRequireEquals();
const price = this.price.getAndRequireEquals();
const sender = this.sender.getUnconstrained();
params.collection.assertEquals(collectionAddress);
params.nft.assertEquals(nftAddress);
params.from.assertEquals(owner);
params.approved.assertEquals(this.address);
params.price.assertSome().assertEquals(price);
params.to.assertEquals(sender);
params.fee.orElse(UInt64.zero).assertLessThan(price, "Fee is too high");
const payment = price.sub(params.fee.orElse(UInt64.zero));
const senderUpdate = AccountUpdate.createSigned(sender);
senderUpdate.account.balance.requireBetween(payment, UInt64.MAXINT());
senderUpdate.balance.subInPlace(payment);
const ownerUpdate = AccountUpdate.create(owner);
ownerUpdate.balance.addInPlace(payment);
senderUpdate.body.useFullCommitment = Bool(true);
ownerUpdate.body.useFullCommitment = Bool(true);
this.emitEvent("buy", new TransferEvent({
...params,
}));
return Bool(true);
}
}
__decorate([
state(PublicKey),
__metadata("design:type", Object)
], NonFungibleTokenOfferContract.prototype, "owner", void 0);
__decorate([
state(UInt64),
__metadata("design:type", Object)
], NonFungibleTokenOfferContract.prototype, "price", void 0);
__decorate([
state(PublicKey),
__metadata("design:type", Object)
], NonFungibleTokenOfferContract.prototype, "collection", void 0);
__decorate([
state(PublicKey),
__metadata("design:type", Object)
], NonFungibleTokenOfferContract.prototype, "nft", void 0);
__decorate([
state(Bool),
__metadata("design:type", Object)
], NonFungibleTokenOfferContract.prototype, "insideBuy", void 0);
__decorate([
method,
__metadata("design:type", Function),
__metadata("design:paramtypes", [PublicKey]),
__metadata("design:returntype", Promise)
], NonFungibleTokenOfferContract.prototype, "buy", null);
__decorate([
method.returns(Bool),
__metadata("design:type", Function),
__metadata("design:paramtypes", [TransferExtendedParams]),
__metadata("design:returntype", Promise)
], NonFungibleTokenOfferContract.prototype, "canTransfer", null);
return NonFungibleTokenOfferContract;
}
//# sourceMappingURL=offer.js.map