DIP721 - An Internet Computer Non-fungible Token Standard

Related tags

Cryptography DIP721
Overview

Group 5982

DIP721 - Introduction

DIP721 is an ERC-721 style non-fungible token standard built mirroring its Ethereum counterpart and adapting it to the Internet Computer, maintaining the same interface.

This standard aims to adopt the EIP-721 to the Internet Computer; providing a simple, non-ambiguous, extendable API for the transfer and tracking ownership of NFTs and expanding/building upon the EXT standard with partial compatibility.

Important: This is an an in-development standard, consider it a work in progress as we finalize details in its design and gather feedback from the community.

Contributing

We'd like to collaborate with the community to provide better token standard implementation for the developers on the IC, if you have some ideas you'd like to discuss, submit an issue, if you want to improve the code or you made a different implementation, make a pull request!

Motivation

DIP-721 tries to improve on existing Internet Computer standards in the following ways:

  • Most NFT projects don't require a multi-token standard, and a simple NFT standard like DIP-721 would suffice. Users of NFTs based on multi-token standards (such as EXT) will be required to pay extra cycle cost compared to DIP-721.
  • Most NFT projects don't require the generalization of IC Principals into Ledger Accounts, and avoiding that direction can help reduce the complexity of the API.
  • Most current NFT standards on the IC don't yet have proper metadata support for NFTs.
  • The ability to track the history of NFT transfers is an important requirement of almost every NFT projects, and it should be a core part of the standard.
  • Most NFT projects don't require arbitrarily large token balances, and that can lead to more cycle inefficient implementations.
  • DIP-721 closely follows the original EIP-721, and that will make porting existing Ethereum contracts onto the IC more straightforward.
  • NFTs projects that choose to implement DIP-721, will be able to implement other NFT token standards without worrying about interface function name collision. This is achieved by DIP-721 postfixing all its interface methods with DIP721.

Interface specification

Basic interface

Every DIP-721 compatible smart contract must implement this interface. All other interfaces are optional. For all interface methods trapping (instead of returning an error) is allowed, but not encouraged.

balanceOfDip721

Count of all NFTs assigned to user.

balanceOfDip721: (user: principal) -> (nat64) query;

ownerOfDip721

Returns the owner of the NFT associated with token_id. Returns ApiError.InvalidTokenId, if the token id is invalid.

ownerOfDip721: (token_id: nat64) -> (OwnerResult) query;

safeTransferFromDip721

Safely transfers token_id token from user from to user to. If to is zero, then ApiError.ZeroAddress should be returned. If the caller is neither the owner, nor an approved operator, nor someone approved with the approveDip721 function, then ApiError.Unauthorized should be returned. If token_id is not valid, then ApiError.InvalidTokenId is returned.

safeTransferFromDip721: (from: principal, to: principal, token_id: nat64) -> (TxReceipt);

transferFromDip721

Identical to safeTransferFromDip721 except that this function doesn't check whether the to is a zero address or not.

transferFromDip721: (from: principal, to: principal, token_id: nat64) -> (TxReceipt);

supportedInterfacesDip721

Returns the interfaces supported by this smart contract.

supportedInterfacesDip721: () -> (vec InterfaceId) query;
logoDip721

Returns the logo of the NFT contract.

logoDip721: () -> (LogoResult) query;
nameDip721

Returns the name of the NFT contract.

nameDip721: () -> (text) query;
symbolDip721

Returns the symbol of the NFT contract.

symbolDip721: () -> (text) query;
totalSupplyDip721

Returns the total current supply of NFT tokens. NFTs that are minted and later burned explictely or sent to the zero address should also count towards totalSupply.

totalSupplyDip721: () -> (nat64) query;
getMetadataDip721

Returns the metadata for token_id. Returns ApiError.InvalidTokenId, if the token_id is invalid.

getMetadataDip721: (token_id: nat64) -> MetadataResult query;
getMetadataForUserDip721

