ICRC icon indicating copy to clipboard operation
ICRC copied to clipboard

ICRC-13: Canister Interface Detection

Open SuddenlyHazel opened this issue 2 years ago • 2 comments

icrc: 13
title: ICRC-13 Canister Interface Detection
authors: ?
discussions-to: https://github.com/dfinity/ICRC/issues/13
status: Deliberating 
category: ICRC
requires: None
supports: ICRC-12 (optional)
created: 2023-02-28
updated: 2023-02-28

Summary

A set of methods for publishing and detecting which interfaces a canister implements.

References

ERC-165

Introduction

The following is a simple ERC-165 like standard for the internet computer. This standard allows canister developers to explicitly state which standards their canisters supports. This allows integrators to programmatically negotiate how best to communicate between canisters.

Notes

  • Canisters on the IC are potentially mutable. We should discuss best practices for how to leverage this standard as an integrator.
    • A follow up standard might be created allowing canisters to declare a dependency on a canister and interface.
  • Canisters implementing this standard should not be taken at face value. It is up to the developer interfacing with a canister implementing this standard to be aware of potential attack vectors.
    • For example a canister could claim to be the ICRC-1 ICP token canister. Don't blindly index off token name.

Standard

icrc13_supports_interface

Given a text interface name like ICRC1, DLIP1v1, EXT returns a bool

icrc13_supported_interfaces

Given a text interface returns a vec text of all supported interfaces.

Candid

service : {
    icrc13_supports_interface : (text) -> (bool);
    icrc13_supported_interfaces : () -> (vec text);
}

Events

Canisters which implement this standard can choose to optionally implement the ICRC-12 events. Support is optional. However, If developers choose to implement events for ICRC-13 developers MUST implement all of the following ICRC-13 events.

type InterfaceAction = variant {
  InterfaceAdded : text;       // event_schema = "icrc13.v1.interface.added"
  InterfaceRemoved : text;  // event_schema = "icrc13.v1.interface.removed"
};

type InterfaceUpdated = record {
  updated_at : u64; // When the mutation occurred.
  action : opt; // Optional to allow for modification of types 
}

SuddenlyHazel avatar Feb 28 '23 19:02 SuddenlyHazel

A canister can expose its DID file, and ICRC-1 already supports icrc1_supported_standards. But I see how a more generic way of specifying it could be useful.

A text description of the interface may not suffice in this case, and a ERC165 interface signature is a canonical hash of all the function signatures.

benjizhai avatar Mar 01 '23 14:03 benjizhai

Another alternative might be indexing (standard_key, string(candid.did)). But, integrators would still have to write clients.

Long term I have a feeling we can come up with a significantly more powerful set of standards leveraging the candid 'func' type. Until then I see this as a stop gap.

As far as I know canisters are unable to actually introspect on their exports. So, I'm not sure we stand to gain much with the canonical hash methodology and it makes the experience less intuitive for developers. Hash vs String.

Thoughts?

SuddenlyHazel avatar Mar 01 '23 15:03 SuddenlyHazel