tuminfei / icrc7_launchpad

An example implementation of ICRC7 containing ICRC37 and ICRC3 standards.
MIT License
6 stars 2 forks source link

icrc7_launchpad

Init

ICRC7 Init args:

pub struct InitArg {
    pub minting_account: Option<Account>,
    pub icrc7_symbol: String,
    pub icrc7_name: String,
    pub icrc7_description: Option<String>,
    pub icrc7_logo: Option<String>,
    pub icrc7_supply_cap: Option<u128>,
    pub icrc7_max_query_batch_size: Option<u16>,
    pub icrc7_max_update_batch_size: Option<u16>,
    pub icrc7_max_take_value: Option<u128>,
    pub icrc7_default_take_value: Option<u128>,
    pub icrc7_max_memo_size: Option<u32>,
    pub icrc7_atomic_batch_transfers: Option<bool>,
    pub tx_window: Option<u64>,
    pub permitted_drift: Option<u64>,
    pub approval_init: Option<InitApprovalsArg>,    // ICRC37 Init args
    pub archive_init: Option<InitArchiveArg>,       // ICRC3 Init args
}

ICRC37 Init args:

type InitApprovalsArg = record {
    max_approvals : opt nat16;
    max_approvals_per_token_or_collection : opt nat16;
    settle_to_approvals : opt nat16;
    max_revoke_approvals : opt nat16;
    collection_approval_requires_token : opt bool;
}

ICRC3 Init args:

type InitArchiveArg = record {
    maxRecordsToArchive : nat;                    //Max number of archive items to archive in one round
    archiveIndexType : IndexType;                 //Index type to use for the memory of the archive
    maxArchivePages : nat;                        //Max number of pages allowed on the archivserver
    settleToRecords : nat;                        //number of records to settle to during the clean up process
    archiveCycles : nat;                          //number of cycles to sent to a new archive canister;
    maxActiveRecords : nat;                       //allowed max active records on this canister
    maxRecordsInArchiveInstance : nat;            //specify the max number of archive items to put on an archive instance
    archiveControllers : opt opt vec principal;   //override the default controllers. The canister will always add itself to this group;
}

ICIC7

ICRC-7

ICRC-7 is the minimal standard for the implementation of Non-Fungible Tokens (NFTs) on the Internet Computer.

A token ledger implementation following this standard hosts an NFT collection (collection), which is a set of NFTs.

ICRC-7 does not handle approval-related operations such as approve and transfer_from itself. Those operations are specified by ICRC-37 which extends ICRC-7 with approval semantics.

ICRC-7

ICRC-37

ICRC-37

ICRC-3

ICRC-3

Scripts

Deploying Icrc7 Canister

dfx deploy icrc7 --argument '(record{                                  
minting_account= opt record {
    owner = principal "3yyxm-t5fpe-v32em-ac6lr-xyort-wuscb-dvl4x-3wnwi-hqkyj-xortw-oqe";                                     
    subaccount = opt blob "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00";
  };                  
icrc7_supply_cap= null;
icrc7_description= opt "ICP Flower Collection";
tx_window= null;                        
permitted_drift= null;                  
icrc7_max_take_value= opt 100;
icrc7_max_memo_size= opt 1000;
icrc7_symbol= "ICFL";
icrc7_max_update_batch_size= opt 100;
icrc7_max_query_batch_size= opt 100;
icrc7_atomic_batch_transfers= null;
icrc7_default_take_value= opt 100;
icrc7_logo= null;
icrc7_name= "ICP Flower";
approval_init= null;
archive_init= null
})'
dfx deploy icrc7 --argument '(record{                                  
minting_account= opt record {
        owner = principal "3yyxm-t5fpe-v32em-ac6lr-xyort-wuscb-dvl4x-3wnwi-hqkyj-xortw-oqe";                                     
        subaccount = opt blob "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00";
    };                  
icrc7_supply_cap= null;
icrc7_description= opt "ICP Flower Collection";
tx_window= null;                        
permitted_drift= null;                  
icrc7_max_take_value= null;
icrc7_max_memo_size= null;
icrc7_symbol= "ICFL";
icrc7_max_update_batch_size= null;
icrc7_max_query_batch_size= null;
icrc7_atomic_batch_transfers= null;
icrc7_default_take_value= null;
icrc7_logo= null;
icrc7_name= "ICP Flower";
approval_init= null;
archive_init= opt record {
        maxRecordsToArchive= 2;
        archiveIndexType= variant {Stable};
        maxArchivePages= 3;
        settleToRecords= 2;
        archiveCycles= 1000000000000;
        maxActiveRecords= 4;
        maxRecordsInArchiveInstance= 4;
        archiveControllers= null
    }
})'

Minting NFT

dfx canister call icrc7 mint '(record{                                  
to= record {
    owner = principal "3yyxm-t5fpe-v32em-ac6lr-xyort-wuscb-dvl4x-3wnwi-hqkyj-xortw-oqe";                                     
    subaccount = opt blob "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00";
  };          
token_id=1;
memo= null;
from_subaccount= null;                  
token_description= opt "Token Number 1";
token_logo= null;
token_name= null
})'

Transfer NFT

dfx canister call icrc7 icrc7_transfer '(vec{
  record{
    to=record {
      owner = principal "t4egw-clf4w-qbpli-svryg-7yqq6-jt2yj-7v755-mabir-zmx6i-vp4fr-fqe";
      subaccount = opt blob "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00";
    };
    token_id= 1;
    from_subaccount= null;
    memo= null;
    created_at_time= null
  }
})'

Approve NFT

dfx canister call icrc7 icrc37_approve_tokens '(vec{ 
  record{
    token_id= 2;                               
    approval_info= record {
      memo= null;
      from_subaccount= null;
      created_at_time= null;
      expires_at= null;
      spender= record {
          owner = principal "o2zom-piy75-ifbnk-nhhlq-362su-4vsx5-ptl2s-ec4jw-osbv4-nygtw-dae";                                     
          subaccount = opt blob "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00";
      }
  }
}     
})'

dfx canister call icrc7 icrc37_approve_collection '(vec{ 
  record{
    token_id= 2;                               
    approval_info= record {
      memo= null;
      from_subaccount= null;
      created_at_time= null;
      expires_at= null;
      spender= record {
          owner = principal "o2zom-piy75-ifbnk-nhhlq-362su-4vsx5-ptl2s-ec4jw-osbv4-nygtw-dae";                                     
          subaccount = opt blob "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00";
      }
  }
}     
})'

Transfer From NFT

dfx canister call icrc7 icrc37_transfer_from '(vec{
  record{
    from= record {
        owner = principal "3yyxm-t5fpe-v32em-ac6lr-xyort-wuscb-dvl4x-3wnwi-hqkyj-xortw-oqe";                                     
        subaccount = opt blob "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00";
    };
    to= record {
        owner = principal "t4egw-clf4w-qbpli-svryg-7yqq6-jt2yj-7v755-mabir-zmx6i-vp4fr-fqe";                                     
        subaccount = opt blob "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00";
    };
    spender_subaccount= null;
    token_id= 2;
    memo= opt blob "123";
    created_at_time= null
  }
})'

Burn NFT

The implementation of the burn method does not delete the token; rather, it transfers the token to a burn_address (akin to a zero address).

dfx canister call icrc7 burn '(vec {
  record {
    token_id = 1 : nat;
    memo = opt blob "Burning token 1";
    from_subaccount = null
  }
})'