Giter Club home page Giter Club logo

extendable-token-azle's Introduction

EXT Standard

The extendable token standard

This token standard provides a ERC1155/multi-token-like approach with extensions that can add additional functionality based on the purpose of the token. EXT Standard allows for the following features:

  1. Multiple tokens (which can be a mix, e.g. fungible and non-fungible) within a single canister. This provides better computation/gas savings and can reduce complexities.
  2. Bulit-in transfer notifications for more streamlined usage (e.g. similar to transferAndCall).
  3. Supports both native AccountIdentifiers (64 long hex strings) and Principals. EXT integrates well with both address styles making it easier for end users to interact with.
  4. Extendable standard with a method to query a token's capabilities to aid in deciding how to communicate with it (better integration with 3rd party tools).
  5. A unique TokenIdentifier is generated for each token with a canister (e.g. cnvzt-kikor-uwiaa-aaaaa-b4aah-eaqca-aaaaa-a) which is constructed using the canister ID and the token index within the canister. The canister ID can also be used which would point to the 0 index token (perfect if you have a single token like the erc20 example)
  6. WIP: Building a new core entrypoint named exchange to incorporate exchange mechanism directly into our core token standard

Here are some of the initial extensions we are working on:

  • allowance - ERC20 like allowances
  • archive - Transaction archive
  • batch - Batch transfer/balance functions
  • common - Some common token methods (metadata, supply)
  • fee - A way to provide a standard fee
  • ledger - ICP Ledger-like interface
  • operator - Operator's for spending tokens
  • secure - Add's update calls for common queries (more secure)
  • subscribe - Provide interface for notification subscription

You can view more details here.

Please comment, submit PRs, publish your own extensions and collaborate with us to build this standard.

Examples

We have a number of examples that you can use in the examples dirextory - all of these work with the EXT interface and can be added to a supporting wallet like Stoic:

  • ERC20 - an ERC20-like standard that is very basic
  • ERC721 - as per the above, except for NFTs specifically
  • Standard - our standard single-token implementation with notifications
  • Advanced - our advanced multi-token implementation

Rationale

Tokens can be used in a wide variety of circumstances, from cryptocurrency ledgers to in-game assets and more. These tokens can serve different purposes and therefore need to allow for a wide variety of functionalities. On the other hand, 3rd party tools that need to integrate with tokens would benefit from a standardized interface.

EXT Standard promotes modular development of tokens using extensions and a common core. Token developers can developer their tokens based on their exact use case, and 3rd party developers can build tools around these tokens using the standardized interfaces.

This repo contains our core standard and a number of initial extensions. We have added a full motoko library of these modules, and have provided some examples. We are also developing a basic JS library to easily integrate EXT with your applications.

Interface Specification

The ext-core standard requires the following public entry points:

type Token = actor {
  extensions : shared query () -> async [Extension];
    
  balance: shared query (request : BalanceRequest) -> async BalanceResponse;
      
  transfer: shared (request : TransferRequest) -> async TransferResponse;
};

Types

Native ICP Ledger types

type AccountIdentifier = Text;
type SubAccount = [Nat8];

Basic support for ICP Ledger AccountIdentifiers (64 long hex addresses) and SubAccounts (an index for a Principal).

User

type User = {
  #address : AccountIdentifier;
  #principal : Principal;
}

EXT supports both native AccountIdentifiers (64 long hex addresses) and Principals. EXT contains methods to check equality and generate a hash of a User. We advise storing balances against the AccountIdentifier as a Principal can be easily converted to one (using the default 0 index).

Balance

type Balance = Nat;

Balance refers to an amount of a particular TokenIdentifier. For the cases of non-fungible tokens, this would be 0 or 1.

TokenIdentifier

// \x0Atid" + canisterId + 32 bit index
type TokenIdentifier  = Text;

The TokenIdentifier is a unique id for a particular token and reflects the canister where the token exists as well as the index within the tokens container. The TokenIdentifier is similar to a Principal and is a representation of the canister's ID, the index of the token within the canister, and a domain seperator.

TokenIndex

type TokenIndex = Nat32;

This allows for 2**32 unique tokens within a single canister (over 4 billion). This represents an individual token's index within a given canister.

Extension

type Extension = Text;

Extensions are simply text fields, e.g. "batch", "common" and "archive".

Memo

type Memo : Blob;

Represents a "payment" memo/data which can be attached to a transaction. We hope that we can utilize native serialization/deserialization to allow for more advanced data to be stored in this way.

NotifyService

type NotifyCallback = shared (TokenIdentifier, User, Balance, Memo) -> async ?Balance;
type NotifyService = actor { tokenTransferNotification : NotifyCallback) -> async ?Balance)};
//e.g. (tokenId, from, amount, memo)

This is the public call that a canister must contain to receive a transfer notification. The amount returned is the balance actually accepted. If a transaction request has notify set to true but the receiver does not have the correct NotifyCallback then the tx is cancelled.

Common Error

type CommonError = {
  #InvalidToken: TokenIdentifier;
  #Other : Text;
};

The above represents a common error which can be returned.

Entry Points

extensions (query)

extensions : shared query () -> async [Extension];

Public query that returns an array of Extensions that the canister supports.

balance (query)

type BalanceRequest = { 
  user : User; 
  token: TokenIdentifier;
};
type BalanceResponse = Result<Balance, CommonError>;

balance: shared query (request : BalanceRequest) -> async BalanceResponse;

Public query that returns the Balance of a requested User, otherwise an error if it fails.

transfer

type TransferRequest = {
  from : User;
  to : User;
  token : TokenIdentifier;
  amount : Balance;
  memo : ?Memo;
  notify : ?Bool;
  subaccount : ?SubAccount;
};
type TransferResponse = Result<Balance, {
  #Unauthorized: AccountIdentifier;
  #InsufficientBalance;
  #Rejected; //Rejected by canister
  #InvalidToken: TokenIdentifier;
  #CannotNotify: AccountIdentifier;
  #Other : Text;
}>;

transfer: shared (request : TransferRequest) -> async TransferResponse;

This function attempts to transfer an amount of token between two users, from and to, with an optional memo (which is additional data specific to the transaction).

If notify is true, the canister will attempt to notify the recipient of the transaction (for which a response must be returned). This gives the recipient the power to reject a transaction if they wish. The recipient can also choose to only accept a partial transfer of tokens. Any rejected tokens are refunded to the sender.

extendable-token-azle's People

Contributors

stephenandrews avatar lastmjs avatar

Stargazers

 avatar Fer Martinez avatar  avatar Lucid avatar

Watchers

James Cloos avatar  avatar

Forkers

fury02

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.