Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create FungibleTokenMetadataViews contract #89

Merged
merged 58 commits into from Nov 29, 2022

Conversation

alilloig
Copy link
Contributor

@alilloig alilloig commented Sep 1, 2022

Closes: #82

Description

Creates the contract for the Fungible Token's Metadata Views.


For contributor use:

  • Targeted PR against master branch
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
  • Code follows the standards mentioned here.
  • Updated relevant documentation
  • Re-reviewed Files changed in the Github PR explorer
  • Added appropriate labels
  • Update the version in package.json when there is a change in the smart contracts

@alilloig alilloig linked an issue Sep 1, 2022 that may be closed by this pull request
@alilloig alilloig added Feature Improvement SC-Eng Issues that we want to see surfaced in SC-Eng ZH Board and removed Improvement labels Sep 1, 2022
@alilloig
Copy link
Contributor Author

alilloig commented Sep 1, 2022

There are at least two thing I'd love to have some input, the contract name and how to deal with the MetadataViews.cdc file


/// Function that allows creation of an empty FT vault that is intended
/// to store the funds.
pub let createEmptyVault: ((): @FungibleToken.Vault)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reasoning for this createEmptyVault function to be inside the FTVaultData struct?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

People can get metadata views from an object without importing or knowing what contract the object comes from, so this view allows code that has the object or a reference to it, but not the imported contract, to be able to create a new vault and also know what the storage and public paths are for it without having to find out that information elsewhere.

Copy link
Member

@joshuahannan joshuahannan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good so far! I think the name is good and just copying MetadataViews into the utility contracts directory here is probably fine until we figure out a better way to manage it.

Now we just need to add some tests and we can start sharing this PR around a bit more for reviews

