Potentially problematic `*_nft_*` function naming
The names of these recently added functions:
has_any_nft(self: Value, policy: PolicyId) -> Bool
has_any_nft_strict(self: Value, policy: PolicyId) -> Bool
has_nft(self: Value, policy: PolicyId, asset_name: AssetName) -> Bool
has_nft_strict(self: Value, policy: PolicyId, asset_name: AssetName) -> Bool
Implicitly assume tokens that are unique at the UTxO level are also unique at the blockchain level.
This could be problematic or confusing for inexperienced Cardano developers and for experienced devs who could use it to check for fungible tokens that should be unique per UTxO.
Would it be ok to rename them to something like this (and update the docs)?:
has_any_unique(self: Value, policy: PolicyId) -> Bool
has_any_unique_strict(self: Value, policy: PolicyId) -> Bool
has_unique(self: Value, policy: PolicyId, asset_name: AssetName) -> Bool
has_unique_strict(self: Value, policy: PolicyId, asset_name: AssetName) -> Bool
I believe those names have the same problem: being unique is an extrinsic property; it cannot be determined without context.
In both cases though, the context is rather clear: it's the given value.
I agree that the user should know/infer there's no way to guarantee it's an NFT. However, even if the proposed names could be better, they don't have the same problem:
With these functions, we can guarantee that a specific token is unique in the Value. And with the proposed names, we don't claim anything else on top of that. has_unique doesn't say anything about the context, but has_nft does imply that the context is the blockchain, even though it's not accessible by the function.
On top of that, it would be weird to write code like this one, where we are clearly not checking for NFTs:
// Get all generated dex orders (each buy/sell order needs to have a single "order" fungible token in its value)
let orders =
list.filter(
self.outputs,
fn(o) {
and {
assets.has_nft(o.value, "dex_policy", "order_token_name"),
o.address == orders_addr,
}
},
)
VS:
// Get all generated dex orders (each buy/sell order needs to have a single "order" fungible token in its value)
let orders =
list.filter(
self.outputs,
fn(o) {
and {
assets.has_unique(o.value, "dex_policy", "order_token_name"),
o.address == orders_addr,
}
},
)
It's a silly example, but I hope it gets my point across.