Skip to content

Commit

Permalink
docs: Proofread Standards docs (#1668)
Browse files Browse the repository at this point in the history
* fix(docs): Typos in Standards section

* fix(docs): Fix typos and broken links in coin docs

* fix(docs): Typos in CoinManager doc

* feat(docs): Add missing PTBs to kiosk docs

* fix(docs): Typos in kiosk apps

* fix(docs): Fix typos and consistency

* fix(docs): Convert tabs to spaces

* fix(docs): Typos in wallet standard

* fix(docs): JavaScript examples

* fix(docs): Make Move examples syntactically correct

* fix(docs): Put overview on Standards header

* fix(docs): update link to Standards in developer documentation

* Update docs/content/sidebars/developer.js

Co-authored-by: Dr-Electron <[email protected]>

* fix(docs): Auto generate standards overview

* fix(docs): More move warning fixes

* fix(docs): Use `programmable_move_call` instead of command

---------

Co-authored-by: Thibault Martinez <[email protected]>
Co-authored-by: Dr-Electron <[email protected]>
  • Loading branch information
3 people authored Aug 13, 2024
1 parent 21befe0 commit 2d52a43
Show file tree
Hide file tree
Showing 13 changed files with 259 additions and 211 deletions.
4 changes: 2 additions & 2 deletions docs/content/developer/developer.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Go to [Cryptography](cryptography.mdx).

Utilizing standards while developing applications is very important for composability. In this section you can find out all about the standards within the IOTA Move ecosystem for dealing with tokens, NFT like objects, and wallets.

Go to the [Standards](standards/standards.mdx).
Go to the [Standards](/developer/standards).

## Advanced Topics

Expand Down Expand Up @@ -69,4 +69,4 @@ Go to [Migrating from IOTA/Shimmer Stardust](stardust/stardust-migration.mdx).

This section contains the technical details needed to integrate IOTA on a exchange.

Go to [Exchange integration](exchange-integration/exchange-integration.mdx).
Go to [Exchange integration](exchange-integration/exchange-integration.mdx).
4 changes: 2 additions & 2 deletions docs/content/developer/standards/closed-loop-token.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
title: Closed-Loop Token
---

Using the Closed-Loop Token standard, you can limit the applications that can use the token and set up custom policies for transfers, spends, and conversions. The [`iota::token` module](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/iota-framework/token.md) in the IOTA framework defines the standard.
Using the Closed-Loop Token standard, you can limit the applications that can use the token and set up custom policies for transfers, spends, and conversions. The [`iota::token` module](../../references/framework/iota-framework/token.mdx) in the IOTA framework defines the standard.

## Background and use cases

The [Coin standard](coin.mdx) on IOTA is an example of an open-loop system - coins are free-flowing, [wrappable](../iota-101/objects/object-ownership/wrapped.mdx), [freely transferable](../iota-101/objects/transfers/custom-rules.mdx#the-store-ability-and-transfer-rules) and you can store them in any application. The best real world analogy would be cash - hardly regulated and can be freely used and passed.

Some applications, however, require constraining the scope of the token to a specific purpose. For example, some applications might need a token that you can only use for a specific service, or that an authorized account can only use, or a token that you can block certain accounts from using. A real-world analogy would be a bank account - regulated, bank-controlled, and compliant with certain rules and policies.
Some applications, however, require constraining the scope of the token to a specific purpose. For example, some applications might need a token that you can only use for a specific service, or that only an authorized account can use, or a token that you can block certain accounts from using. A real-world analogy would be a bank account - regulated, bank-controlled, and compliant with certain rules and policies.

## Difference with Coin

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ tx.moveCall({

### Confirming with TokenPolicyCap

Use `TokenPolicyCap` to confirm action requests. A convenient approach when the `TreasuryCap` is wrapped in another object, and `TokenPolicy` does not allow certain action or has rules that make the default way of confirming impossible.
Use `TokenPolicyCap` to confirm action requests. A convenient approach when the `TreasuryCap` is wrapped in another object, and `TokenPolicy` does not allow a certain action or has rules that make the default way of confirming impossible.

:::info

Expand Down Expand Up @@ -192,7 +192,7 @@ tx.moveCall({

## Approving actions

`ActionRequest`s can collect approvals - witness stamps from applications or rules. They carry the confirmation that a certain module or a rule has approved the action. This mechanic allows gating actions behind certain requirements.
`ActionRequest`s can collect approvals - witness stamps from applications or rules. They carry the confirmation that a certain module or a rule has approved the action. This mechanism allows gating actions behind certain requirements.

The signature for the `token::add_approval` function is:

Expand Down
5 changes: 2 additions & 3 deletions docs/content/developer/standards/closed-loop-token/rules.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ A rule is represented as a witness - a type with a `drop` ability. You can eithe

```move
/// The Rule type
struct Rule has drop {}
public struct Rule has drop {}
```

After you [add a rule](token-policy.mdx#adding-rules) to an action in the `TokenPolicy`, the action requires a stamp of the rule to pass confirmation.
Expand All @@ -25,11 +25,10 @@ A rule module is a regular module with a `verify`-like function that typically t

```move
module example::pass_rule {
use iota::tx_context;
use iota::token::{Self, ActionRequest, TokenPolicy};
/// The Rule type
struct Pass has drop {}
public struct Pass has drop {}
/// Add approval from the Pass rule to the ActionRequest
public fun verify<T>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Normally, the `spend` action should have at least one rule assigned to it to pre

```move
/// Rule-like witness to stamp the ActionRequest
struct GiftShop has drop {}
public struct GiftShop has drop {}
/// Spend the token and return a Gift + ActionRequest
public fun buy_gift(
Expand Down
54 changes: 26 additions & 28 deletions docs/content/developer/standards/coin-manager.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,25 @@ By having your `Coin` managed by a `CoinManager`, you gain the following functio
- Both management caps can transparently be renounced through the `CoinManager` so that everyone on-chain can know that the supply and metadata are immutable, Offering end-users clarity and assurance.
- A `CoinManagerTreasuryCap`-owned object will allow you to set a maximum supply for a coin. This will ensure that once set (a one-time, irrevocable action), there will never be any more tokens minted as the provided maximum supply. This offers assurances to the end-user about the asset they are interested in.
- A custom additional Metadata object can be provided, allowing coins to have more data than just the standard fields provided by the default `Metadata` object. The existing metadata object will stay the same and remain fully compatible.
- The total supply of a given `Coin` type, the maximum supply, and the metadata can be transparently queried through the `CoinManager` by anyone interested, not just the `TreauryCap` owner.
- The total supply of a given `Coin` type, the maximum supply, and the metadata can be transparently queried through the `CoinManager` by anyone interested, not just the `TreasuryCap` owner.

With a `CoinManager` in place, you can offer assurances to whoever uses your `Coin` that can not be offered with just a regular `Coin` and `TreasuryCap`. We recommend every new coin utilize the `CoinManager.` Any existing coin can be managed by a `CoinManager` as long as the `TreasuryCap` object for that `Coin` is still in possession.
With a `CoinManager` in place, you can offer assurances to whoever uses your `Coin` that can not be offered with just a regular `Coin` and `TreasuryCap`. We recommend every new coin utilize the `CoinManager`. Any existing coin can be managed by a `CoinManager` as long as the `TreasuryCap` object for that `Coin` is still in possession.

## How To Manage A `Coin` With A `CoinManager`
## How To Manage a `Coin` With a `CoinManager`

### New `Coin` Assets

When you are starting a new `Coin` type and wish to use the `CoinManager` you can use the `CoinManager` directly to create this `Coin`. You will receive back the `CoinManagerTreasuryCap` and a `CoinManagerMetadataCap` to perform any follow-up management actions:
When you are creating a new `Coin` type and wish to use the `CoinManager` you can use the `CoinManager` directly to create this `Coin`. You will receive back the `CoinManagerTreasuryCap` and a `CoinManagerMetadataCap` to perform any follow-up management actions:

```move
module example::exclusive_coin {
use iota::coin_manager;
public struct EXCLUSIVE_COIN has drop {}
#[allow(lint(share_owned))]
fun init(witness: EXCLUSIVE_COIN, ctx: &mut TxContext) {
// Create a `Coin` type and have it managed.
let (cm_treasury_cap, cm_meta_cap, mut manager) = coin_manager::create(
let (cm_treasury_cap, cm_meta_cap, manager) = coin_manager::create(
witness,
0,
b"EXCL",
Expand All @@ -50,13 +49,13 @@ module example::exclusive_coin {
ctx
);
// Returning a new `CoinManagerTreasuryCap` to the creator of the `Coin`
// Transfer the `CoinManagerTreasuryCap` to the creator of the `Coin`.
transfer::public_transfer(cm_treasury_cap, ctx.sender());
// Returning a new `CoinManagerMetadataCap` to the creator of the `Coin`
// Transfer the `CoinManagerMetadataCap` to the creator of the `Coin`.
transfer::public_transfer(cm_meta_cap, ctx.sender());
// Publicly sharing the `CoinManager` object for convenient usage by anyone interested
// Publicly share the `CoinManager` object for convenient usage by anyone interested.
transfer::public_share_object(manager);
}
}
Expand All @@ -71,28 +70,28 @@ If you already have an existing `Coin`, you can create the `CoinManager` object
If you already froze the `Metadata` object you can only migrate to a `CoinManager` that has immutable metadata from the start. You will not receive a `CoinManagerMetadataCap` in return, but you will get a `CoinManagerTreasuryCap`:

```move
let (cm_treasury_cap, mut manager) = coin_manager::new_with_immutable_metadata(cap, &meta, ctx);
let (cm_treasury_cap, manager) = coin_manager::new_with_immutable_metadata(cap, &meta, ctx);
// Returning a new `CoinManagerTreasuryCap` to the creator of the `Coin`
// Transfer the `CoinManagerTreasuryCap` to the creator of the `Coin`.
transfer::public_transfer(cm_treasury_cap, ctx.sender());
// Publicly sharing the `CoinManager` object for convenient usage by anyone interested
// Publicly share the `CoinManager` object for convenient usage by anyone interested.
transfer::public_share_object(manager);
```
#### With mutable metadata

If the metadata object is still owned, you can take advantage of the full functionality of the `CoinManager` with mutable `Metadata`:

```move
let (cm_treasury_cap, cm_meta_cap, mut manager) = coin_manager::new(cap, meta, ctx);
let (cm_treasury_cap, cm_meta_cap, manager) = coin_manager::new(cap, meta, ctx);
// Returning a new `CoinManagerTreasuryCap` to the creator of the `Coin`
// Transfer the `CoinManagerTreasuryCap` to the creator of the `Coin`.
transfer::public_transfer(cm_treasury_cap, ctx.sender());
// Returning a new `CoinManagerMetadataCap` to the creator of the `Coin`
// Transfer the `CoinManagerMetadataCap` to the creator of the `Coin`.
transfer::public_transfer(cm_meta_cap, ctx.sender());
// Publicly sharing the `CoinManager` object for convenient usage by anyone interested
// Publicly share the `CoinManager` object for convenient usage by anyone interested.
transfer::public_share_object(manager);
```

Expand All @@ -103,10 +102,10 @@ Once the `CoinManager` has been created and publicly shared you can make use of
### Retrieving metadata

```move
/// Get the decimals for a Coin managed by this manager, without needing the Metadata object
/// Get the decimals for the `Coin` of this manager, without needing the Metadata object.
let decimals = manager.decimals();
/// See if the Metadata is immutable or if it can still be changed later:
/// See if the Metadata is immutable or if it can still be changed later.
let immutabe = manager.metadata_is_immutable();
```

Expand All @@ -118,17 +117,17 @@ let max_supply = manager.maximum_supply();
let remaining_supply = manager.available_supply();
let has_maximum_supply = manager.has_maximum_supply();
let supply_reference = manager.supply_immut();
let immutabe = manager.supply_is_immutable();
let supply_is_immutable = manager.supply_is_immutable();
```

### Minting

```move
/// Minting more coins, if allowed
/// Mint more coins, if allowed.
let coin = coin_manager_treasury_cap.mint(&mut manager, 100, ctx);
```

Next to minting the same functionality is available that usually is available on the `TreasuryCap` like `burn`, `mint_balance`, and `mint_and_transfer`.
Next to minting, the same functionality is available that usually is available on the `TreasuryCap` like `burn`, `mint_balance` and `mint_and_transfer`.

### Updating Metadata

Expand All @@ -143,10 +142,10 @@ coin_manager_metadata_cap.update_symbol(&mut manager, "NEW");
By renouncing ownership (handing in your cap(s)), you provide assurances for your `Coin` type to its users. Users can check if a `Coin` type has an immutable supply or metadata on-chain.

```move
/// Turns the supply immutable, no more minting or max. supply changes
/// Turns the supply immutable. No more minting or maximum supply changes.
coin_manager_treasury_cap.renounce_ownership(&mut manager);
/// Turns the metadata immutable
/// Turns the metadata immutable.
coin_manager_metadata_cap.renounce_ownership(&mut manager);
```

Expand All @@ -169,15 +168,14 @@ let version = wrapper.additional_metadata<T, CustomMetadata>().version;
If you wish to update or replace your custom Metadata object with a new one (of the same type or another), you can do so using the `replace_additional_metadata` function, which returns the old Metadata object:

```move
public struct NewCustomMetadata has store {
website: Url,
is_amazing: bool
website: Url,
is_amazing: bool
}
let new_meta = NewCustomMetadata {
website: url::new_unsafe(string(b"https://iota.org")),
is_amazing: true
website: url::new_unsafe(string(b"https://iota.org")),
is_amazing: true
};
let oldmeta = metacap.replace_additional_metadata<COIN_TYPE, NewCustomMetadata, CustomMetadata>(&mut wrapper, new_meta);
Expand Down
17 changes: 9 additions & 8 deletions docs/content/developer/standards/coin.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,15 @@ let deny_list = ptb.obj(ObjectArg::SharedObject {
mutable: true,
})?;
let deny_cap = ptb.obj(ObjectArg::ImmOrOwnedObject(deny_cap))?;
let address = ptb.pure(cmd.address())?;
ptb.command(Command::move_call(
let address_to_ban = IotaAddress::from_str("0x...")?;
let address_to_ban_arg = ptb.pure(address_to_ban)?;
ptb.programmable_move_call(
IOTA_FRAMEWORK_PACKAGE_ID,
Identifier::from(COIN_MODULE_NAME),
Identifier::from_str("deny_list_add".to_string())?,
Identifier::from_str("deny_list_add")?,
vec![<otw-type>],
vec![deny_list, deny_cap, address],
));
vec![deny_list, deny_cap, address_to_ban_arg],
);

let builder = ptb.finish();
```
Expand All @@ -191,7 +192,7 @@ let builder = ptb.finish();
- `SequenceNumber` is the `initial_shared_version` of the `DenyList` singleton.
- `deny_cap` is the `ObjectRef` (`(ObjectID, SequenceNumber, ObjectDigest)`) of the `DenyCap<REGULATED_COIN>` the publisher has received.
- `otw_type` is the `TypeTag` created from `<PACKAGE_ID>::regulated_coin::REGULATED_COIN` type.
- `cmd.address()` returns the address to ban as a `IOTAAddress`.
- `address_to_ban` is the address to ban as an `IotaAddress`.

</TabItem>

Expand Down Expand Up @@ -266,6 +267,6 @@ Check out the following content for more information about coins and tokens on I

- [Create a Coin](../iota-101/create-coin/create-coin.mdx): Guide for creating coins and regulated coins in your smart contracts.
- [Closed-Loop Token Standard](closed-loop-token.mdx): Details the Token standard on IOTA.
- [`coin` module rustdoc documentation](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/iota-framework/coin.md): Automated documentation output for the IOTA framework `coin` module.
- [`token` module rustdoc documentation](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/iota-framework/token.md): Automated documentation output for the IOTA framework `token` module.
- [`coin` module documentation](../../references/framework/iota-framework/coin.mdx): Automated documentation output for the IOTA framework `coin` module.
- [`token` module documentation](../../references/framework/iota-framework/token.mdx): Automated documentation output for the IOTA framework `token` module.
- [Tokenomics](../../about-iota/tokenomics.mdx): Discover the IOTA ecosystem and where IOTA coins fit within it.
Loading

0 comments on commit 2d52a43

Please sign in to comment.