I am able to transfer funds from one connected account to another not connected account simply by using the icp ledger in js. but now i want to transfer funds the other way arround.
If what i was doing before was send tokens now i want to recieve them is there a possible way for it in a reactjs app which is 100% on chain.
Are you looking for icrc2_transfer_from
? ICRC-1/standards/ICRC-2/README.md at main ¡ dfinity/ICRC-1 ¡ GitHub
What i want is to transfer icp tokens from my motoko canister using my master wallet. without me having to approve the transaction.
You can have your canister blanket-approve a large amount (say u64::MAX
) and then you can icrc2_transfer_from
whenever you want, but the canister will have to call icrc2_approve
once to set this up
i can approve a canister to do transfers on my behalf?
Yes, you can approve any valid principal to spend on your behalf
so i could do something like:
public shared ({caller}) func gimme_money() : Bool {
<If the caller deserves money>
ledger.transfer(to:<callers'accountid>,amount: <what he deserves>);
return true;
<else>
return false;
}
You can do that. If you use ledger.transfer
you will always spend your own tokens (so since this is in a canister you would spend the canisterâs tokens). If you want to spend tokens of some other account you have to use ledger.icrc2_transfer_from
Yes i get that, Thank you very much!!!
But how can i call ledgerâs methods from a motoko canister is it just like how we do normal inter-canister calls or is it different?
The ledger is a canister like any other canister. You can use the normal inter-canister calls. Itâs just a bit âmore importantâ, otherwise thereâs nothing special about it
yes and in normal cansiter call we declare the methods we want to use by creating the actor like:
let ledgerCanister = actor ('ryjl3-tyaaa-aaaaa-aaaba-cai') : actor {
transfer : (to : Principal, amount : Int) -> async Bool;
};
its not complete ik but do we have to declare all the methods we want to use or is ther a predefined way to achieve this
The recommended setup is here, then you can use the ledger in Motoko with import LEDGER "canister:ledger";
I am got this error when tried to call the approve method on my local ledger.
ICRC-2 features are not enabled on the ledger., error code None
from what i found on the docs. i have to deploy an icrc1 ledger with feature_flags = opt record{icrc2 = true};
but i dont really want to create my own tokens and interact with them i want to interact with the icp ledger and its (icp)tokens.
You only deploy the ledger yourself if youâre developing locally on your machine. For mainnet you wonât deploy your own.
To turn on ICRC-2, you need to add the feature_flag
field to the init args like this:
dfx deploy --specified-id ryjl3-tyaaa-aaaaa-aaaba-cai icp_ledger_canister --argument "
(variant {
Init = record {
minting_account = \"$MINTER_ACCOUNT_ID\";
initial_values = vec {
record {
\"$DEFAULT_ACCOUNT_ID\";
record {
e8s = 10_000_000_000 : nat64;
};
};
};
send_whitelist = vec {};
transfer_fee = opt record {
e8s = 10_000 : nat64;
};
token_symbol = opt \"LICP\";
token_name = opt \"Local ICP\";
feature_flags = opt record {
icrc2 = true;
};
}
})
"
Sorry to bother again but it is releated to the issue so:
I was able to do it locally as youâve mentioned but when i deploy my canisters on main-net and i want to allow my canister to use my masterWallets token i got stuck.
what i tried was to use the icrc2_approve method on the dfx ledger but it doesnât have a method like that so the question is :
How am i supposed to allow a canister on mainnet to use my icp tokens from icp ledger âryjl3-tyaaa-aaaaa-aaaba-caiâ using the icrc2_approve method
You have to call the function manually using dfx canister call
.
dfx canister --network ic call ryjl3-tyaaa-aaaaa-aaaba-cai icrc2_approve '( record {
amount = <amount in e8s>;
spender = record {
owner = principal "<canister id>";
};
})'
This is the command iam running
dfx canister call ryjl3-tyaaa-aaaaa-aaaba-cai icrc2_approve "(record { amount = 10_000_000_000_000_000; spender = record{owner = principal \"my-canister-id\";} })" --network ic
And i get this error
Error: Failed update call.
Caused by: Failed update call.
The replica returned a replica error: Replica Error: reject code CanisterReject, reject message Fail to decode argument 0, error code None```
Maybe try amount = 10_000 : nat
?
I did but didnât work i even removed the whole amount field yet it still gave the same error
If I add : nat
to the amount it works for me:
⯠dfx canister call ryjl3-tyaaa-aaaaa-aaaba-cai icrc2_approve "(record { amount = 10_000_000_000_000_000: nat; spender = record{owner = principal \"aaaaa-aa\";} })" --network ic
(variant { 17_724 = 9_232_450 : nat })