Returns all the metadata for the coins user owns.

getMetadataForUserDip721: (user: principal) -> (vec ExtendedMetadataResult);

Transfer notification interface

This interface add notification feature for NFT transfers. Implementing this interface might open up other smart contracts to re-entrancy attacks.

safeTransferFromNotifyDip721

Same as safeTransferFromDip721, but to is treated as a smart contract that implements the Notification interface. Upon successful transfer onDIP721Received is called with data.

safeTransferFromNotifyDip721: (from: principal, to: principal, token_id: nat64, data: vec nat8) -> (TxReceipt);

transferFromNotifyDip721

Same as transferFromDip721, but to is treated as a smart contract that implements the Notification interface. Upon successful transfer onDIP721Received is called with data.

transferFromNotifyDip721: (from: principal, to: principal, token_id: nat64, data: vec nat8) -> (TxReceipt);

Approval interface

This interface adds approve functionality to DIP-721 tokens.

approveDip721

Change or reaffirm the approved address for an NFT. The zero address indicates there is no approved address. Only one user can be approved at a time to manage token_id. Approvals given by the approveDip721 function are independent from approvals given by the setApprovalForAllDip721. Returns ApiError.InvalidTokenId, if the token_id is not valid. Returns ApiError.Unauthorized in case the caller neither owns token_id nor he is an operator approved by a call to the setApprovalForAll function.

approveDip721: (user: principal, nat64: token_id) -> (TxReceipt) query;

setApprovalForAllDip721

Enable or disable an operator to manage all of the tokens for the caller of this function. Multiple operators can be given permission at the same time. Approvals granted by the approveDip721 function are independent from the approvals granted by setApprovalForAll function. The zero address indicates there are no approved operators.

setApprovalForAllDip721: (operator: principal, isApproved: bool) -> (TxReceipt);

getApprovedDip721

Returns the approved user for token_id. Returns ApiError.InvalidTokenId if the token_id is invalid.

getApprovedDip721: (token_id: nat64) -> (TxReceipt) query;

isApprovedForAllDip721

Returns true if the given operator is an approved operator for all the tokens owned by the caller, returns false otherwise.

isApprovedForAllDip721: (operator: principal) -> (bool) query;

Mint interface

This interface adds mint functionality to DIP-721 tokens.

mintDip721

Mint an NFT for principal to. The parameter blobContent is non zero, if the NFT contract embeds the NFTs in the smart contract. Implementations are encouraged to only allow minting by the owner of the smart contract. Returns ApiError.Unauthorized, if the caller doesn't have the permission to mint the NFT.

mintDip721: (to: principal, metadata: Metadata, blobContent: blob) -> (MintReceipt);

Burn interface

This interface adds burn functionality to DIP-721 tokens.

burnDip721

Burn an NFT identified by token_id. Implementations are encouraged to only allow burning by the owner of the token_id. Returns ApiError.Unauthorized, if the caller doesn't have the permission to burn the NFT. Returns ApiError.InvalidTokenId, if the provided token_id doesn't exist.

burnDip721: (token_id: nat64) -> (TxReceipt);

Notification interface

transferFromNotifyDip721 and safeTransferFromNotifyDip721 functions can - upon successfull NFT transfer - notify other smart contracts that adhere to the following interface.

caller is the entity that called the transferFromNotifyDip721 or safeTransferFromNotifyDip721 function, and from is the previous owner of the NFT.

onDIP721Received: (address caller, address from, uint256 token_id, bytes data) -> ();

Datastructure specification

OwnerResult

type ApiError =
 variant {
   Unauthorized;
   InvalidTokenId;
   ZeroAddress;
   Other;
 };
type OwnerResult =
variant {
   Err: ApiError;
   Ok: Principal;
 };

TxReceipt

type TxReceipt =
variant {
   Err: ApiError;
   Ok: nat;
 };

