How to transfer funds/tokens from a master identity to another identity / wallet

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.

1 Like

Are you looking for icrc2_transfer_from? ICRC-1/standards/ICRC-2/README.md at main ¡ dfinity/ICRC-1 ¡ GitHub

1 Like

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

1 Like

i can approve a canister to do transfers on my behalf?

Yes, you can approve any valid principal to spend on your behalf

1 Like

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

1 Like

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

1 Like

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";

1 Like

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;
      };
    }
  })
"
1 Like

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>";
  };
})'
1 Like

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?

1 Like

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 })
1 Like