UNPKG

@silvana-one/token

Version:

Silvana Fungible Token Library

156 lines 6.67 kB
import { __decorate, __metadata } from "tslib"; import { AccountUpdate, method, Permissions, PublicKey, State, state, UInt64, SmartContract, Bool, Struct, Provable, } from "o1js"; import { Whitelist } from "@silvana-one/storage"; import { FungibleToken } from "./FungibleToken.js"; class ClaimEvent extends Struct({ amount: UInt64, address: PublicKey, }) { } export class FungibleTokenClaimContract extends SmartContract { constructor() { super(...arguments); this.owner = State(); this.token = State(); this.whitelist = State(); this.maxAmount = State(); this.events = { offer: ClaimEvent, withdraw: ClaimEvent, claim: ClaimEvent, updateWhitelist: Whitelist, }; } async deploy(args) { await super.deploy(args); this.whitelist.set(args.whitelist); this.maxAmount.set(args.maxAmount ?? UInt64.MAXINT()); this.account.permissions.set({ ...Permissions.default(), send: Permissions.proof(), setVerificationKey: Permissions.VerificationKey.impossibleDuringCurrentVersion(), setPermissions: Permissions.impossible(), }); } async initialize(owner, // we are short of AccountUpdates here, so we use this parameter instead of this.sender.getUnconstrained() token, amount) { this.account.provedState.requireEquals(Bool(false)); const tokenContract = new FungibleToken(token); const tokenId = tokenContract.deriveTokenId(); tokenId.assertEquals(this.tokenId); await tokenContract.transfer(owner, this.address, amount); this.owner.set(owner); this.token.set(token); this.emitEvent("offer", { amount, address: owner }); } async offer(amount) { const owner = this.owner.getAndRequireEquals(); const token = this.token.getAndRequireEquals(); const tokenContract = new FungibleToken(token); const tokenId = tokenContract.deriveTokenId(); tokenId.assertEquals(this.tokenId); const sender = this.sender.getUnconstrained(); const senderUpdate = AccountUpdate.createSigned(sender); senderUpdate.body.useFullCommitment = Bool(true); sender.assertEquals(owner); await tokenContract.transfer(sender, this.address, amount); this.emitEvent("offer", { amount, address: sender }); } async withdraw(amount) { amount.equals(UInt64.from(0)).assertFalse(); this.account.balance.requireBetween(amount, UInt64.MAXINT()); const owner = this.owner.getAndRequireEquals(); const token = this.token.getAndRequireEquals(); const tokenContract = new FungibleToken(token); const tokenId = tokenContract.deriveTokenId(); tokenId.assertEquals(this.tokenId); const sender = this.sender.getUnconstrained(); const senderUpdate = AccountUpdate.createSigned(sender, tokenId); senderUpdate.body.useFullCommitment = Bool(true); sender.assertEquals(owner); let offerUpdate = this.send({ to: senderUpdate, amount }); offerUpdate.body.mayUseToken = AccountUpdate.MayUseToken.InheritFromParent; offerUpdate.body.useFullCommitment = Bool(true); this.emitEvent("withdraw", { amount, address: sender }); } async claim(amount) { const maxAmount = this.maxAmount.getAndRequireEquals(); const token = this.token.getAndRequireEquals(); const tokenContract = new FungibleToken(token); const tokenId = tokenContract.deriveTokenId(); tokenId.assertEquals(this.tokenId); const sender = this.sender.getUnconstrained(); const senderUpdate = AccountUpdate.createSigned(sender, tokenId); senderUpdate.body.useFullCommitment = Bool(true); const whitelist = this.whitelist.getAndRequireEquals(); const whiteListedAmount = await whitelist.getWhitelistedAmount(sender); const maxClaimAmount = Provable.if(whitelist.isSome(), whiteListedAmount.assertSome("No tokens to claim"), maxAmount); amount.assertLessThanOrEqual(maxClaimAmount); this.account.balance.requireBetween(amount, UInt64.MAXINT()); let offerUpdate = this.send({ to: senderUpdate, amount }); offerUpdate.body.mayUseToken = AccountUpdate.MayUseToken.InheritFromParent; offerUpdate.body.useFullCommitment = Bool(true); this.emitEvent("claim", { amount, address: sender, }); } async updateWhitelist(whitelist) { const owner = this.owner.getAndRequireEquals(); const sender = this.sender.getUnconstrained(); const senderUpdate = AccountUpdate.createSigned(sender); senderUpdate.body.useFullCommitment = Bool(true); sender.assertEquals(owner); this.whitelist.set(whitelist); this.emitEvent("updateWhitelist", whitelist); } } __decorate([ state(PublicKey), __metadata("design:type", Object) ], FungibleTokenClaimContract.prototype, "owner", void 0); __decorate([ state(PublicKey), __metadata("design:type", Object) ], FungibleTokenClaimContract.prototype, "token", void 0); __decorate([ state(Whitelist), __metadata("design:type", Object) ], FungibleTokenClaimContract.prototype, "whitelist", void 0); __decorate([ state(UInt64), __metadata("design:type", Object) ], FungibleTokenClaimContract.prototype, "maxAmount", void 0); __decorate([ method, __metadata("design:type", Function), __metadata("design:paramtypes", [PublicKey, PublicKey, UInt64]), __metadata("design:returntype", Promise) ], FungibleTokenClaimContract.prototype, "initialize", null); __decorate([ method, __metadata("design:type", Function), __metadata("design:paramtypes", [UInt64]), __metadata("design:returntype", Promise) ], FungibleTokenClaimContract.prototype, "offer", null); __decorate([ method, __metadata("design:type", Function), __metadata("design:paramtypes", [UInt64]), __metadata("design:returntype", Promise) ], FungibleTokenClaimContract.prototype, "withdraw", null); __decorate([ method, __metadata("design:type", Function), __metadata("design:paramtypes", [UInt64]), __metadata("design:returntype", Promise) ], FungibleTokenClaimContract.prototype, "claim", null); __decorate([ method, __metadata("design:type", Function), __metadata("design:paramtypes", [Whitelist]), __metadata("design:returntype", Promise) ], FungibleTokenClaimContract.prototype, "updateWhitelist", null); //# sourceMappingURL=claim.js.map