@silvana-one/token
Version:
Silvana Fungible Token Library
1,082 lines (1,072 loc) • 76.6 kB
JavaScript
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// dist/node/index.js
var index_exports = {};
__export(index_exports, {
AdvancedAdminData: () => AdvancedAdminData,
AdvancedFungibleToken: () => AdvancedFungibleToken,
BalanceChangeEvent: () => BalanceChangeEvent,
BidEvent: () => BidEvent,
BondingCurveAdminInitializeProps: () => BondingCurveAdminInitializeProps,
BondingCurveFungibleToken: () => BondingCurveFungibleToken,
BondingCurveParams: () => BondingCurveParams,
BondingMintEvent: () => BondingMintEvent,
BondingRedeemEvent: () => BondingRedeemEvent,
BurnEvent: () => BurnEvent,
FungibleToken: () => FungibleToken,
FungibleTokenAdmin: () => FungibleTokenAdmin,
FungibleTokenAdvancedAdmin: () => FungibleTokenAdvancedAdmin,
FungibleTokenBidContract: () => FungibleTokenBidContract,
FungibleTokenBondingCurveAdmin: () => FungibleTokenBondingCurveAdmin,
FungibleTokenClaimContract: () => FungibleTokenClaimContract,
FungibleTokenContract: () => FungibleTokenContract,
FungibleTokenErrors: () => FungibleTokenErrors,
FungibleTokenOfferContract: () => FungibleTokenOfferContract,
MintEvent: () => MintEvent,
OfferEvent: () => OfferEvent,
PauseEvent: () => PauseEvent,
SetAdminEvent: () => SetAdminEvent
});
module.exports = __toCommonJS(index_exports);
// dist/node/bid.js
var import_tslib4 = require("tslib");
var import_o1js5 = require("o1js");
var import_storage2 = require("@silvana-one/storage");
// dist/node/FungibleTokenContract.js
var import_tslib = require("tslib");
var import_o1js = require("o1js");
var FungibleTokenErrors = {
noAdminKey: "could not fetch admin contract key",
noPermissionToChangeAdmin: "Not allowed to change admin contract",
tokenPaused: "Token is currently paused",
noPermissionToMint: "Not allowed to mint tokens",
noPermissionToPause: "Not allowed to pause token",
noPermissionToResume: "Not allowed to resume token",
noTransferFromCirculation: "Can't transfer to/from the circulation account",
noPermissionChangeAllowed: "Can't change permissions for access or receive on token accounts",
flashMinting: "Flash-minting or unbalanced transaction detected. Please make sure that your transaction is balanced, and that your `AccountUpdate`s are ordered properly, so that tokens are not received before they are sent.",
unbalancedTransaction: "Transaction is unbalanced"
};
function FungibleTokenContract(adminContract) {
class FungibleToken2 extends import_o1js.TokenContract {
constructor() {
super(...arguments);
this.decimals = (0, import_o1js.State)();
this.admin = (0, import_o1js.State)();
this.paused = (0, import_o1js.State)();
this.events = {
SetAdmin: SetAdminEvent,
Pause: PauseEvent,
Mint: MintEvent,
Burn: BurnEvent,
BalanceChange: BalanceChangeEvent
};
}
async deploy(props) {
await super.deploy(props);
this.paused.set((0, import_o1js.Bool)(true));
this.account.zkappUri.set(props.src);
this.account.tokenSymbol.set(props.symbol);
this.account.permissions.set({
...import_o1js.Permissions.default(),
setVerificationKey: props.allowUpdates ? import_o1js.Permissions.VerificationKey.proofDuringCurrentVersion() : import_o1js.Permissions.VerificationKey.impossibleDuringCurrentVersion(),
setPermissions: import_o1js.Permissions.impossible(),
access: import_o1js.Permissions.proof()
});
}
/** Update the verification key.
* This will only work when `allowUpdates` has been set to `true` during deployment.
*/
async updateVerificationKey(vk) {
const adminContract2 = await this.getAdminContract();
const canChangeVerificationKey = await adminContract2.canChangeVerificationKey(vk);
canChangeVerificationKey.assertTrue(FungibleTokenErrors.noPermissionToChangeAdmin);
this.account.verificationKey.set(vk);
}
/** Initializes the account for tracking total circulation.
* @argument {PublicKey} admin - public key where the admin contract is deployed
* @argument {UInt8} decimals - number of decimals for the token
* @argument {Bool} startPaused - if set to `Bool(true), the contract will start in a mode where token minting and transfers are paused. This should be used for non-atomic deployments
*/
async initialize(admin, decimals, startPaused) {
this.account.provedState.requireEquals((0, import_o1js.Bool)(false));
this.admin.set(admin);
this.decimals.set(decimals);
this.paused.set((0, import_o1js.Bool)(false));
this.paused.set(startPaused);
const accountUpdate = import_o1js.AccountUpdate.createSigned(this.address, this.deriveTokenId());
let permissions = import_o1js.Permissions.default();
permissions.send = import_o1js.Permissions.none();
permissions.setPermissions = import_o1js.Permissions.impossible();
accountUpdate.account.permissions.set(permissions);
}
async getAdminContract() {
const admin = await import_o1js.Provable.witnessAsync(import_o1js.PublicKey, async () => {
let pk = await this.admin.fetch();
(0, import_o1js.assert)(pk !== void 0, FungibleTokenErrors.noAdminKey);
return pk;
});
this.admin.requireEquals(admin);
return new adminContract(admin);
}
async setAdmin(admin) {
const adminContract2 = await this.getAdminContract();
const canChangeAdmin = await adminContract2.canChangeAdmin(admin);
canChangeAdmin.assertTrue(FungibleTokenErrors.noPermissionToChangeAdmin);
this.admin.set(admin);
this.emitEvent("SetAdmin", new SetAdminEvent({ adminKey: admin }));
}
async mint(recipient, amount) {
this.paused.getAndRequireEquals().assertFalse(FungibleTokenErrors.tokenPaused);
const accountUpdate = this.internal.mint({ address: recipient, amount });
const adminContract2 = await this.getAdminContract();
const canMint = await adminContract2.canMint(accountUpdate);
canMint.assertTrue(FungibleTokenErrors.noPermissionToMint);
recipient.equals(this.address).assertFalse(FungibleTokenErrors.noTransferFromCirculation);
this.approve(accountUpdate);
this.emitEvent("Mint", new MintEvent({ recipient, amount }));
const circulationUpdate = import_o1js.AccountUpdate.create(this.address, this.deriveTokenId());
circulationUpdate.balanceChange = import_o1js.Int64.fromUnsigned(amount);
return accountUpdate;
}
async burn(from, amount) {
this.paused.getAndRequireEquals().assertFalse(FungibleTokenErrors.tokenPaused);
const accountUpdate = this.internal.burn({ address: from, amount });
const circulationUpdate = import_o1js.AccountUpdate.create(this.address, this.deriveTokenId());
from.equals(this.address).assertFalse(FungibleTokenErrors.noTransferFromCirculation);
circulationUpdate.balanceChange = import_o1js.Int64.fromUnsigned(amount).neg();
this.emitEvent("Burn", new BurnEvent({ from, amount }));
return accountUpdate;
}
async pause() {
const adminContract2 = await this.getAdminContract();
const canPause = await adminContract2.canPause();
canPause.assertTrue(FungibleTokenErrors.noPermissionToPause);
this.paused.set((0, import_o1js.Bool)(true));
this.emitEvent("Pause", new PauseEvent({ isPaused: (0, import_o1js.Bool)(true) }));
}
async resume() {
const adminContract2 = await this.getAdminContract();
const canResume = await adminContract2.canResume();
canResume.assertTrue(FungibleTokenErrors.noPermissionToResume);
this.paused.set((0, import_o1js.Bool)(false));
this.emitEvent("Pause", new PauseEvent({ isPaused: (0, import_o1js.Bool)(false) }));
}
async transfer(from, to, amount) {
this.paused.getAndRequireEquals().assertFalse(FungibleTokenErrors.tokenPaused);
from.equals(this.address).assertFalse(FungibleTokenErrors.noTransferFromCirculation);
to.equals(this.address).assertFalse(FungibleTokenErrors.noTransferFromCirculation);
this.internal.send({ from, to, amount });
}
checkPermissionsUpdate(update) {
let permissions = update.update.permissions;
let { access, receive } = permissions.value;
let accessIsNone = import_o1js.Provable.equal(import_o1js.Types.AuthRequired, access, import_o1js.Permissions.none());
let receiveIsNone = import_o1js.Provable.equal(import_o1js.Types.AuthRequired, receive, import_o1js.Permissions.none());
let updateAllowed = accessIsNone.and(receiveIsNone);
(0, import_o1js.assert)(updateAllowed.or(permissions.isSome.not()), FungibleTokenErrors.noPermissionChangeAllowed);
}
/** Approve `AccountUpdate`s that have been created outside of the token contract.
*
* @argument {AccountUpdateForest} updates - The `AccountUpdate`s to approve. Note that the forest size is limited by the base token contract, @see TokenContract.MAX_ACCOUNT_UPDATES The current limit is 9.
*/
async approveBase(updates) {
this.paused.getAndRequireEquals().assertFalse(FungibleTokenErrors.tokenPaused);
let totalBalance = import_o1js.Int64.from(0);
this.forEachUpdate(updates, (update, usesToken) => {
this.checkPermissionsUpdate(update);
this.emitEventIf(usesToken, "BalanceChange", new BalanceChangeEvent({
address: update.publicKey,
amount: update.balanceChange
}));
update.publicKey.equals(this.address).and(usesToken).assertFalse(FungibleTokenErrors.noTransferFromCirculation);
totalBalance = import_o1js.Provable.if(usesToken, totalBalance.add(update.balanceChange), totalBalance);
totalBalance.isPositive().assertFalse(FungibleTokenErrors.flashMinting);
});
totalBalance.assertEquals(import_o1js.Int64.zero, FungibleTokenErrors.unbalancedTransaction);
}
async getBalanceOf(address) {
const account = import_o1js.AccountUpdate.create(address, this.deriveTokenId()).account;
const balance = account.balance.get();
account.balance.requireEquals(balance);
return balance;
}
/** Reports the current circulating supply
* This does take into account currently unreduced actions.
*/
async getCirculating() {
let circulating = await this.getBalanceOf(this.address);
return circulating;
}
async getDecimals() {
return this.decimals.getAndRequireEquals();
}
}
(0, import_tslib.__decorate)([
(0, import_o1js.state)(import_o1js.UInt8),
(0, import_tslib.__metadata)("design:type", Object)
], FungibleToken2.prototype, "decimals", void 0);
(0, import_tslib.__decorate)([
(0, import_o1js.state)(import_o1js.PublicKey),
(0, import_tslib.__metadata)("design:type", Object)
], FungibleToken2.prototype, "admin", void 0);
(0, import_tslib.__decorate)([
(0, import_o1js.state)(import_o1js.Bool),
(0, import_tslib.__metadata)("design:type", Object)
], FungibleToken2.prototype, "paused", void 0);
(0, import_tslib.__decorate)([
import_o1js.method,
(0, import_tslib.__metadata)("design:type", Function),
(0, import_tslib.__metadata)("design:paramtypes", [import_o1js.VerificationKey]),
(0, import_tslib.__metadata)("design:returntype", Promise)
], FungibleToken2.prototype, "updateVerificationKey", null);
(0, import_tslib.__decorate)([
import_o1js.method,
(0, import_tslib.__metadata)("design:type", Function),
(0, import_tslib.__metadata)("design:paramtypes", [import_o1js.PublicKey, import_o1js.UInt8, import_o1js.Bool]),
(0, import_tslib.__metadata)("design:returntype", Promise)
], FungibleToken2.prototype, "initialize", null);
(0, import_tslib.__decorate)([
import_o1js.method,
(0, import_tslib.__metadata)("design:type", Function),
(0, import_tslib.__metadata)("design:paramtypes", [import_o1js.PublicKey]),
(0, import_tslib.__metadata)("design:returntype", Promise)
], FungibleToken2.prototype, "setAdmin", null);
(0, import_tslib.__decorate)([
import_o1js.method.returns(import_o1js.AccountUpdate),
(0, import_tslib.__metadata)("design:type", Function),
(0, import_tslib.__metadata)("design:paramtypes", [import_o1js.PublicKey, import_o1js.UInt64]),
(0, import_tslib.__metadata)("design:returntype", Promise)
], FungibleToken2.prototype, "mint", null);
(0, import_tslib.__decorate)([
import_o1js.method.returns(import_o1js.AccountUpdate),
(0, import_tslib.__metadata)("design:type", Function),
(0, import_tslib.__metadata)("design:paramtypes", [import_o1js.PublicKey, import_o1js.UInt64]),
(0, import_tslib.__metadata)("design:returntype", Promise)
], FungibleToken2.prototype, "burn", null);
(0, import_tslib.__decorate)([
import_o1js.method,
(0, import_tslib.__metadata)("design:type", Function),
(0, import_tslib.__metadata)("design:paramtypes", []),
(0, import_tslib.__metadata)("design:returntype", Promise)
], FungibleToken2.prototype, "pause", null);
(0, import_tslib.__decorate)([
import_o1js.method,
(0, import_tslib.__metadata)("design:type", Function),
(0, import_tslib.__metadata)("design:paramtypes", []),
(0, import_tslib.__metadata)("design:returntype", Promise)
], FungibleToken2.prototype, "resume", null);
(0, import_tslib.__decorate)([
import_o1js.method,
(0, import_tslib.__metadata)("design:type", Function),
(0, import_tslib.__metadata)("design:paramtypes", [import_o1js.PublicKey, import_o1js.PublicKey, import_o1js.UInt64]),
(0, import_tslib.__metadata)("design:returntype", Promise)
], FungibleToken2.prototype, "transfer", null);
(0, import_tslib.__decorate)([
import_o1js.method,
(0, import_tslib.__metadata)("design:type", Function),
(0, import_tslib.__metadata)("design:paramtypes", [import_o1js.AccountUpdateForest]),
(0, import_tslib.__metadata)("design:returntype", Promise)
], FungibleToken2.prototype, "approveBase", null);
(0, import_tslib.__decorate)([
import_o1js.method.returns(import_o1js.UInt64),
(0, import_tslib.__metadata)("design:type", Function),
(0, import_tslib.__metadata)("design:paramtypes", [import_o1js.PublicKey]),
(0, import_tslib.__metadata)("design:returntype", Promise)
], FungibleToken2.prototype, "getBalanceOf", null);
(0, import_tslib.__decorate)([
import_o1js.method.returns(import_o1js.UInt8),
(0, import_tslib.__metadata)("design:type", Function),
(0, import_tslib.__metadata)("design:paramtypes", []),
(0, import_tslib.__metadata)("design:returntype", Promise)
], FungibleToken2.prototype, "getDecimals", null);
return FungibleToken2;
}
var SetAdminEvent = class extends (0, import_o1js.Struct)({
adminKey: import_o1js.PublicKey
}) {
};
var PauseEvent = class extends (0, import_o1js.Struct)({
isPaused: import_o1js.Bool
}) {
};
var MintEvent = class extends (0, import_o1js.Struct)({
recipient: import_o1js.PublicKey,
amount: import_o1js.UInt64
}) {
};
var BurnEvent = class extends (0, import_o1js.Struct)({
from: import_o1js.PublicKey,
amount: import_o1js.UInt64
}) {
};
var BalanceChangeEvent = class extends (0, import_o1js.Struct)({
address: import_o1js.PublicKey,
amount: import_o1js.Int64
}) {
};
// dist/node/FungibleTokenStandardAdmin.js
var import_tslib2 = require("tslib");
var import_o1js2 = require("o1js");
var FungibleTokenAdmin = class extends import_o1js2.SmartContract {
constructor() {
super(...arguments);
this.adminPublicKey = (0, import_o1js2.State)();
}
async deploy(props) {
await super.deploy(props);
this.adminPublicKey.set(props.adminPublicKey);
this.account.permissions.set({
...import_o1js2.Permissions.default(),
setVerificationKey: import_o1js2.Permissions.VerificationKey.impossibleDuringCurrentVersion(),
setPermissions: import_o1js2.Permissions.impossible()
});
}
/** Update the verification key.
* Note that because we have set the permissions for setting the verification key to `impossibleDuringCurrentVersion()`, this will only be possible in case of a protocol update that requires an update.
*/
async updateVerificationKey(vk) {
this.account.verificationKey.set(vk);
}
async ensureAdminSignature() {
const admin = await import_o1js2.Provable.witnessAsync(import_o1js2.PublicKey, async () => {
let pk = await this.adminPublicKey.fetch();
(0, import_o1js2.assert)(pk !== void 0, "could not fetch admin public key");
return pk;
});
this.adminPublicKey.requireEquals(admin);
return import_o1js2.AccountUpdate.createSigned(admin);
}
async canMint(_accountUpdate) {
await this.ensureAdminSignature();
return (0, import_o1js2.Bool)(true);
}
async canChangeAdmin(_admin) {
await this.ensureAdminSignature();
return (0, import_o1js2.Bool)(true);
}
async canPause() {
await this.ensureAdminSignature();
return (0, import_o1js2.Bool)(true);
}
async canResume() {
await this.ensureAdminSignature();
return (0, import_o1js2.Bool)(true);
}
async canChangeVerificationKey(_vk) {
await this.ensureAdminSignature();
return (0, import_o1js2.Bool)(true);
}
};
(0, import_tslib2.__decorate)([
(0, import_o1js2.state)(import_o1js2.PublicKey),
(0, import_tslib2.__metadata)("design:type", Object)
], FungibleTokenAdmin.prototype, "adminPublicKey", void 0);
(0, import_tslib2.__decorate)([
import_o1js2.method,
(0, import_tslib2.__metadata)("design:type", Function),
(0, import_tslib2.__metadata)("design:paramtypes", [import_o1js2.VerificationKey]),
(0, import_tslib2.__metadata)("design:returntype", Promise)
], FungibleTokenAdmin.prototype, "updateVerificationKey", null);
(0, import_tslib2.__decorate)([
import_o1js2.method.returns(import_o1js2.Bool),
(0, import_tslib2.__metadata)("design:type", Function),
(0, import_tslib2.__metadata)("design:paramtypes", [import_o1js2.AccountUpdate]),
(0, import_tslib2.__metadata)("design:returntype", Promise)
], FungibleTokenAdmin.prototype, "canMint", null);
(0, import_tslib2.__decorate)([
import_o1js2.method.returns(import_o1js2.Bool),
(0, import_tslib2.__metadata)("design:type", Function),
(0, import_tslib2.__metadata)("design:paramtypes", [import_o1js2.PublicKey]),
(0, import_tslib2.__metadata)("design:returntype", Promise)
], FungibleTokenAdmin.prototype, "canChangeAdmin", null);
(0, import_tslib2.__decorate)([
import_o1js2.method.returns(import_o1js2.Bool),
(0, import_tslib2.__metadata)("design:type", Function),
(0, import_tslib2.__metadata)("design:paramtypes", []),
(0, import_tslib2.__metadata)("design:returntype", Promise)
], FungibleTokenAdmin.prototype, "canPause", null);
(0, import_tslib2.__decorate)([
import_o1js2.method.returns(import_o1js2.Bool),
(0, import_tslib2.__metadata)("design:type", Function),
(0, import_tslib2.__metadata)("design:paramtypes", []),
(0, import_tslib2.__metadata)("design:returntype", Promise)
], FungibleTokenAdmin.prototype, "canResume", null);
(0, import_tslib2.__decorate)([
import_o1js2.method.returns(import_o1js2.Bool),
(0, import_tslib2.__metadata)("design:type", Function),
(0, import_tslib2.__metadata)("design:paramtypes", [import_o1js2.VerificationKey]),
(0, import_tslib2.__metadata)("design:returntype", Promise)
], FungibleTokenAdmin.prototype, "canChangeVerificationKey", null);
// dist/node/FungibleTokenAdvancedAdmin.js
var import_tslib3 = require("tslib");
var import_o1js3 = require("o1js");
var import_storage = require("@silvana-one/storage");
var AdvancedAdminData = class _AdvancedAdminData extends (0, import_o1js3.Struct)({
totalSupply: import_o1js3.UInt64,
requireAdminSignatureForMint: import_o1js3.Bool,
anyoneCanMint: import_o1js3.Bool
}) {
static new(params = {}) {
const { totalSupply, requireAdminSignatureForMint, anyoneCanMint } = params;
return new _AdvancedAdminData({
totalSupply: import_o1js3.UInt64.from(totalSupply ?? 0),
requireAdminSignatureForMint: (0, import_o1js3.Bool)(requireAdminSignatureForMint ?? false),
anyoneCanMint: (0, import_o1js3.Bool)(anyoneCanMint ?? false)
});
}
pack() {
const totalSupplyBits = this.totalSupply.value.toBits(64);
return import_o1js3.Field.fromBits([
...totalSupplyBits,
this.requireAdminSignatureForMint,
this.anyoneCanMint
]);
}
static unpack(packed) {
const bits = packed.toBits(64 + 1 + 1);
const totalSupply = import_o1js3.UInt64.Unsafe.fromField(import_o1js3.Field.fromBits(bits.slice(0, 64)));
const requireAdminSignatureForMint = bits[64];
const anyoneCanMint = bits[64 + 1];
return new _AdvancedAdminData({
totalSupply,
requireAdminSignatureForMint,
anyoneCanMint
});
}
};
var FungibleTokenAdvancedAdmin = class extends import_o1js3.TokenContract {
constructor() {
super(...arguments);
this.adminPublicKey = (0, import_o1js3.State)();
this.tokenContract = (0, import_o1js3.State)();
this.whitelist = (0, import_o1js3.State)();
this.adminData = (0, import_o1js3.State)();
this.events = { updateWhitelist: import_storage.Whitelist };
}
/**
* Overrides the approveBase method to prevent transfers of tokens.
*
* @param forest - The account update forest.
*/
async approveBase(forest) {
throw Error("Transfer not allowed");
}
async deploy(props) {
await super.deploy(props);
this.adminPublicKey.set(props.adminPublicKey);
this.tokenContract.set(props.tokenContract);
this.adminData.set(new AdvancedAdminData({
totalSupply: props.totalSupply,
requireAdminSignatureForMint: props.requireAdminSignatureForMint,
anyoneCanMint: props.anyoneCanMint
}).pack());
this.whitelist.set(props.whitelist);
this.account.permissions.set({
...import_o1js3.Permissions.default(),
setVerificationKey: import_o1js3.Permissions.VerificationKey.proofDuringCurrentVersion(),
setPermissions: import_o1js3.Permissions.impossible()
});
}
/** Update the verification key.
* Note that because we have set the permissions for setting
* the verification key to `impossibleDuringCurrentVersion()`,
* this will only be possible in case of a protocol update that requires an update.
*/
async updateVerificationKey(vk) {
await this.ensureAdminSignature();
this.account.verificationKey.set(vk);
}
async ensureAdminSignature() {
const admin = this.adminPublicKey.getAndRequireEquals();
const adminUpdate = import_o1js3.AccountUpdate.createSigned(admin);
adminUpdate.body.useFullCommitment = (0, import_o1js3.Bool)(true);
return adminUpdate;
}
async canMint(_accountUpdate) {
const address = _accountUpdate.body.publicKey;
const balanceChange = _accountUpdate.body.balanceChange;
balanceChange.isPositive().assertTrue();
const amount = balanceChange.magnitude;
const adminData = AdvancedAdminData.unpack(this.adminData.getAndRequireEquals());
amount.assertLessThanOrEqual(adminData.totalSupply);
const tokenContract = this.tokenContract.getAndRequireEquals();
const tokenId = import_o1js3.TokenId.derive(tokenContract);
const adminTokenId = this.deriveTokenId();
_accountUpdate.body.tokenId.assertEquals(tokenId);
const maxAdditionalSupply = adminData.totalSupply.sub(amount);
const tokenUpdate = import_o1js3.AccountUpdate.createIf(adminData.totalSupply.equals(import_o1js3.UInt64.MAXINT()).not(), this.address, adminTokenId);
tokenUpdate.account.balance.requireBetween(import_o1js3.UInt64.zero, maxAdditionalSupply);
tokenUpdate.balance.addInPlace(amount);
this.self.approve(tokenUpdate);
const whitelist = this.whitelist.getAndRequireEquals();
const whitelistedAmount = await whitelist.getWhitelistedAmount(address);
whitelistedAmount.isSome.or(adminData.anyoneCanMint).assertTrue("Cannot mint to non-whitelisted address");
const maxMintAmount = import_o1js3.Provable.if(
adminData.anyoneCanMint,
import_o1js3.Provable.if(whitelistedAmount.isSome, whitelistedAmount.value, import_o1js3.UInt64.MAXINT()),
// blacklist
whitelistedAmount.value
);
amount.assertLessThanOrEqual(maxMintAmount);
const trackMintUpdate = import_o1js3.AccountUpdate.createIf(
whitelist.isSome(),
// we do not track minting if the whitelist is empty
address,
adminTokenId
);
trackMintUpdate.account.balance.requireBetween(import_o1js3.UInt64.zero, maxMintAmount.sub(amount));
trackMintUpdate.balance.addInPlace(amount);
this.self.approve(trackMintUpdate);
const adminSignatureUpdate = import_o1js3.AccountUpdate.createIf(adminData.requireAdminSignatureForMint, this.adminPublicKey.getAndRequireEquals());
adminSignatureUpdate.requireSignature();
adminSignatureUpdate.body.useFullCommitment = (0, import_o1js3.Bool)(true);
return (0, import_o1js3.Bool)(true);
}
async canChangeAdmin(_admin) {
await this.ensureAdminSignature();
return (0, import_o1js3.Bool)(true);
}
async canPause() {
await this.ensureAdminSignature();
return (0, import_o1js3.Bool)(true);
}
async canResume() {
await this.ensureAdminSignature();
return (0, import_o1js3.Bool)(true);
}
async updateWhitelist(whitelist) {
const admin = this.adminPublicKey.getAndRequireEquals();
const sender = this.sender.getUnconstrained();
const senderUpdate = import_o1js3.AccountUpdate.createSigned(sender);
senderUpdate.body.useFullCommitment = (0, import_o1js3.Bool)(true);
admin.assertEquals(sender);
this.whitelist.set(whitelist);
this.emitEvent("updateWhitelist", whitelist);
}
async canChangeVerificationKey(_vk) {
await this.ensureAdminSignature();
return (0, import_o1js3.Bool)(true);
}
};
(0, import_tslib3.__decorate)([
(0, import_o1js3.state)(import_o1js3.PublicKey),
(0, import_tslib3.__metadata)("design:type", Object)
], FungibleTokenAdvancedAdmin.prototype, "adminPublicKey", void 0);
(0, import_tslib3.__decorate)([
(0, import_o1js3.state)(import_o1js3.PublicKey),
(0, import_tslib3.__metadata)("design:type", Object)
], FungibleTokenAdvancedAdmin.prototype, "tokenContract", void 0);
(0, import_tslib3.__decorate)([
(0, import_o1js3.state)(import_storage.Whitelist),
(0, import_tslib3.__metadata)("design:type", Object)
], FungibleTokenAdvancedAdmin.prototype, "whitelist", void 0);
(0, import_tslib3.__decorate)([
(0, import_o1js3.state)(import_o1js3.Field),
(0, import_tslib3.__metadata)("design:type", Object)
], FungibleTokenAdvancedAdmin.prototype, "adminData", void 0);
(0, import_tslib3.__decorate)([
import_o1js3.method,
(0, import_tslib3.__metadata)("design:type", Function),
(0, import_tslib3.__metadata)("design:paramtypes", [import_o1js3.VerificationKey]),
(0, import_tslib3.__metadata)("design:returntype", Promise)
], FungibleTokenAdvancedAdmin.prototype, "updateVerificationKey", null);
(0, import_tslib3.__decorate)([
import_o1js3.method.returns(import_o1js3.Bool),
(0, import_tslib3.__metadata)("design:type", Function),
(0, import_tslib3.__metadata)("design:paramtypes", [import_o1js3.AccountUpdate]),
(0, import_tslib3.__metadata)("design:returntype", Promise)
], FungibleTokenAdvancedAdmin.prototype, "canMint", null);
(0, import_tslib3.__decorate)([
import_o1js3.method.returns(import_o1js3.Bool),
(0, import_tslib3.__metadata)("design:type", Function),
(0, import_tslib3.__metadata)("design:paramtypes", [import_o1js3.PublicKey]),
(0, import_tslib3.__metadata)("design:returntype", Promise)
], FungibleTokenAdvancedAdmin.prototype, "canChangeAdmin", null);
(0, import_tslib3.__decorate)([
import_o1js3.method.returns(import_o1js3.Bool),
(0, import_tslib3.__metadata)("design:type", Function),
(0, import_tslib3.__metadata)("design:paramtypes", []),
(0, import_tslib3.__metadata)("design:returntype", Promise)
], FungibleTokenAdvancedAdmin.prototype, "canPause", null);
(0, import_tslib3.__decorate)([
import_o1js3.method.returns(import_o1js3.Bool),
(0, import_tslib3.__metadata)("design:type", Function),
(0, import_tslib3.__metadata)("design:paramtypes", []),
(0, import_tslib3.__metadata)("design:returntype", Promise)
], FungibleTokenAdvancedAdmin.prototype, "canResume", null);
(0, import_tslib3.__decorate)([
import_o1js3.method,
(0, import_tslib3.__metadata)("design:type", Function),
(0, import_tslib3.__metadata)("design:paramtypes", [import_storage.Whitelist]),
(0, import_tslib3.__metadata)("design:returntype", Promise)
], FungibleTokenAdvancedAdmin.prototype, "updateWhitelist", null);
(0, import_tslib3.__decorate)([
import_o1js3.method.returns(import_o1js3.Bool),
(0, import_tslib3.__metadata)("design:type", Function),
(0, import_tslib3.__metadata)("design:paramtypes", [import_o1js3.VerificationKey]),
(0, import_tslib3.__metadata)("design:returntype", Promise)
], FungibleTokenAdvancedAdmin.prototype, "canChangeVerificationKey", null);
// dist/node/FungibleToken.js
var FungibleToken = FungibleTokenContract(FungibleTokenAdmin);
var AdvancedFungibleToken = FungibleTokenContract(FungibleTokenAdvancedAdmin);
// dist/node/div.js
var import_o1js4 = require("o1js");
var MulDivResult = class extends (0, import_o1js4.Struct)({
result: import_o1js4.UInt64,
remainder: import_o1js4.UInt64
}) {
};
var MulDivResultInternal = class extends (0, import_o1js4.Struct)({
result: import_o1js4.Field,
remainder: import_o1js4.Field
}) {
};
function mulDiv(params) {
const { value, multiplier, denominator } = params;
denominator.equals(import_o1js4.UInt64.zero).assertFalse("division by zero");
const fields = import_o1js4.Provable.witness(MulDivResultInternal, () => {
const valueBigInt = value.toBigInt();
const multiplierBigInt = multiplier.toBigInt();
const denominatorBigInt = denominator.toBigInt();
if (denominatorBigInt === 0n) {
return { result: import_o1js4.Field.from(0n), remainder: import_o1js4.Field.from(0n) };
}
const result = valueBigInt * multiplierBigInt / denominatorBigInt;
const remainder = valueBigInt * multiplierBigInt - result * denominatorBigInt;
return { result: import_o1js4.Field.from(result), remainder: import_o1js4.Field.from(remainder) };
});
import_o1js4.Gadgets.rangeCheck64(fields.result);
import_o1js4.Gadgets.rangeCheck64(fields.remainder);
fields.remainder.assertLessThan(denominator.value);
fields.result.mul(denominator.value).add(fields.remainder).assertEquals(value.value.mul(multiplier.value));
return {
result: import_o1js4.UInt64.Unsafe.fromField(fields.result),
remainder: import_o1js4.UInt64.Unsafe.fromField(fields.remainder)
};
}
// dist/node/bid.js
var BidEvent = class extends (0, import_o1js5.Struct)({
amount: import_o1js5.UInt64,
address: import_o1js5.PublicKey
}) {
};
var FungibleTokenBidContract = class extends import_o1js5.SmartContract {
constructor() {
super(...arguments);
this.price = (0, import_o1js5.State)();
this.buyer = (0, import_o1js5.State)();
this.token = (0, import_o1js5.State)();
this.whitelist = (0, import_o1js5.State)();
this.events = {
bid: BidEvent,
withdraw: BidEvent,
sell: BidEvent,
updateWhitelist: import_storage2.Whitelist
};
}
async deploy(args) {
await super.deploy(args);
this.whitelist.set(args.whitelist);
this.account.permissions.set({
...import_o1js5.Permissions.default(),
send: import_o1js5.Permissions.proof(),
setVerificationKey: import_o1js5.Permissions.VerificationKey.impossibleDuringCurrentVersion(),
setPermissions: import_o1js5.Permissions.impossible()
});
}
async initialize(token, amount, price) {
this.account.provedState.requireEquals((0, import_o1js5.Bool)(false));
amount.equals(import_o1js5.UInt64.from(0)).assertFalse();
const totalPrice = mulDiv({
value: price,
multiplier: amount,
denominator: import_o1js5.UInt64.from(1e9)
}).result;
const buyer = this.sender.getUnconstrained();
const buyerUpdate = import_o1js5.AccountUpdate.createSigned(buyer);
buyerUpdate.send({ to: this.address, amount: totalPrice });
buyerUpdate.body.useFullCommitment = (0, import_o1js5.Bool)(true);
this.buyer.set(buyer);
this.price.set(price);
this.token.set(token);
this.emitEvent("bid", { amount, address: buyer });
}
async bid(amount, price) {
amount.equals(import_o1js5.UInt64.from(0)).assertFalse();
const balance = this.account.balance.getAndRequireEquals();
const oldPrice = this.price.getAndRequireEquals();
price.equals(oldPrice).or(balance.equals(import_o1js5.UInt64.from(0))).assertTrue();
this.price.set(price);
const totalPrice = mulDiv({
value: price,
multiplier: amount,
denominator: import_o1js5.UInt64.from(1e9)
}).result;
const sender = this.sender.getUnconstrained();
const buyer = this.buyer.getAndRequireEquals();
sender.assertEquals(buyer);
const buyerUpdate = import_o1js5.AccountUpdate.createSigned(buyer);
buyerUpdate.send({ to: this.address, amount: totalPrice });
buyerUpdate.body.useFullCommitment = (0, import_o1js5.Bool)(true);
this.price.set(price);
this.emitEvent("bid", { amount, address: buyer });
}
async withdraw(amountInMina) {
amountInMina.equals(import_o1js5.UInt64.from(0)).assertFalse();
this.account.balance.requireBetween(amountInMina, import_o1js5.UInt64.MAXINT());
const buyer = this.buyer.getAndRequireEquals();
const sender = this.sender.getUnconstrained();
const senderUpdate = import_o1js5.AccountUpdate.createSigned(sender);
senderUpdate.body.useFullCommitment = (0, import_o1js5.Bool)(true);
sender.assertEquals(buyer);
let bidUpdate = this.send({ to: senderUpdate, amount: amountInMina });
bidUpdate.body.useFullCommitment = (0, import_o1js5.Bool)(true);
this.emitEvent("withdraw", {
amount: amountInMina,
address: buyer
});
}
async sell(amount) {
amount.equals(import_o1js5.UInt64.from(0)).assertFalse();
const price = this.price.getAndRequireEquals();
const totalPrice = mulDiv({
value: price,
multiplier: amount,
denominator: import_o1js5.UInt64.from(1e9)
}).result;
this.account.balance.requireBetween(totalPrice, import_o1js5.UInt64.MAXINT());
const buyer = this.buyer.getAndRequireEquals();
const token = this.token.getAndRequireEquals();
const seller = this.sender.getUnconstrained();
const sellerUpdate = this.send({ to: seller, amount: totalPrice });
sellerUpdate.body.useFullCommitment = (0, import_o1js5.Bool)(true);
sellerUpdate.requireSignature();
const tokenContract = new FungibleToken(token);
await tokenContract.transfer(seller, buyer, amount);
const whitelist = this.whitelist.getAndRequireEquals();
const whitelistedAmount = await whitelist.getWhitelistedAmount(seller);
amount.assertLessThanOrEqual(whitelistedAmount.assertSome("Cannot sell more than whitelisted amount"));
this.emitEvent("sell", { amount, address: seller });
}
async updateWhitelist(whitelist) {
const buyer = this.buyer.getAndRequireEquals();
const sender = this.sender.getUnconstrained();
const senderUpdate = import_o1js5.AccountUpdate.createSigned(sender);
senderUpdate.body.useFullCommitment = (0, import_o1js5.Bool)(true);
sender.assertEquals(buyer);
this.whitelist.set(whitelist);
this.emitEvent("updateWhitelist", whitelist);
}
};
(0, import_tslib4.__decorate)([
(0, import_o1js5.state)(import_o1js5.UInt64),
(0, import_tslib4.__metadata)("design:type", Object)
], FungibleTokenBidContract.prototype, "price", void 0);
(0, import_tslib4.__decorate)([
(0, import_o1js5.state)(import_o1js5.PublicKey),
(0, import_tslib4.__metadata)("design:type", Object)
], FungibleTokenBidContract.prototype, "buyer", void 0);
(0, import_tslib4.__decorate)([
(0, import_o1js5.state)(import_o1js5.PublicKey),
(0, import_tslib4.__metadata)("design:type", Object)
], FungibleTokenBidContract.prototype, "token", void 0);
(0, import_tslib4.__decorate)([
(0, import_o1js5.state)(import_storage2.Whitelist),
(0, import_tslib4.__metadata)("design:type", Object)
], FungibleTokenBidContract.prototype, "whitelist", void 0);
(0, import_tslib4.__decorate)([
import_o1js5.method,
(0, import_tslib4.__metadata)("design:type", Function),
(0, import_tslib4.__metadata)("design:paramtypes", [import_o1js5.PublicKey, import_o1js5.UInt64, import_o1js5.UInt64]),
(0, import_tslib4.__metadata)("design:returntype", Promise)
], FungibleTokenBidContract.prototype, "initialize", null);
(0, import_tslib4.__decorate)([
import_o1js5.method,
(0, import_tslib4.__metadata)("design:type", Function),
(0, import_tslib4.__metadata)("design:paramtypes", [import_o1js5.UInt64, import_o1js5.UInt64]),
(0, import_tslib4.__metadata)("design:returntype", Promise)
], FungibleTokenBidContract.prototype, "bid", null);
(0, import_tslib4.__decorate)([
import_o1js5.method,
(0, import_tslib4.__metadata)("design:type", Function),
(0, import_tslib4.__metadata)("design:paramtypes", [import_o1js5.UInt64]),
(0, import_tslib4.__metadata)("design:returntype", Promise)
], FungibleTokenBidContract.prototype, "withdraw", null);
(0, import_tslib4.__decorate)([
import_o1js5.method,
(0, import_tslib4.__metadata)("design:type", Function),
(0, import_tslib4.__metadata)("design:paramtypes", [import_o1js5.UInt64]),
(0, import_tslib4.__metadata)("design:returntype", Promise)
], FungibleTokenBidContract.prototype, "sell", null);
(0, import_tslib4.__decorate)([
import_o1js5.method,
(0, import_tslib4.__metadata)("design:type", Function),
(0, import_tslib4.__metadata)("design:paramtypes", [import_storage2.Whitelist]),
(0, import_tslib4.__metadata)("design:returntype", Promise)
], FungibleTokenBidContract.prototype, "updateWhitelist", null);
// dist/node/claim.js
var import_tslib5 = require("tslib");
var import_o1js6 = require("o1js");
var import_storage3 = require("@silvana-one/storage");
var ClaimEvent = class extends (0, import_o1js6.Struct)({
amount: import_o1js6.UInt64,
address: import_o1js6.PublicKey
}) {
};
var FungibleTokenClaimContract = class extends import_o1js6.SmartContract {
constructor() {
super(...arguments);
this.owner = (0, import_o1js6.State)();
this.token = (0, import_o1js6.State)();
this.whitelist = (0, import_o1js6.State)();
this.maxAmount = (0, import_o1js6.State)();
this.events = {
offer: ClaimEvent,
withdraw: ClaimEvent,
claim: ClaimEvent,
updateWhitelist: import_storage3.Whitelist
};
}
async deploy(args) {
await super.deploy(args);
this.whitelist.set(args.whitelist);
this.maxAmount.set(args.maxAmount ?? import_o1js6.UInt64.MAXINT());
this.account.permissions.set({
...import_o1js6.Permissions.default(),
send: import_o1js6.Permissions.proof(),
setVerificationKey: import_o1js6.Permissions.VerificationKey.impossibleDuringCurrentVersion(),
setPermissions: import_o1js6.Permissions.impossible()
});
}
async initialize(owner, token, amount) {
this.account.provedState.requireEquals((0, import_o1js6.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 = import_o1js6.AccountUpdate.createSigned(sender);
senderUpdate.body.useFullCommitment = (0, import_o1js6.Bool)(true);
sender.assertEquals(owner);
await tokenContract.transfer(sender, this.address, amount);
this.emitEvent("offer", { amount, address: sender });
}
async withdraw(amount) {
amount.equals(import_o1js6.UInt64.from(0)).assertFalse();
this.account.balance.requireBetween(amount, import_o1js6.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 = import_o1js6.AccountUpdate.createSigned(sender, tokenId);
senderUpdate.body.useFullCommitment = (0, import_o1js6.Bool)(true);
sender.assertEquals(owner);
let offerUpdate = this.send({ to: senderUpdate, amount });
offerUpdate.body.mayUseToken = import_o1js6.AccountUpdate.MayUseToken.InheritFromParent;
offerUpdate.body.useFullCommitment = (0, import_o1js6.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 = import_o1js6.AccountUpdate.createSigned(sender, tokenId);
senderUpdate.body.useFullCommitment = (0, import_o1js6.Bool)(true);
const whitelist = this.whitelist.getAndRequireEquals();
const whiteListedAmount = await whitelist.getWhitelistedAmount(sender);
const maxClaimAmount = import_o1js6.Provable.if(whitelist.isSome(), whiteListedAmount.assertSome("No tokens to claim"), maxAmount);
amount.assertLessThanOrEqual(maxClaimAmount);
this.account.balance.requireBetween(amount, import_o1js6.UInt64.MAXINT());
let offerUpdate = this.send({ to: senderUpdate, amount });
offerUpdate.body.mayUseToken = import_o1js6.AccountUpdate.MayUseToken.InheritFromParent;
offerUpdate.body.useFullCommitment = (0, import_o1js6.Bool)(true);
this.emitEvent("claim", {
amount,
address: sender
});
}
async updateWhitelist(whitelist) {
const owner = this.owner.getAndRequireEquals();
const sender = this.sender.getUnconstrained();
const senderUpdate = import_o1js6.AccountUpdate.createSigned(sender);
senderUpdate.body.useFullCommitment = (0, import_o1js6.Bool)(true);
sender.assertEquals(owner);
this.whitelist.set(whitelist);
this.emitEvent("updateWhitelist", whitelist);
}
};
(0, import_tslib5.__decorate)([
(0, import_o1js6.state)(import_o1js6.PublicKey),
(0, import_tslib5.__metadata)("design:type", Object)
], FungibleTokenClaimContract.prototype, "owner", void 0);
(0, import_tslib5.__decorate)([
(0, import_o1js6.state)(import_o1js6.PublicKey),
(0, import_tslib5.__metadata)("design:type", Object)
], FungibleTokenClaimContract.prototype, "token", void 0);
(0, import_tslib5.__decorate)([
(0, import_o1js6.state)(import_storage3.Whitelist),
(0, import_tslib5.__metadata)("design:type", Object)
], FungibleTokenClaimContract.prototype, "whitelist", void 0);
(0, import_tslib5.__decorate)([
(0, import_o1js6.state)(import_o1js6.UInt64),
(0, import_tslib5.__metadata)("design:type", Object)
], FungibleTokenClaimContract.prototype, "maxAmount", void 0);
(0, import_tslib5.__decorate)([
import_o1js6.method,
(0, import_tslib5.__metadata)("design:type", Function),
(0, import_tslib5.__metadata)("design:paramtypes", [
import_o1js6.PublicKey,
import_o1js6.PublicKey,
import_o1js6.UInt64
]),
(0, import_tslib5.__metadata)("design:returntype", Promise)
], FungibleTokenClaimContract.prototype, "initialize", null);
(0, import_tslib5.__decorate)([
import_o1js6.method,
(0, import_tslib5.__metadata)("design:type", Function),
(0, import_tslib5.__metadata)("design:paramtypes", [import_o1js6.UInt64]),
(0, import_tslib5.__metadata)("design:returntype", Promise)
], FungibleTokenClaimContract.prototype, "offer", null);
(0, import_tslib5.__decorate)([
import_o1js6.method,
(0, import_tslib5.__metadata)("design:type", Function),
(0, import_tslib5.__metadata)("design:paramtypes", [import_o1js6.UInt64]),
(0, import_tslib5.__metadata)("design:returntype", Promise)
], FungibleTokenClaimContract.prototype, "withdraw", null);
(0, import_tslib5.__decorate)([
import_o1js6.method,
(0, import_tslib5.__metadata)("design:type", Function),
(0, import_tslib5.__metadata)("design:paramtypes", [import_o1js6.UInt64]),
(0, import_tslib5.__metadata)("design:returntype", Promise)
], FungibleTokenClaimContract.prototype, "claim", null);
(0, import_tslib5.__decorate)([
import_o1js6.method,
(0, import_tslib5.__metadata)("design:type", Function),
(0, import_tslib5.__metadata)("design:paramtypes", [import_storage3.Whitelist]),
(0, import_tslib5.__metadata)("design:returntype", Promise)
], FungibleTokenClaimContract.prototype, "updateWhitelist", null);
// dist/node/offer.js
var import_tslib6 = require("tslib");
var import_o1js7 = require("o1js");
var import_storage4 = require("@silvana-one/storage");
var OfferEvent = class extends (0, import_o1js7.Struct)({
amount: import_o1js7.UInt64,
address: import_o1js7.PublicKey
}) {
};
var FungibleTokenOfferContract = class extends import_o1js7.SmartContract {
constructor() {
super(...arguments);
this.price = (0, import_o1js7.State)();
this.seller = (0, import_o1js7.State)();
this.token = (0, import_o1js7.State)();
this.whitelist = (0, import_o1js7.State)();
this.events = {
offer: OfferEvent,
withdraw: OfferEvent,
buy: OfferEvent,
updateWhitelist: import_storage4.Whitelist
};
}
async deploy(args) {
await super.deploy(args);
this.whitelist.set(args.whitelist);
this.account.permissions.set({
...import_o1js7.Permissions.default(),
send: import_o1js7.Permissions.proof(),
setVerificationKey: import_o1js7.Permissions.VerificationKey.impossibleDuringCurrentVersion(),
setPermissions: import_o1js7.Permissions.impossible()
});
}
async initialize(seller, token, amount, price) {
this.account.provedState.requireEquals((0, import_o1js7.Bool)(false));
const tokenContract = new FungibleToken(token);
const tokenId = tokenContract.deriveTokenId();
tokenId.assertEquals(this.tokenId);
await tokenContract.transfer(seller, this.address, amount);
this.seller.set(seller);
this.price.set(price);
this.token.set(token);
this.emitEvent("offer", { amount, address: seller });
}
async offer(amount, price) {
const seller = this.seller.getAndRequireEquals();
const token = this.token.getAndRequireEquals();
const tokenContract = new FungibleToken(token);
const tokenId = tokenContract.deriveTokenId();
tokenId.assertEquals(this.tokenId);
const balance = this.account.balance.getAndRequireEquals();
const oldPrice = this.price.getAndRequireEquals();
price.equals(oldPrice).or(balance.equals(import_o1js7.UInt64.from(0))).assertTrue();
this.price.set(price);
const sender = this.sender.getUnconstrained();
const senderUpdate = import_o1js7.AccountUpdate.createSigned(sender);
senderUpdate.body.useFullCommitment = (0, import_o1js7.Bool)(true);
sender.assertEquals(seller);
await tokenContract.transfer(sender, this.address, amount);
this.emitEvent("offer", { amount, address: sender });
}
async withdraw(amount) {
amount.equals(import_o1js7.UInt64.from(0)).assertFalse();
this.account.balance.requireBetween(amount, import_o1js7.UInt64.MAXINT());
const seller = this.seller.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 = import_o1js7.AccountUpdate.createSigned(sender, tokenId);
senderUpdate.body.useFullCommitment = (0, import_o1js7.Bool)(true);
sender.assertEquals(seller);
let offerUpdate = this.send({ to: senderUpdate, amount });
offerUpdate.body.mayUseToken = import_o1js7.AccountUpdate.MayUseToken.InheritFromParent;
offerUpdate.body.useFullCommitment = (0, import_o1js7.Bool)(true);
this.emitEvent("withdraw", { amount, address: sender });
}
async buy(amount) {
amount.equals(import_o1js7.UInt64.from(0)).assertFalse();
this.account.balance.requireBetween(amount, import_o1js7.UInt64.MAXINT());
const seller = this.seller.getAndRequireEquals();
const token = this.token.getAndRequireEquals();
const tokenContract = new FungibleToken(token);
const tokenId = tokenContract.deriveTokenId();
tokenId.assertEquals(this.tokenId);
const price = this.price.getAndRequireEquals();
const totalPrice = mulDiv({
value: price,
multiplier: amount,
denominator: import_o1js7.UInt64.from(1e9)
}).result;
const buyer = this.sender.getUnconstrained(