Skip to content

Commit

Permalink
configuring mdbook (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
harrysolovay authored Apr 3, 2024
1 parent 840f302 commit d71fc89
Show file tree
Hide file tree
Showing 12 changed files with 244 additions and 115 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Documentation
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
container:
image: michaelfbryan/mdbook-docker-image
steps:
- uses: actions/checkout@v4
- run: mdbook build
- uses: actions/upload-artifact@v4
with:
name: documentation
path: ./target/documentation
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
name: documentation
path: ./target/documentation
- uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./target/documentation


1 change: 1 addition & 0 deletions FungibleToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export class FungibleToken extends TokenContract implements FungibleTokenLike {
setOwner(owner: PublicKey) {
this.ensureOwnerSignature()
this.owner.set(owner)
this.emitEvent("SetOwner", owner)
}

@method
Expand Down
37 changes: 37 additions & 0 deletions book.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[book]
language = "en"
multilingual = false
src = "documentation"
title = "Mina Fungible Token Documentation"
description = "Information on using implementing and interacting with custom fungible tokens on Mina."

[build]
build-dir = "target/documentation"
create-missing = false

[output.html]
copy-fonts = true
edit-url-template = "https://github.com/MinaFoundation/mina-fungible-token/edit/main/{path}"
git-repository-url = "https://github.com/MinaFoundation/mina-fungible-token"
no-section-label = false
preferred-dark-theme = "Coal"

[output.html.print]
enable = true

[output.html.fold]
enable = true
level = 1

[output.html.search]
enable = true
limit-results = 30
teaser-word-count = 30
use-boolean-and = true
boost-title = 2
boost-hierarchy = 1
boost-paragraph = 1
expand = true
heading-split-level = 3
copy-js = true

56 changes: 0 additions & 56 deletions docs/01-concepts.md

This file was deleted.

7 changes: 7 additions & 0 deletions documentation/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Summary

- [Introduction](./introduction.md)
- [API](./api.md)
- [Deploy](./deploy.md)
- [Token Operations](./token_operations.md)
- [Use in ZkApp](./use_in_zk_app.md)
32 changes: 19 additions & 13 deletions docs/02-api.md → documentation/api.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
# FungibleTokenBase API overview
# API overview

The token standard implementation is a Token Manager zkApp that is splitted in 2 parts: low-level and high-level one.
The token standard implementation is a Token Manager zkApp that is split in 2 parts: low-level and
high-level one.

The low-level implementation is included in `o1js` library `TokenContract` abstract class. See the overview in the o1js [Custom Tokens tutorial](https://docs.minaprotocol.com/zkapps/o1js/custom-tokens)
The low-level implementation is included in `o1js` library `TokenContract` abstract class. See the
overview in the o1js
[Custom Tokens tutorial](https://docs.minaprotocol.com/zkapps/o1js/custom-tokens)

> [!WARNING]
> Please note that this is a beta release. The implementation will change soon. The API may also change in future.
> [!WARNING] Please note that this is a beta release. The implementation will change soon. The API
> may also change in future.
The high-level part inherts from the `TokenContract` class and has following user-facing features:
The high-level part inherits from the `TokenContract` class and has following user-facing features:

## On-chain State, `decimals` and deploy arguments

Expand All @@ -21,17 +24,21 @@ The on-chain state is defined as follows:

- `owner` is set on deployment, and some of token functionality requires an admin signature.

If you want to implement admin-only method, just call `this.ensureOwnerSignature()` helper in the method you want to protect.
If you want to implement admin-only method, just call `this.ensureOwnerSignature()` helper in the
method you want to protect.

- `supply` defines a maximum amount of tokens to exist. It is set on deployment and can be modified with `setSupply()` function (can be called by admin only)
- `supply` defines a maximum amount of tokens to exist. It is set on deployment and can be modified
with `setSupply()` function (can be called by admin only)

- `circulating` tracks the total amount in circulation. When new tokens are minted, the `circulating` increases by an amount minted.
- `circulating` tracks the total amount in circulation. When new tokens are minted, the
`circulating` increases by an amount minted.

- The `decimals` is a constant, that defines where to place the decimal comma in the token amounts.

- The `deploy()` function requires `owner` and `supply` to be passed as parameters.

- Along with state variables initial values, the `deploy()` function also takes `symbol` (to set `account.tokenSymbol`) and `src` (to set `account.zkappUri`)
- Along with state variables initial values, the `deploy()` function also takes `symbol` (to set
`account.tokenSymbol`) and `src` (to set `account.zkappUri`)

## Methods

Expand Down Expand Up @@ -61,8 +68,7 @@ getDecimals()

## Events

On each token operation, the event is emitted.
The events are declared as follows:
On each token operation, the event is emitted. The events are declared as follows:

```ts
events = {
Expand Down Expand Up @@ -90,4 +96,4 @@ class TransferEvent extends Struct({
}) {}
```

That completes a review of a fungible token.
That completes a review of a fungible token.
35 changes: 19 additions & 16 deletions docs/03-deploy.md → documentation/deploy.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
# Create and deploy a custom token
# Deploy

To create a token manager smart contract, inherit your smart contract from base custom token implementation, or use the `FungibleToken` directly
To create a token manager smart contract, inherit your smart contract from base custom token
implementation, or use the `FungibleToken` directly

```ts
import {
FungibleToken
} from 'mina-fungible-token';
import { FungibleToken } from "mina-fungible-token"

class MyToken extends FungibleToken {}
```

> [!NOTE]
> If you inherit from `FungibleToken` to override some functionality, you will need to compile both parent and child contracts to be able to prove code for both of them
> [!NOTE] If you inherit from `FungibleToken` to override some functionality, you will need to
> compile both parent and child contracts to be able to prove code for both of them
To deploy a token manager contract, create and compile the token contract instance, then create, prove and sign the deploy transaction:
To deploy a token manager contract, create and compile the token contract instance, then create,
prove and sign the deploy transaction:

```ts
await FungibleToken.compile()
await MyToken.compile()

const {
privateKey: tokenKey,
publicKey: tokenAddress
privateKey: tokenKey,
publicKey: tokenAddress,
} = PrivateKey.randomKeypair()
const token = new MyToken(tokenAddress)

// paste the private key of the deployer and admin account here
const deployerKey = PrivateKey.fromBase58('...')
const ownerKey = PrivateKey.fromBase58('...')
const deployerKey = PrivateKey.fromBase58("...")
const ownerKey = PrivateKey.fromBase58("...")
const owner = PublicKey.fromPrivateKey(ownerKey)
const deployer = PublicKey.fromPrivateKey(deployerKey)

const supply = UInt64.from(21_000_000)
const symbol = 'MYTKN'
const symbol = "MYTKN"
const src = "https://github.com/MinaFoundation/mina-fungible-token/blob/main/FungibleToken.ts"

const fee = 1e8

const tx = await Mina.transaction({sender: deployer, fee}, () => {
const tx = await Mina.transaction({ sender: deployer, fee }, () => {
AccountUpdate.fundNewAccount(deployer, 1)
token.deploy(owner, supply, symbol, src)
})
Expand All @@ -47,6 +47,9 @@ await tx.prove()
await tx.send()
```

For this and following samples to work, make sure you have enough funds on deployer and admin accounts.
For this and following samples to work, make sure you have enough funds on deployer and admin
accounts.

Refer to [examples/e2e.eg.ts](https://github.com/MinaFoundation/mina-fungible-token/blob/main/examples/e2e.eg.ts) to see executable end to end example.
Refer to
[examples/e2e.eg.ts](https://github.com/MinaFoundation/mina-fungible-token/blob/main/examples/e2e.eg.ts)
to see executable end to end example.
90 changes: 90 additions & 0 deletions documentation/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Introduction

Mina natively supports custom tokens
([MIP-4](https://github.com/MinaProtocol/MIPs/blob/main/MIPS/mip-zkapps.md#token-mechanics)). Each
account on Mina can correspond to a custom token.

To create a new token, one creates a smart contract, which becomes the manager for the token, and
uses that contract to set the rules around how the token can be minted, burned and transferred. The
contract may also set a token symbol. Uniqueness is not enforced for token names. Instead the public
key of the contract is used to derive the token's unique identifier.

## SHOW ME THE CODE

The
[`mina-fungible-token` repo's e2e example](https://github.com/MinaFoundation/mina-fungible-token/blob/main/examples/e2e.eg.ts)
showcases the entire lifecycle of a token.

After running `npm i mina-fungible-token`, import the `FungibleToken` contract and deploy it like
so.

```ts
const token = new FungibleToken(contract.publicKey)

const deployTx = await Mina.transaction({
sender: deployer.publicKey,
fee,
}, () => {
AccountUpdate.fundNewAccount(deployer.publicKey, 1)
token.deploy({
owner: owner.publicKey,
supply: UInt64.from(10_000_000_000_000),
symbol: "abc",
src: "https://github.com/MinaFoundation/mina-fungible-token/blob/main/examples/e2e.eg.ts",
})
})
await deployTx.prove()
deployTx.sign([deployer.privateKey, contract.privateKey])
await deployTx.send()
```

> Note: this example assumes that `contract` and `deployer` are valid key pairs in scope.
## How?

How is this custom token mechanism implemented in Mina?

### Token Manager

The token manager account is a contract with the following capabilities.

- Set a token symbol (also called token name) for its token. Uniqueness is not enforced for token
names because the public key of the manager account is used to derive a unique identifier for each
token.
- Mint new tokens. The zkApp updates an account's balance by adding the newly created tokens to it.
You can send minted tokens to any existing account in the network.
- Burn tokens (the opposite of minting). Burning tokens deducts the balance of a certain address by
the specified amount. A zkApp cannot burn more tokens than the specified account has.
- Send tokens between two accounts. Any account can initiate a transfer, and the transfer must be
approved by a Token Manager zkApp (see [Approval mechanism](#approval-mechanism)).

### Token Account

Token accounts are like regular accounts, but they hold a balance of a specific custom token instead
of MINA. A token account is created from an existing account and is specified by a public key _and_
a token id.

Token accounts are specific for each type of custom token, so a single public key can have many
different token accounts.

A token account is automatically created for a public key whenever an existing account receives a
transaction denoted with a custom token.

> [!IMPORTANT] When a token account is created for the first time, an account creation fee must be
> paid the same as creating a new standard account.
### Token ID

Token ids are unique identifiers that distinguish between different types of custom tokens. Custom
token identifiers are globally unique across the entire network.

Token ids are derived from a Token Manager zkApp. Use `deriveTokenId()` function to get id of a
token.

### Approval mechanism

Sending tokens between two accounts must be approved by a Token Manager zkApp. This can be done with
`approveBase()` method of the custom token standard reference implementation.

If you customize the `transfer()` function or constructing `AccountUpdate`s for sending tokens
manually, don't forget to call `approveBase()`.
Loading

0 comments on commit d71fc89

Please sign in to comment.