contracts/FungibleTokenMetadataViews.cdc Show resolved Hide resolved
contracts/FungibleTokenMetadataViews.cdc Outdated Show resolved Hide resolved
contracts/FungibleTokenMetadataViews.cdc Outdated Show resolved Hide resolved
contracts/FungibleTokenMetadataViews.cdc Outdated Show resolved Hide resolved
contracts/FungibleTokenMetadataViews.cdc Outdated Show resolved Hide resolved
bannerImage: MetadataViews.Media,
socials: {String: MetadataViews.ExternalURL}
) {
self.name = name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the token symbol?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanna discuss over the FLIP on the forum about the fields of this FTDisplay, the symbol is a really good catch, and I also would like to discuss which images we really do need for the FTs, I'm not sure at all that we need a square and a banner Image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please mention the flip here

@franklywatson franklywatson removed the SC-Eng Issues that we want to see surfaced in SC-Eng ZH Board label Sep 7, 2022
@boczeratul
Copy link

I love where this is heading!

From Blocto's perspective, it would be useful to include 2 different kinds of logos in FTDisplay:

  • One as png/jpg image, which is the colored version of the logo
  • One as vector like svg. Since FT logos can appear in multiple places and may need to be changed to different colors depending on the context it's used

@alilloig
Copy link
Contributor Author

alilloig commented Sep 15, 2022

Hi @boczeratul! It's such an honour that you like this proposal.

What do you think if we turn pub let logo: MetadataViews.Media into pub let logos: MetadataViews.Medias so we can store any amount of different logo formats?

Just for context

    pub struct Medias {

        /// An arbitrary-sized list for any number of Media items
        pub let items: [Media]

        init(_ items: [Media]) {
            self.items = items
        }
    }

@boczeratul
Copy link

Awesome 👍

/// @return An array of Types defining the implemented views. This value will be used by
/// developers to know which parameter to pass to the resolveView() method.
///
pub fun getViews(): [Type]{
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joshuahannan I've done the default implementations of the Resolver functions on this branch since it seemed to me that it belonged more to the features than to the example, does it look good?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, that looks good. The version of Cadence that you're using to test it supports default implementations and is working, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not at all, I'm on v0.39.3 of the cli, the latest distributed via brew. I thought the version supporting default implementations was not live yet. I haven't merge this changes into the example token branch which is the one that includes the tests.

Screenshot 2022-09-27 at 14 17 43 (2)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Working with v0.41.0 🎉
Screenshot 2022-10-06 at 18 49 37

Copy link
Contributor

@psiemens psiemens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic looks good! My comments are almost entirely stylistic.

contracts/FungibleToken.cdc Outdated Show resolved Hide resolved
contracts/FungibleToken.cdc Outdated Show resolved Hide resolved
contracts/FungibleTokenMetadataViews.cdc Outdated Show resolved Hide resolved
contracts/FungibleTokenMetadataViews.cdc Outdated Show resolved Hide resolved
contracts/FungibleTokenMetadataViews.cdc Outdated Show resolved Hide resolved
contracts/FungibleTokenMetadataViews.cdc Outdated Show resolved Hide resolved
@@ -0,0 +1,740 @@
import FungibleToken from "./../FungibleToken.cdc"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another nitpick, but I think the flow-nft repo stores utility contracts in contracts/utility. Feels a bit redundant to mention "contracts" again in contracts/utilityContracts

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have a pretty good point there, should we change the folder's name here and on the flow-nft repo @joshuahannan ???

contracts/FungibleTokenMetadataViews.cdc Show resolved Hide resolved
contracts/FungibleToken.cdc Outdated Show resolved Hide resolved
contracts/FungibleTokenMetadataViews.cdc Outdated Show resolved Hide resolved
@alilloig
Copy link
Contributor Author

Thanks a lot for your comments @psiemens! I love descriptive names on variables so I love the "maybeView" names, it makes the code way more readable!!

Copy link
Contributor

@psiemens psiemens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM!

@alilloig
Copy link
Contributor Author

alilloig commented Oct 5, 2022

@satyamakgec package.json now stands...

  "name": "@onflow/flow-ft",
  "version": "1.0.0",

According to the PR Template I should move the version to 2.0.0 since we are adding the new contract, am I right?

Copy link

@bjartek bjartek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, a small comment about the required restrictions of the balancer cap.

) {
pre {
receiverLinkedType.isSubtype(of: Type<&{FungibleToken.Receiver}>()): "Receiver public type must include FungibleToken.Receiver."
metadataLinkedType.isSubtype(of: Type<&{FungibleToken.Balance, MetadataViews.Resolver}>()): "Metadata public type must include FungibleToken.Balance and MetadataViews.Resolver interfaces."
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this also ensure that it is a subtype of receiver? personally I never understood why FT capabilities do not link both receiver and balance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good question. I guess that if we are making sure that a {FungibleToken.Receiver} is provided on the receiverLinkedType we don't need to check for it on the metadataLinkedType.

Also you make me thing if we really want to be checking that the providerLinkedType is also a {MetadataViews.Resolver}

@bshahid331
Copy link

Quick thought, we might want to support the TokenForwarder pattern that both DapperUtilityCoin and FlowUtilityToken use. Right now if I was resolving metadata views on these contracts I would not be able to figure out the storage path for the token forwarder is users accounts and I wont be able to use the data to write any transactions for Dapper Wallet. We would still want the core vault path to grab the main dapper vaults for Flow and DUC.

A couple potential solutions...

  1. Add it as an optional field
  2. Add a new Metadata View for forwarder tokens

Copy link
Contributor

@sisyphusSmiling sisyphusSmiling left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Just needs Go assets updated for CI to build properly

@joshuahannan
Copy link
Member

@bshahid331 can you elaborate on what you would want with a code sample? IMO these use cases are not that common and will be phased out eventually, so I don't see much reason to build them into the standard. It might make more sense for those forwarder contracts to upgrade their contracts and relink their paths so that their forwarders expose the metadata though, if that is what you want

@bshahid331
Copy link

@joshuahannan I agree, not a common use case. It can be a custom MetadataView like the TopShot ones that dapper wallet fungible tokens can support. If you look at dapper wallet transactions there is the main dapper vault path that stores all the DUC for example. Then each account has a receiver path that is essentially what you deposit DUC too. Custom use case but still DUC and FUT are the main FT's being used outside of Flow that's why I wanted to bring it up.

@joshuahannan
Copy link
Member

I have one main question. Currently in the FungibleToken contract, we have the Vault resource implementing the MetadataViews.Resolver now. This would be a breaking change to all fungible token contracts. Are we ok with that? I feel like we won't want to do any breaking changes until we do the main upgrade to the token standards as part of stable cadence.

Therefore, if we don't want to introduce a breaking change, then the only other way to include this before then would be to put the metadata views methods into one of the existing interfaces, either Receiver or Balance. Balance makes the most sense to me since it is already kind of a metadata field, but it is unfortunate that the name balance is not accurate to what it fully represents.

Does anyone have any thoughts? I'll probably just add it to Balance if nobody says anything.

@alilloig alilloig merged commit 339da75 into master Nov 29, 2022
@alilloig alilloig deleted the alilloig/ft-metadata-views branch November 29, 2022 20:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet