Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

icrc2 #10

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"defaults": {
"build": {
"packtool": "mops sources",
"packtool": "vessel sources",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, mops is the preferred manager because of its ability to host packages that can be easily retrieved without the added effort of setting up complex package sets.

We would lose all these benefits if we switch back to vessel.

"args": ""
}
}
Expand Down
16 changes: 12 additions & 4 deletions example/icrc1/main.mo
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,23 @@ shared ({ caller = _owner }) actor class Token(
};

public shared ({ caller }) func icrc1_transfer(args : ICRC1.TransferArgs) : async ICRC1.TransferResult {
await ICRC1.transfer(token, args, caller);
await* ICRC1.transfer(token, args, caller);
};

public shared ({ caller }) func mint(args : ICRC1.Mint) : async ICRC1.TransferResult {
await ICRC1.mint(token, args, caller);
await* ICRC1.mint(token, args, caller);
};

public shared ({ caller }) func burn(args : ICRC1.BurnArgs) : async ICRC1.TransferResult {
await ICRC1.burn(token, args, caller);
await* ICRC1.burn(token, args, caller);
};

public shared ({ caller }) func approve(args : ICRC1.ApproveArgs) : async ICRC1.ApproveResult {
await* ICRC1.approve(token, args, caller);
};

public shared ({ caller }) func transfer_from(args : ICRC1.TransferFromArgs) : async ICRC1.TransferFromResult {
await* ICRC1.transfer_from(token, args, caller);
};

