This Topic is to discuss ICRC-104.
The Issue: ICRC-104 - Rule-Based Membership Manager - ICRC-75 Expansion · Issue #104 · dfinity/ICRC · GitHub
The Draft: https://github.com/icdevsorg/icrc04.mo/blob/main/icrc104-standard.md
Reference Motoko Module: GitHub - icdevsorg/icrc104.mo: ICRC-104 for motoko. Rule-Based Membership Manager Standard
Mops: Mops • Motoko Package Manager
Sample Dapp: https://iedms-tqaaa-aaaal-amieq-cai.icp0.io/ (A ICRC-104 Rule manages the org.icdevs.lists.king_of_the_hill list, note the canister as admin)
Tips:
- Easily add handling multiple rules to manage your ICRC-75 lists through a single governance endpoint.
- You can write simulators and validators(for SNS integration) as well
- Code to add a new rule is straightforward:
public func run_validator<system>(request: ICRC104.HandleRuleEvent) : async* ICRC104.SNSValidationResponse {
if(not Set.has(init.icrc104.get_state().admins, Set.phash, request.caller)){
return #Err("caller not authorized");
};
switch(init.validator){
case(?validator){
switch(await* validator(request)){
case(#Err(response)) return #Err(response);
case(#Ok(response)) return #Ok(response);
};
};
case(null) {
return #Ok(defaultValidationMessage(request));
};
};
};
public func rule_action<system>(request: ICRC104.HandleRuleEvent, bSimulate : Bool) : async* Star.Star<ICRC104.RuleHandlerResponse,()> {
if(request.rule_namespace != init.ruleNamespace){
return #trappable(#apply(#Err(#ExecutionFailed("rule namespace mismatch"))));
};
///add rule execution code here
if(not Set.has(init.icrc104.get_state().admins, Set.phash, request.caller)){
return #trappable(#apply(#Err(#ExecutionFailed("caller not authorized"))));
};
if(bSimulate){
//handle simulation
};
var bAwaited = false;
//qualify the request
//handle the return
return if(bAwaited){
#awaited(#apply(#Ok(#LocalTrx({
metadata = if(metadata.size() > 0){
[("errors", #Text(metadata))];
}else {
[]
};
transactions = Buffer.toArray(trx);
}))))} else {
#trappable(#apply(#Ok(#LocalTrx({
metadata = if(metadata.size() > 0){
[("errors", #Text(metadata))];
}else {
[]
};
transactions = Buffer.toArray(trx);
}))));
};
};
ignore init.icrc104.add_rule_handler_listener("my_rule_namespace", replace_role, ?run_validator);
The candid function list interface:
icrc104_apply_rule : (ApplyRuleRequest) -> (ApplyRuleResult);
icrc104_simulate_rule : (ApplyRuleRequest) -> (ApplyRuleResult);
validateApplyRule : (ApplyRuleRequest) -> (SNSValidationResponse);