UNPKG

o1js

Version:

TypeScript framework for zk-SNARKs and zkApps

98 lines (87 loc) 2.86 kB
import { AccountUpdate, Authorization, TokenId } from '../account-update.js'; import { isSmartContract } from '../smart-contract-base.js'; import { PublicKey } from '../../provable/crypto/signature.js'; import type { SmartContract } from '../zkapp.js'; import { UInt64 } from '../../provable/int.js'; import { Bool, Field } from '../../provable/wrapped.js'; export { tokenMethods }; function tokenMethods(self: AccountUpdate) { return { /** * Mints token balance to `address`. Returns the mint account update. */ mint({ address, amount, }: { address: PublicKey | AccountUpdate | SmartContract; amount: number | bigint | UInt64; }) { let id = TokenId.derive(self.publicKey, self.tokenId); let receiver = getApprovedUpdate(self, id, address, 'token.mint()'); receiver.balance.addInPlace(amount); return receiver; }, /** * Burn token balance on `address`. Returns the burn account update. */ burn({ address, amount, }: { address: PublicKey | AccountUpdate | SmartContract; amount: number | bigint | UInt64; }) { let id = TokenId.derive(self.publicKey, self.tokenId); let sender = getApprovedUpdate(self, id, address, 'token.burn()'); // Sub the amount to burn from the sender's account sender.balance.subInPlace(amount); // Require signature from the sender account being deducted sender.body.useFullCommitment = Bool(true); Authorization.setLazySignature(sender); return sender; }, /** * Move token balance from `from` to `to`. Returns the `to` account update. */ send({ from, to, amount, }: { from: PublicKey | AccountUpdate | SmartContract; to: PublicKey | AccountUpdate | SmartContract; amount: number | bigint | UInt64; }) { let id = TokenId.derive(self.publicKey, self.tokenId); let sender = getApprovedUpdate(self, id, from, 'token.send() (sender)'); sender.balance.subInPlace(amount); sender.body.useFullCommitment = Bool(true); Authorization.setLazySignature(sender); let receiver = getApprovedUpdate(self, id, to, 'token.send() (receiver)'); receiver.balance.addInPlace(amount); return receiver; }, }; } // helper function getApprovedUpdate( self: AccountUpdate, tokenId: Field, child: PublicKey | AccountUpdate | SmartContract, label: string ) { if (isSmartContract(child)) { child = child.self; } if (child instanceof AccountUpdate) { child.tokenId.assertEquals(tokenId); self.approve(child); } if (child instanceof PublicKey) { child = AccountUpdate.defaultAccountUpdate(child, tokenId); self.approve(child); } if (!child.label) child.label = `${self.label ?? 'Unlabeled'}.${label}`; return child; }