InterfaceId

type InterfaceId =
 variant {
   Approval;
   TransactionHistory;
   Mint;
   Burn;
   TransferNotification;
 };

LogoResult

type LogoResult =
 record {
   logo_type: text // MIME type of the logo
   data: text // Base64 encoded logo
 };
 type ExtendedMetadataResult =
 record {
     metadata_desc: MetadataDesc;
     token_id: nat64;
 };

MetadataResult

type MetadataResult =
 variant {
   Err: ApiError;
   Ok: MetadataDesc;
 };
type MetadataDesc = vec MetadataPart;
type MetadataPart =
 record {
   purpose: MetadataPurpose;
   key_val_data: vec MetadataKeyVal;
   data: blob;
 };
type MetadataPurpose =
 variant {
   Preview; // used as a preview, can be used as preivew in a wallet
   Rendered; // used as a detailed version of the NFT
 };
type MetadataKeyVal =
 record {
   text;
   MetadataVal;
 };
type MetadataVal =
 variant {
   TextContent : Text;
   BlobContent : blob;
   NatContent : Nat;
   Nat8Content: Nat8;
   Nat16Content: Nat16;
   Nat32Content: Nat32;
   Nat64Content: Nat64;
  };

Predefined key value pairs

content hash

Uniquely identifies the content of the NFT by its hash fingerprint. This field might be missing unless the NFT is stored on the Web, in which case the content hash is mandatory.

{"contentHash", BlobContent(<hash of the content>)}
contentType
{"contentType", TextContent(<MIME type of the NFT>)}
locationType
{"locationType", Nat8Content(<type of the location>)}

1 - IPFS storage
2 - Asset canister storage
3 - URI(Web) storage
4 - Embedded in the token contract
location
{"location", any(<location>)}

// where any(<location>) is one of the followings based on the "locationType"

BlobContent(<IPFS location hash>) - IPFS
TextContent(<PrincipalId of the asset canister>) - Asset canister
TextContent(<URI of the NFT location on the Web>) - URI
location field is missing - Embedded in the token contract

TxResult

type TxResult =
 record {
     fee: Nat;
     transaction_type: TransactionType;
 };

type TransactionType =
 variant {
     Transfer:
      record {
          token_id: nat64;
          from: principal;
          to: principal;
      };
     TransferFrom:
      record {
          token_id: nat64;
          from: principal;
          to: principal;
      };
      Approve:
       record {
          token_id: nat64;
          from: principal;
          to: principal;
       };
      SetApprovalForAll:
       record {
          from: principal;
          to: principal;
       };
      Mint:
       record {
          token_id: nat64;
       };
      Burn:
       record {
          token_id: nat64;
       };
 };

MintReceipt

type MintReceipt =
 variant {
   Err: variant {
          Unauthorized;
        };
   Ok: record {
          token_id: nat64; // minted token id
          id: nat // transaction id
       };
 };

BurnRequest

type BurnRequest =
 record {
     token_id: nat64;
 }

Fees

Implementations are encouraged not to charge any fees when an approved entity transfers NFTs on the user's behalf, as that entity might have no means for payment. If any fees needs to be taken for such a transferFromDip721, safeTransferFromDip721, transferFromNotifyDip721, safeTransferFromNotifyDip721 call, then it is encouraged to be taken during the call to approveDip721, setApprovalForAllDip721 from the caller's balance.

