These are all great thoughts. I’ll add a few to the mix:
Re: Subscribe - Please don’t call it subscribe! Use notify. We will soon want to support subscriptions(the ability to take a certain amount of tokens every (x) time period and it will get really confusing. see Subscription Services on the Blockchain: ERC-948 | ConsenSys
Re: Notify(instead of subscribe) - This is a great solution in as much as a canister can notify another canister with some metadata, it may be nice to be able to return something more than a true/false.
Re: OpenCan - I’ve seen @dostro pushing us over there a good bit. Perhaps if you gave some instructions, best practices, rollout plan, etc. Right now it just looks like a github site that you translate into a static site and push to the IC? Are we supposed to just use the github issue features? Who controls the github site? How does publishing work? This forum gets a good bit of attention and a lot of people are directed here. It has some great community and notification features. I’m all for moving onto an IC based system or documenting our findings on OpenCan, but until it has the features that we have here it may not be time yet.
Finally, I’ll propose that we don’t really need giant standards. Little pieces of candid interface seem to work well. We could add a meta layer on top as well.
Given the following type:
//this is the DIPs type file
module {
type Meta = actor{
dip_supports: query (dip_feature: Text) -> async Bool;
}
type MetaData = [byte];
type Payment_Notifiable = actor{
notify_of_payment: (amount: Nat, metadata: ?MetaData) -> async ?Payment_Notifiable_Response;
}
type Payment_Notifiable_Response = ?MetaData
}
Then you can do something like the following
public shared(msg) func transfer(recipient : Principal, amount : Nat) : async Bool {
//handle transaction stuff
//....
let metaActor : DIP.Meta = actor.fromPrincipal(recipient);
//figure out if the principal is a subscriber
let bWantsNotification : Bool = wantsNotification(principal);
if(bWantsNotification and metaActor.dip_supports('DIP_Payment_Notifiable') == true){
let notifiable : DIP.Payment_Notifiable = actor.fromPrincipal(recipient);
let response: DIP.Payment_Notifiable_Response = notifiable.notify_of_payment(amount, metadata);
//do something with the response
};
}
The canister requesting notification will need a “dip_supports” function that returns true for the string “DIP_Payment_Notifiable”. I think you’d generally want to say that this should not be a dynamic set of supports, but hardcoded into your canister.