I am trying to integrate the ng index canister with my token that has been live for quite some time.
I have taken a look at the source code for the ng index cansiter and i “think” the only method i need to add is the icrc3_get_blocks method.
I have taken a look at doing a migration using this icrc3-mo mops package. and it looks a lot more complex than what i need.
I have taken a look at the source code for this mops package and have noticed a block looks like this:
blocks : [{ id : Nat; block : Value }];
public type Value = { #Int : Int; #Map : [(Text, Value)]; #Nat : Nat; #Blob : Blob; #Text : Text; #Array : [Value];
};
I have no idea what Value is / where it comes from. Could anyone possibly explain?
Also if anyone has motoko source code or an easier way of adding this get_blocks method that would be great. Or just any easy ways of integrating with the ng index canister
If you already have the old get_blocks set you you may want to use that indexing canister. There are two versions of the indexing canister. One for ‘old style’ SNS tokens and one for ‘ICRC3’.
If you need to add icrc3 in motoko you can just setup and include the icrc3-mo library and copy the add_records sections from icrc1/2 libraries if you don’t want to replace your icrc1 code.
In this case you pass your icrc3 object into the icrc1-mo object…you likely won’t need to be that fancy and can just call the icrc3.add_record(tx, ?top) function (tx and top are values…the tx gets inserted into the top as a “tx”, #Map(x) entry…they are separated out for deduping.
If you are trying to write ICRC3 logs then you can use the icrc3-mo package without needing icrc1-mo. If you’re just looking at converting existing blocks into icrc3 blocks, the the icrc1-mo should have some examples that directly do that when the transactions are recorded…you can just pull that code out and it should get you most of the way there.
I’m trying to remember the exact format of the get_transactions, but I think that is what @tomijaga used for his format in the original icrc1 tokens…I used that as a patter when writing these, so they should line up nicely.
Specifically this part:
/// `transfer_req_to_value`
///
/// Converts a transaction request into a `Value` type that can be processed by an ICRC-3 transaction log.
///
/// Parameters:
/// - `request`: The transaction request to convert.
///
/// Returns:
/// - `Value`: The transaction request converted to a `Value` type suitable for logs.
public func transfer_req_to_value(request: TransactionRequest) : Value {
let trx = Vec.new<(Text, Value)>();
Vec.add(trx, ("amt",#Nat(request.amount)));
switch(request.kind){
case(#mint) {
Vec.add(trx, ("op",#Text("mint")));
Vec.add(trx, ("to", Utils.accountToValue(request.to)));
};
case(#burn){
Vec.add(trx, ("op",#Text("burn")));
Vec.add(trx, ("from", Utils.accountToValue(request.from)));
};
case(#transfer){
Vec.add(trx, ("op",#Text("xfer")));
Vec.add(trx, ("to", Utils.accountToValue(request.to)));
Vec.add(trx, ("from", Utils.accountToValue(request.from)));
};
};
switch(request.fee){
case(null){
};
case(?val){
Vec.add(trx, ("fee", #Nat(val)));
};
};
switch(request.created_at_time){
case(null){
};
case(?val){
Vec.add(trx, ("ts", #Nat(Nat64.toNat(val))));
};
};
switch(request.memo){
case(null){
};
case(?val){
Vec.add(trx, ("memo", #Blob(val)));
};
};
let vTrx = #Map(Vec.toArray(trx));
return vTrx
};