Comments
  • Please add back DIP721 Namespace in v2

    Please add back DIP721 Namespace in v2

    We have a significant amount of work done that relies on the standard being namespace. We really want to support the standard and having namespace enables us to do so without having to choose between supporting both EXT and DIP721. We are working on a superset that theoretically supports both standards as well as adding significant functionality.

    opened by skilesare 4
  • chore: 🤖 adds deploy script

    chore: 🤖 adds deploy script

    Why?

    Using icx heavily overcomplicates the scripts and requires users to build an extra tool. It also did not work on the public ic mainnet.

    Demo

    ./healthcheck.sh

    ./deploy.sh local

    wip 
    opened by ozwaldorf 4
  • feat: cap transaction history

    feat: cap transaction history

    Why?

    Adds cap transaction history

    How?

    • [x] Utilize the new cap-sdk insert_sync and archive/from_archive, which guarantees the finality and order of transactions. In the background, the sdk stores a buffer of failed insertions and flushes the buffer using the new batch insertion method
    • [x] upgrade cap submodule
    • [x] deploy cap if CAP_ID is not set
    • [x] init canister with CAP_ID
    • [x] integrate cap-js with the tests to restore txn testing

    Contribution checklist?

    • [x] The commit messages are detailed
    • [x] It does not break existing features (unless required)
    • [x] I have performed a self-review of my own code
    • [x] Documentation has been updated to reflect the changes
    • [x] Tests have been added or updated to reflect the changes
    • [x] All code formatting pass
    • [x] All lints pass
    • [x] All tests pass

    Security checklist?

    • [x] Injection has been prevented (parameterized queries, no eval or system calls)
    • [x] Sensitive data has been identified and is being protected properly
    opened by ozwaldorf 3
  • feat: totalTransactions

    feat: totalTransactions

    Why?

    feat: totalTransactions.

    ⚠️ Should wait for https://github.com/Psychedelic/DIP721/pull/45 to get integrated first

    How?

    • feat: totalTransactions

    Tickets?

    • N/A

    Contribution checklist?

    • [x] The commit messages are detailed
    • [x] It does not break existing features (unless required)
    • [x] I have performed a self-review of my own code
    • [x] Documentation has been updated to reflect the changes
    • [x] Tests have been added or updated to reflect the changes
    • [x] All code formatting pass
    • [x] All lints pass
    • [x] All tests pass

    Security checklist?

    • [x] Injection has been prevented (parameterized queries, no eval or system calls)
    • [x] Sensitive data has been identified and is being protected properly

    Demo?

    Optionally, provide any screenshot, gif or small video.

    opened by scott-dn 2
  • refactor: 💡 home prefix, split deploy nft and controllers

    refactor: 💡 home prefix, split deploy nft and controllers

    Why?

    The prefix should only affect the exec context and not override and the deploy should explicitly show to the user the initial owner

    How?

    • Changes prefix for dfx commands
    opened by heldrida 1
  • feat: move to namespace and snake case methods

    feat: move to namespace and snake case methods

    Why?

    #64

    How?

    • namespace and snakecase methods, remove renames
    • update tests

    Contribution checklist?

    • [x] The commit messages are detailed
    • [ ] It does not break existing features (unless required)
    • [x] I have performed a self-review of my own code
    • [ ] Documentation has been updated to reflect the changes
    • [x] Tests have been added or updated to reflect the changes
    • [x] All code formatting pass
    • [x] All lints pass
    • [x] All tests pass

    Security checklist?

    • [x] Injection has been prevented (parameterized queries, no eval or system calls)
    • [x] Sensitive data has been identified and is being protected properly

    Demo?

    image

    opened by ozwaldorf 0
  • feat: cover metadata

    feat: cover metadata

    Why?

    add COVER metadata.

    How?

    • add COVER metadata.

    Tickets?

    • N/A

    Contribution checklist?

    • [x] The commit messages are detailed
    • [x] It does not break existing features (unless required)
    • [x] I have performed a self-review of my own code
    • [x] Documentation has been updated to reflect the changes
    • [x] Tests have been added or updated to reflect the changes
    • [x] All code formatting pass
    • [x] All lints pass
    • [x] All tests pass

    Security checklist?

    • [ ] Injection has been prevented (parameterized queries, no eval or system calls)
    • [ ] Sensitive data has been identified and is being protected properly

    Demo?

    Optionally, provide any screenshot, gif or small video.

    opened by scott-dn 0
  • chore: refactor

    chore: refactor

    Why?

    refactor.

    How?

    • refactor

    Tickets?

    • N/A

    Contribution checklist?

    • [x] The commit messages are detailed
    • [x] It does not break existing features (unless required)
    • [x] I have performed a self-review of my own code
    • [x] Documentation has been updated to reflect the changes
    • [x] Tests have been added or updated to reflect the changes
    • [x] All code formatting pass
    • [x] All lints pass
    • [x] All tests pass

    Security checklist?

    • [ ] Injection has been prevented (parameterized queries, no eval or system calls)
    • [ ] Sensitive data has been identified and is being protected properly

    Demo?

    Optionally, provide any screenshot, gif or small video.

    opened by scott-dn 0
  • chore: update ic-cdk version to 0.5.0

    chore: update ic-cdk version to 0.5.0

    Why?

    update ic-cdk version to 0.5.0.

    How?

    • N/A

    Tickets?

    • N/A

    Contribution checklist?

    • [x] The commit messages are detailed
    • [x] It does not break existing features (unless required)
    • [x] I have performed a self-review of my own code
    • [x] Documentation has been updated to reflect the changes
    • [x] Tests have been added or updated to reflect the changes
    • [x] All code formatting pass
    • [x] All lints pass
    • [x] All tests pass

    Security checklist?

    • [ ] Injection has been prevented (parameterized queries, no eval or system calls)
    • [ ] Sensitive data has been identified and is being protected properly

    Demo?

    Optionally, provide any screenshot, gif or small video.

    opened by scott-dn 0
  • chore: general improve

    chore: general improve

    Why?

    How?

    • zero-copy & alloc Principal
    • remove ambiguous Unauthorized error
      • UnauthorizedOwner
      • UnauthorizedOperator
    • chore: fix makefile, update unit test...
    • stats api
    • restructure code block
    • support f64

    Tickets?

    • N/A

    Contribution checklist?

    • [x] The commit messages are detailed
    • [x] It does not break existing features (unless required)
    • [x] I have performed a self-review of my own code
    • [x] Documentation has been updated to reflect the changes
    • [x] Tests have been added or updated to reflect the changes
    • [x] All code formatting pass
    • [x] All lints pass
    • [x] All tests pass

    Security checklist?

    • [x] Injection has been prevented (parameterized queries, no eval or system calls)
    • [x] Sensitive data has been identified and is being protected properly

    Demo?

    Optionally, provide any screenshot, gif or small video.

    opened by scott-dn 0
  • chore: refactor

    chore: refactor

    Why?

    refactor and experiment

    How?

    • using ManualReply
    • add approved_at and approved_by
    • ledger modular
    • token_ids => token_identifiers

    Tickets?

    • N/A

    Contribution checklist?

    • [x] The commit messages are detailed
    • [x] It does not break existing features (unless required)
    • [x] I have performed a self-review of my own code
    • [x] Documentation has been updated to reflect the changes
    • [x] Tests have been added or updated to reflect the changes
    • [x] All code formatting pass
    • [x] All lints pass
    • [x] All tests pass

    Security checklist?

    • [x] Injection has been prevented (parameterized queries, no eval or system calls)
    • [x] Sensitive data has been identified and is being protected properly

    Demo?

    Optionally, provide any screenshot, gif or small video.

    opened by scott-dn 0
  • Revise dip721v2

    Revise dip721v2

    • Namespace + Snake Case

      fn dip721_metadata()
      fn dip721_token_metadata()
      fn dip721_balance_of()
      fn dip721_transfer()
      fn dip721_transfer_from()
      fn dip721_owner_token_ids()
      fn dip721_owner_token_metadata()
      fn dip721_operator_token_ids()
      
    opened by ozwaldorf 1
  • docs: (spec) private property prefix, remove data blob

    docs: (spec) private property prefix, remove data blob

    Why?

    Based on some feedback from the community (cc @jorgenbuilder ), there is a need for specifying if a given key value should be displayed in frontends (eg; plug wallet's trait chips).

    This also removes the requirement of the data blob, as storing large amounts of data in the meta is not recommended, due to the IC's 2MB message limit.

    How?

    Adds the _ prefix for private properties to the spec

    Removed reserved property data

    Tickets?

    n.a

    Contribution checklist?

    • [ ] The commit messages are detailed
    • [ ] It does not break existing features (unless required)
    • [ ] I have performed a self-review of my own code
    • [ ] Documentation has been updated to reflect the changes
    • [ ] Tests have been added or updated to reflect the changes
    • [ ] All code formatting pass
    • [ ] All lints pass
    • [ ] All tests pass

    Security checklist?

    n.a

    Demo?

    n.a

    opened by ozwaldorf 2
  • Add `Transfer` to `SupportedInterface`.

    Add `Transfer` to `SupportedInterface`.

    Every DIP-721 compatible smart contract must implement this interface. All other interfaces are optional. ~ spec.md: DIP721 v2

    The basic interface does/should not include the the transfer interface.

    Expected

    type SupportedInterface = variant {
      Transfer;
      Burn;
      Mint;
      Approval;
      TransactionHistory
    };
    

    Actual

    type SupportedInterface = variant {
      Burn;
      Mint;
      Approval;
      TransactionHistory
    };
    
    opened by di-wu 0
  • mintDIP721 - (variant {Err = variant { Unauthorized }}) and The Replica returned an error: code 5, message:

    mintDIP721 - (variant {Err = variant { Unauthorized }}) and The Replica returned an error: code 5, message: "canister xxxx-xxx-xxx-xxxx-xxxx trapped: unreachable

    Used command: dfx canister call nft mintDip721 "(principal "7fi54-4ehlq-on5si-izkkp-n3ism-wipnz-chyha-m7adi-sqjty-rwndi-xae", vec {record { purpose = variant { Preview}; key_val_data= vec { record {key="NFT 1"; val= variant {TextContent="png"}}}; data= blob"100, 97, 116,..., 103, 103, 103, 61, 61"}})"

    I tried the "approval-permissions" version : https://github.com/Psychedelic/DIP721/tree/refactor/approval-permissions

    error: "The Replica returned an error: code 5, message: "canister xxxx-xxx-xxx-xxxx-xxxx trapped: unreachable"" imagen

    opened by sakunix 0
Owner
Psychedelic
Decentralized product studio focused on building products on Web3, Ethereum, and the Internet Computer.
Psychedelic
Dank - The Internet Computer Decentralized Bank - A collection of Open Internet Services - Including the Cycles Token (XTC)

Dank - The Internet Computer Decentralized Bank Dank is a collection of Open Internet Services for users and developers on the Internet Computer. In t

Psychedelic 56 Nov 12, 2022
Bespoke toolkit for Non-fungible token (NFT) technology 🚀

Bespoke toolkit for Non-fungible token (NFT) technology ?? What is Onft? Instead of forcing a consensus algorithm or peer networking on you, Onft prov

Owez 5 Jan 9, 2022
ARYA Network is a polkadot/substrate based chain for Non-fungible Token platform on which we can own sell and buy the NFT's on polkadot network.

ARYA Network ARYA Network is a polkadot/substrate based chain for Non-fungible Token platform on which we can own sell and buy the NFT's on polkadot n

Pankaj Chaudhary 6 Dec 20, 2022
NFT & Marketplace Contracts with royalties and fungible token support. Sample React app included.

NFT Market Reference Implementation A PoC backbone for NFT Marketplaces on NEAR Protocol. Reference Changelog Changelog Progress: basic purchase of NF

NEAR App Examples 156 Apr 28, 2022
An all-in-one IBC protocol providing fungible token transfer, interchain account, and async query functionalities

ICS-999 An all-in-one IBC protocol providing fungible token transfer, interchain account (ICA), and query (ICQ) functionalities, implemented in CosmWa

larry 9 Apr 1, 2023
Metaplex is a protocol built on top of Solana that allows: Creating/Minting non-fungible tokens;

Metaplex is a protocol built on top of Solana that allows: Creating/Minting non-fungible tokens; Starting a variety of auctions for primary/secondary

Metaplex Foundation 3.2k Jan 4, 2023
All the data an IC app needs to make seamless experiences, accessible directly on the IC. DAB is an open internet service for NFT, Token, Canister, and Dapp registries.

DAB ?? Overview An Internet Computer open internet service for data. All the data an IC app needs to make a seamless experience, accessible directly o

Psychedelic 58 Oct 6, 2022
Source project for the Internet Computer software

The Internet Computer is the world’s first blockchain that runs at web speed and can increase its capacity without bound. Like the Internet (which is composed of many machines adhering to TCP/IP protocol) and blockchain protocols (such as Bitcoin and Ethereum).

DFINITY 1.2k Jan 1, 2023
Terabethia - A Bridge and Messaging Protocol between Ethereum and the Internet Computer.

Terabethia - A Bridge Between Ethereum & the Internet Computer Terabethia is a bridge between Ethereum & the Internet Computer that contracts in both

Psychedelic 36 Dec 26, 2022
A preview of the integration between Bitcoin and the Internet Computer.

Bitcoin Integration Developer Preview Overview The integration between the Internet Computer and Bitcoin will enable developers to build canisters tha

DFINITY 39 Sep 21, 2022
Rust library for build smart contracts on Internet Computer, by the Spinner.Cash team.

Spinner Rust library for building smart contracts on the Internet Computer. More specifically it is used by Spinner.Cash, a decentralized layer-2 prot

Spinner 6 May 31, 2022
A demo of the Internet Computer's Bitcoin API

Bitcoin Integration Demo A demo of the bitcoin endpoints on the Internet Computer. This demo is already deployed to the IC, so you can already try it

Islam El-Ashi 8 Jul 2, 2022
Simple PoC to issue JSON Web Tokens (JWTs) with a canister on the Internet Computer.

JWT Issuer Proof of Concept Overview Simple PoC to issue JSON Web Tokens (JWTs) with a canister on the Internet Computer. It allows the issuance of tw

Dominic Wörner 7 Oct 13, 2022
Yi Token by Crate Protocol: the primitive for auto-compounding single token staking pools.

yi Yi Token by Crate Protocol: the primitive for auto-compounding single token staking pools. About Yi is a Solana primitive for building single-sided

Crate Protocol 12 Apr 7, 2022
A contract to lock fungible tokens with a given vesting schedule including cliffs.

Fungible Token Lockup contract Features A reusable lockup contract for a select fungible token. Lockup schedule can be set as a list of checkpoints wi

null 15 Dec 16, 2022
Zcash - Internet Money

Zcash 4.3.0 What is Zcash? Zcash is an implementation of the "Zerocash" protocol. Based on Bitcoin's code, Zcash intends to offer a far higher standar

Zcash 4.7k Jan 4, 2023
Scans the Ethereum network for USDT ERC-20 token transfer transactions

ethscan This is a Rust command line program for scanning the Ethereum blockchain for USDT transfers within a time span and amount span. prerequisites

Frank Buss 4 Oct 6, 2022
Making Token Exchange program with Solana(Rust), Web3, and Vue

Escrow program for Solana blockchain Tech stack Program (Smart Contract) Rust crates: solana-program, spl-token Solana CLI for test validator UI Types

Hoon Wee 3 May 10, 2022
Create your personal token with rust smart contracts

Solana Rust Token ?? This application written Rust using Anchor ⚓

Ritesh 6 Nov 22, 2022