// Functions from the rosetta icrc1 ledger
Expand All @@ -77,7 +85,7 @@ shared ({ caller = _owner }) actor class Token(

// Additional functions not included in the ICRC1 standard
public shared func get_transaction(i : ICRC1.TxIndex) : async ?ICRC1.Transaction {
await ICRC1.get_transaction(token, i);
await* ICRC1.get_transaction(token, i);
};

// Deposit cycles into this archive canister.
Expand Down
21 changes: 10 additions & 11 deletions makefile
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
.PHONY: test docs actor-test

dfx-cache-install:
install-dfx-cache:
dfx cache install

test: dfx-cache-install
$(shell dfx cache show)/moc -r $(shell mops sources) -wasi-system-api ./tests/**/**.Test.mo
test: install-dfx-cache
$(shell dfx cache show)/moc -r $(shell mops sources) -wasi-system-api ./tests/**/**.Test.mo --package base ~/.cache/dfinity/versions/0.13.1/base

no-warn: dfx-cache-install
no-warn: install-dfx-cache
find src -type f -name '*.mo' -print0 | xargs -0 $(shell dfx cache show)/moc -r $(shell mops sources) -Werror -wasi-system-api

docs:
$(shell dfx cache show)/mo-doc
$(shell dfx cache show)/mo-doc --format plain

actor-test: dfx-cache-install
actor-test: install-dfx-cache
-dfx start --background
dfx deploy test
dfx deploy test --no-wallet --identity anonymous
dfx ledger fabricate-cycles --canister test
dfx canister call test run_tests

ref-test:
-dfx start --background --clean
IDENTITY=$$(dfx identity whoami); \
echo $$IDENTITY; \
cat icrc1-default-args.txt | xargs -0 dfx deploy icrc1 --identity $$IDENTITY --no-wallet --argument ; \
-dfx start --background
cat icrc1-default-args.txt | xargs -0 dfx deploy icrc1 --identity default --argument
CANISTER=$$(dfx canister id icrc1); \
cd Dfnity-ICRC1-Reference && cargo run --bin runner -- -u http://127.0.0.1:4943 -c $$CANISTER -s ~/.config/dfx/identity/$$IDENTITY/identity.pem
USER=$$(dfx identity whoami); \
cd Dfnity-ICRC1-Reference && cargo run --bin runner -- -u http://127.0.0.1:4943 -c $$CANISTER -s ~/.config/dfx/identity/$$USER/identity.pem
46 changes: 14 additions & 32 deletions readme.md
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the readme, I think we can leave the previous information about ICRC-1 and then add sections with information for ICRC-2

Original file line number Diff line number Diff line change
@@ -1,30 +1,19 @@
# ICRC-1 Implementation
# ICRC-2 Implementation
This repo contains the implementation of the
[ICRC-1](https://github.com/dfinity/ICRC-1) token standard.
[ICRC-2](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-2/README.md).
Comment on lines +1 to +3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of replacing the link, we could add a statement that says the repo contains implementations of ICRC-1 and ICRC-2 and link to them


## References and other implementations
- [demergent-labs/ICRC-1 (Typescript)](https://github.com/demergent-labs/ICRC-1)
- [Ledger ref in Motoko](https://github.com/dfinity/ledger-ref/blob/main/src/Ledger.mo)
- [ICRC1 Rosetta API](https://github.com/dfinity/ic/blob/master/rs/rosetta-api/icrc1/ledger)
## References
- [ICRC-1](https://github.com/NatLabs/icrc1)
- [ICRC1 test](https://github.com/NatLabs/icrc1/blob/main/example/icrc1/main.mo)
Comment on lines +5 to +7
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to remove the references as they are links to other icrc1 implementations


## Documentation
- [markdown](https://github.com/NatLabs/icrc1/blob/main/docs/ICRC1/lib.md#function-init)
- [web](https://natlabs.github.io/icrc1/ICRC1/lib.html#init)

## Getting Started
- Expose the ICRC-1 token functions from your canister
- Expose the ICRC-1 from your canister
- Import the `icrc1` lib and expose them in an `actor` class.

Take a look at the [examples](./example/icrc1/main.mo)

- Launch the basic token with all the standard functions for ICRC-1
- Install the [mops](https://j4mwm-bqaaa-aaaam-qajbq-cai.ic0.app/#/docs/install) package manager
- Replace the values enclosed in `< >` with your desired values and run in the terminal

```motoko
git clone https://github.com/NatLabs/icrc1
cd icrc1
mops install
git clone https://github.com/JingJingZhang9/I3-code.git
dfx start --background --clean

dfx deploy icrc1 --argument '( record {
Expand Down Expand Up @@ -84,9 +73,12 @@ This repo contains the implementation of the

> The fields for the `advanced_settings` record are documented [here](./docs/ICRC1/Types.md#type-advancedsettings)

## Textual Representation of the ICRC-1 Accounts
This library implements the [Textual Representation](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-1/README.md#textual-representation-of-accounts) format for accounts defined by the standard. It utilizes this implementation to encode each account into a sequence of bytes for improved hashing and comparison.
To help with this process, the library provides functions in the [ICRC1/Account](./src/ICRC1/Account.mo) module for [encoding](./docs/ICRC1/Account.md#encode), [decoding](./docs/ICRC1/Account.md#decode), [converting from text](./docs/ICRC1/Account.md#fromText), and [converting to text](./docs/ICRC1/Account.md#toText).
## Textual Representation of the ICRC-2
This library implements the https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-2/README.md .

ICRC-2 is an extension of the ICRC-1 standard. ICRC-2 provides a way for account owners to delegate token transfer authorization to a third party, allowing the third party to perform transfers on behalf of the owner:
icrc2_approve: Authorizes the spender to transfer a certain amount of tokens on behalf of the caller from the account { owner = caller; subaccount = from_subaccount }. The number of transfers the spender can initiate from the caller's account is unlimited as long as the total amounts and fees of these transfers do not exceed the allowance.
icrc2_transfer_from: Transfers a certain amount of tokens between two accounts.


## Tests
Expand All @@ -95,18 +87,8 @@ To help with this process, the library provides functions in the [ICRC1/Account]
- Run `make test`
- Run `make actor-test`

#### [Dfinity's ICRC-1 Reference Tests](https://github.com/dfinity/ICRC-1/tree/main/test)
- Install Rust and Cargo via [rustup](https://rustup.rs/)

```
curl https://sh.rustup.rs -sSf | sh
```
- Then run the `ref-test` command

```
make ref-test
```

## Funding

This library was initially incentivized by [ICDevs](https://icdevs.org/). You can view more about the bounty on the [forum](https://forum.dfinity.org/t/completed-icdevs-org-bounty-26-icrc-1-motoko-up-to-10k/14868/54) or [website](https://icdevs.org/bounties/2022/08/14/ICRC-1-Motoko.html). The bounty was funded by The ICDevs.org community and the DFINITY Foundation and the award was paid to [@NatLabs](https://github.com/NatLabs). If you use this library and gain value from it, please consider a [donation](https://icdevs.org/donations.html) to ICDevs.
This library was initially incentivized by [ICDevs](https://icdevs.org/). You can view more about the bounty on the [forum](https://forum.dfinity.org/t/completed-icdevs-org-bounty-26-icrc-1-motoko-up-to-10k/14868/54) or [website](https://icdevs.org/bounties/2022/08/14/ICRC-1-Motoko.html). The bounty was funded by The ICDevs.org community and the DFINITY Foundation and the award was paid to [@NatLabs](https://github.com/NatLabs). If you use this library and gain value from it, please consider a [donation](https://icdevs.org/donations.html) to ICDevs.
8 changes: 4 additions & 4 deletions src/ICRC1/Account.mo
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import Result "mo:base/Result";
import Text "mo:base/Text";
import Time "mo:base/Time";

import ArrayModule "mo:array/Array";
import Itertools "mo:itertools/Iter";
import StableBuffer "mo:StableBuffer/StableBuffer";
import STMap "mo:StableTrieMap";
import ArrayModule "array/Array";
import Itertools "itertools/Iter";
import StableBuffer "stable/StableBuffer";
import STMap "stable/StableTrieMap";
Comment on lines +17 to +20
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Downloading the dependencies directly into the repo leads to increased project size and makes it harder to update or rollback package versions


import T "Types";

Expand Down
4 changes: 2 additions & 2 deletions src/ICRC1/Canisters/Archive.mo
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import Result "mo:base/Result";
import ExperimentalCycles "mo:base/ExperimentalCycles";
import ExperimentalStableMemory "mo:base/ExperimentalStableMemory";

import Itertools "mo:itertools/Iter";
import StableTrieMap "mo:StableTrieMap";
import Itertools "../itertools/Iter";
import StableTrieMap "../stable/StableTrieMap";
import U "../Utils";
import T "../Types";

Expand Down
16 changes: 14 additions & 2 deletions src/ICRC1/Canisters/Token.mo
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import Time "mo:base/Time";

import ExperimentalCycles "mo:base/ExperimentalCycles";

import SB "mo:StableBuffer/StableBuffer";
import SB "../stable/StableBuffer";

import ICRC1 "..";
import Archive "Archive";

shared ({ caller = _owner }) actor class Token(
init_args : ICRC1.TokenInitArgs,
init_args : ICRC1.TokenInitArgs
) : async ICRC1.FullInterface {

let icrc1_args : ICRC1.InitArgs = {
Expand Down Expand Up @@ -75,6 +75,18 @@ shared ({ caller = _owner }) actor class Token(
await* ICRC1.burn(token, args, caller);
};

public shared ({ caller }) func icrc2_approve(args : ICRC1.ApproveArgs) : async ICRC1.ApproveResult {
await* ICRC1.approve(token, args, caller);
};

public shared ({ caller }) func icrc2_transfer_from(args : ICRC1.TransferFromArgs) : async ICRC1.TransferFromResult {
await* ICRC1.transfer_from(token, args, caller);
};

public shared query func icrc2_allowance(args : ICRC1.AllowanceArgs) : async ICRC1.Allowance {
ICRC1.get_allowance_of(token, args.account, args.spender);
};

// Functions for integration with the rosetta standard
public shared query func get_transactions(req : ICRC1.GetTransactionsRequest) : async ICRC1.GetTransactionsResponse {
ICRC1.get_transactions(token, req);
Expand Down
Loading