@silvana-one/token
Version:
Silvana Fungible Token Library
96 lines (85 loc) • 2.76 kB
text/typescript
import {
AccountUpdate,
assert,
Bool,
DeployArgs,
method,
Permissions,
Provable,
PublicKey,
SmartContract,
State,
state,
VerificationKey,
} from "o1js";
import { FungibleTokenAdminBase } from "./FungibleTokenContract.js";
export interface FungibleTokenAdminDeployProps
extends Exclude<DeployArgs, undefined> {
adminPublicKey: PublicKey;
}
/** A contract that grants permissions for administrative actions on a token.
*
* We separate this out into a dedicated contract. That way, when issuing a token, a user can
* specify their own rules for administrative actions, without changing the token contract itself.
*
* The advantage is that third party applications that only use the token in a non-privileged way
* can integrate against the unchanged token contract.
*/
export class FungibleTokenAdmin
extends SmartContract
implements FungibleTokenAdminBase
{
(PublicKey)
private adminPublicKey = State<PublicKey>();
async deploy(props: FungibleTokenAdminDeployProps) {
await super.deploy(props);
this.adminPublicKey.set(props.adminPublicKey);
this.account.permissions.set({
...Permissions.default(),
setVerificationKey:
Permissions.VerificationKey.impossibleDuringCurrentVersion(),
setPermissions: 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: VerificationKey) {
this.account.verificationKey.set(vk);
}
private async ensureAdminSignature() {
const admin = await Provable.witnessAsync(PublicKey, async () => {
let pk = await this.adminPublicKey.fetch();
assert(pk !== undefined, "could not fetch admin public key");
return pk;
});
this.adminPublicKey.requireEquals(admin);
return AccountUpdate.createSigned(admin);
}
.returns(Bool)
public async canMint(_accountUpdate: AccountUpdate) {
await this.ensureAdminSignature();
return Bool(true);
}
.returns(Bool)
public async canChangeAdmin(_admin: PublicKey) {
await this.ensureAdminSignature();
return Bool(true);
}
.returns(Bool)
public async canPause(): Promise<Bool> {
await this.ensureAdminSignature();
return Bool(true);
}
.returns(Bool)
public async canResume(): Promise<Bool> {
await this.ensureAdminSignature();
return Bool(true);
}
.returns(Bool)
public async canChangeVerificationKey(_vk: VerificationKey): Promise<Bool> {
await this.ensureAdminSignature();
return Bool(true);
}
}