Hi @cryptoschindler!
Thanks a lot for your thorough review that gave us very valuable feedback! Here’s a response to your points, some of them have been resolved, others still need decisions in the group, see my open points concluding the post.
- should we add an entry to the metadata that enumerates the generic errors by a specific implementation? together with a specific endpoint to query for them?
Do we already have generic errors defined by now? Don’t think so. If so, it would make sense.
- should we have endpoint for single token queries? e.g.
icrc7_get_approval
I thought the idea was to have just batch methods.
The only difference in usage when using the non-batch methods would then be to not require the vector for the token_ids, but a single argument. The opt parameters for pagination can be left out. Considering this, they are not really necessary.
Implementation wise it would not be a big thing to add those methods.
Thoughts?
- transaction deduplication section mentions ICRC1
Good catch! Changed to ICRC-7.
- icrc7_collection_metadata
- seems cumbersome, try assembling ICRC7 suggested fields
- why not follow cap and have (Text,Value) tuple or vec record { text; Value } at the top level
- do we need to prefix suggested metadata fields with icrc7 as well?
Changed to vec record { text; Value } which was my intention following the discussion, but must have missed this change originally.
We should use the same namespacing mechanism as defined for ICRC-1 metadata and use the icrc7 namespace in analogy.
- icrc7_token_metadata
- doesnt specify Metadata type
- what is the behaviour if token id does not exist? will it just not be in the response or will there be an explicit error?
- should this be compliant with behaviour of icrc7_owner, meaning return a Result
This was a remainder when we have the Metadata type.
Switched to Value.
For a non-existing token id we have the following options:
- Return no value
null value for metadata; this requires to make the metadata optional
- Return an error (like for some other queries)
We should align the behaviour for all relevant interfaces. We had errors contained in the queries using a variant, but then removed them as the API was rather convoluted. That’s an important point to address.
- icrc7_owner_of
- says null is returned if token doesnt exist, but lists variant with Err case that contains NonExistingTokenId
Like above, we should consolidate the error handling for queries.
- icrc7_balance_of
- why not 0 instead of null
null gives the caller more information, namely that the token does not exist. But 0 would be appropriate as well.
- icrc7_tokens & icrc7_tokens_of
- should we add default value for take to metadata and create own method to query? like for batch size and approvals?
Yes, it’s there now.
- icrc7_approve_tokens
- multiple approvals can exist for the same
token_id but different spender s and subaccount
- ^ what does this mean? different spender already suggest difference subaccount?
- emphasize that spender subaccount is arbitrary as we only check principal when actual transfer happens
- what error do we throw if the token id doesn’t exist?
- in what case do we throw
TemporarilyUnavailable?
expires_at semantic should be explained
Made the subaccount aspect clearer and changed it to from_subaccounts.
We also check subaccount, not just principal.
Error handling should be unified for all query methods.
- icrc7_approve_collection
- text seems wrong, duplicate response text
- candid method has the wrong name, candid types are missing
Thanks, copy-paste error. Text is fixed.
The method uses the same Candid type as another one where the type is defined. I wondered whether we should repeat the types, but that may lead to inconsistencies, thus may not be the best idea. Maybe refer to where the type is defined. What’s your opinion?
- icrc7_transfer
- here we say if the token doesn’t exist, we throw
Unauthorized. should this be adapted to the above methods where i raised the issue?
- do we need deduplication? if the token id is transfered, calling transfer should already throw
Unauthorized 
- we should add the
created_at_time hint for the approve methods as well
Yes, we need to unify the error responses for all applicable methods.
Deduplication: Very good question. Reading your thoughts and rethinking this, I think we might not strictly need it because of the non-fungibility of tokens. However, it is something that may still make some things nicer: E.g., a double-submitted approve does not create two blocks, but only one.
- icrc7_revoke_token_approvals
- mention that only owner can revoke approvals
- mention what happens when token does not exist
- why is spender
opt?
Mentioned, good point.
The opt is intended to revoke approvals for the respective token for all spenders (and subaccounts) in case left empty.
In that case, we can ask the question whether we can remove the icrc7_revoke_all_token_approvals method probably as it is covered by this one. It adds the removal of all approvals for all tokens, however, which this cannot do. Removed it is the value is diminished.
- icrc7_revoke_collection_approvals
- why does this return a vector? should be analaogue to
approve_collection, so either add it there as well or remove for both
- should be called
icrc7_revoke_collection_approval instead of approvals
- candid types are missing
The method can revoke multiple approvals in case the opt parameters are not provided. Thus, the name is fine. The signature has been fixed, but is still a vector: Each revoked approval is reflected as one response in the vector. Does that make sense to you?
- icrc7_revoke_all_collection_approvals
- this should either contain more information in the return type, so that it is clear to which collection wide approval the response belongs (e.g. via
from_subaccount and spender) or fail/succeed atomically and only return one result instead of a vector
Both revoke_all methods have been removed as they are handled with the opt parameters in the other revoke methods.
- icrc7_is_approved
- typo in
ac
Fixed.
Overall, the main open points now are the following:
- Error handling for query calls needs to be made consistent
- Error variant with an error type per query or a generic error type for all queries could make sense if people think this adds value. It complicates the API, though, compared to the current one.
- How to handle non-existing tokens consistently
TemporarilyUnavailable: Do we need this or can we remove it from the standard?
- Using
icrc1 namespace for existing metadata fields defined in ICRC-1?