# ckBTC Transfer from Canister After Approval

**URL:** <https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677>\
**Category:** Developers\
**Tags:** ckBTC\
**Created:** [March 20, 2024, 12:41pm UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677 "2024-03-20T12:41:00Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![blockbolt](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/blockbolt/32/15640_2.png) [@blockbolt](https://forum.dfinity.org/u/blockbolt)\
**Post date:** [March 20, 2024, 12:41pm UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/1 "2024-03-20T12:41:01Z")

</div>

Hello Community,

We have some questions regarding Motoko and Canister.

We are using Motoko to build a Canister that will be used to transfer ICRC-1 & 2 token from our canister to other principal id.

However, we are stuck at the transfer stage after approval. Here’s the process:

First, we are using the ckBTC Canister ID `mxzaz-hqaaa-aaaar-qaada-cai`. We tried to approve ckBTC from the Canister and it worked fine.

We used this command for approval:  
`dfx canister call bza44-ciaaa-aaaan-qlvna-cai approve '(88)' --network ic`

> (variant { ok = 1\_305\_047 : nat })

So basically, we approve the Canister ID with the respective principal ID. You can see all the approved

[Our canister id: bza44-ciaaa-aaaan-qlvna-cai](https://dashboard.internetcomputer.org/bitcoin/account/bza44-ciaaa-aaaan-qlvna-cai)

After approval from the ckBTC ledger, we are transferring it to another wallet (principal ID).

`dfx canister call bza44-ciaaa-aaaan-qlvna-cai transfer '(30, principal "3zm3c-qhy2j-5vvce-il3fu-il4ai-wf5fs-bwwjp-dbary-numis-kgxui-rae")' --network ic`

However, we are getting the following error:

> (variant { err = “Unknown transfer error” })

We want to send ICRC1, ICRC2, and ICP through our Canister freely.

Can you please guide us on how we can solve this issue?

Thank you!

---

<div class="post-metadata">

**Author:** ![Vivienne](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/vivienne/32/29170_2.png) [@Vivienne](https://forum.dfinity.org/u/Vivienne)\
**Post date:** [March 21, 2024, 10:30am UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/2 "2024-03-21T10:30:11Z")

</div>

Can you show what canister/principal makes what calls to the ckBTC canister? What you show here is how you call your own canister which doesn’t really help to debug

---

<div class="post-metadata">

**Author:** ![karangoraniya](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/karangoraniya/32/13972_2.png) [@karangoraniya](https://forum.dfinity.org/u/karangoraniya)\
**Post date:** [March 21, 2024, 11:22am UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/4 "2024-03-21T11:22:45Z")

</div>

Hello @Vivienne,

Thank you for your response.

We are using the following canister to interact with the ckBTC ledger:

> bza44-ciaaa-aaaan-qlvna-cai

ckBTC canister id

> mxzaz-hqaaa-aaaar-qaada-cai

Below is the code. Initially, we call this function in the canister to approve ckBTC:

```auto
public shared ({ caller = owner }) func approve(amount : Nat) : async Result.Result<Nat,Text> {
    let args = {
        amount;
        created_at_time = null;
        expected_allowance = null;
        expires_at = null;
        fee = null;
        from_subaccount = null;
        memo = null;
        spender = { owner; subaccount = null };
    };
    let result_Trans = await ckbtc_ledger.icrc2_approve(args);
};

```

Following approval, I attempt a transfer using this principal ID:

> uonvj-rdj5h-pft2p-pdo2w-qaolc-ojdyo-3btrc-o27pt-xg2lz-an2ga-qqe

Here is the transfer function:

```auto
public shared ({ caller }) func transfer(amount : Nat, to : Principal) : async Result.Result<Nat, Text> {
    let args = {
        to = { owner = to; subaccount = null };
        fee = null;
        spender_subaccount = null;
        from = { owner = caller; subaccount = null };
        memo = null;
        created_at_time = null;
        amount = amount;
    };
    let transf_Result = await ckbtc_ledger.icrc2_transfer_from(args);
};

```

However, during the transfer process, I’m encountering the following error:

`(variant { err = "Unknown transfer error" })`

---

<div class="post-metadata">

**Author:** ![Vivienne](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/vivienne/32/29170_2.png) [@Vivienne](https://forum.dfinity.org/u/Vivienne)\
**Post date:** [March 21, 2024, 12:37pm UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/5 "2024-03-21T12:37:56Z")

</div>

When you make the `icrc2_transfer_from` call the ckBTC canister sees `bza44-ciaaa-aaaan-qlvna-cai` as the caller. This is different from e.g. ETH where the TX creator gets forwarded between contract calls. If you want to do that transfer you can use a standard `icrc1_transfer`, no need to go through the approval process

The `approve` function seems to work. If I [check the approved amount](https://dashboard.internetcomputer.org/canister/mxzaz-hqaaa-aaaar-qaada-cai#icrc2_allowance) using the principals you posted above I get `(record { allowance = 100 : nat; expires_at = null })`

---

<div class="post-metadata">

**Author:** ![karangoraniya](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/karangoraniya/32/13972_2.png) [@karangoraniya](https://forum.dfinity.org/u/karangoraniya)\
**Post date:** [March 22, 2024, 2:05am UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/6 "2024-03-22T02:05:17Z")

</div>

I’ve tried that approach initially, but it didn’t work as expected. Instead of deducting ckBTC from the user’s wallet, it was taking the amount from the canister.

Here’s an example:

[Transfer amount](https://dashboard.internetcomputer.org/bitcoin/transaction/1313946)

I’m looking for a way to directly deduct from the user’s wallet and transfer it to another account, but it needs to go through our canister because we have additional data that needs to be passed along with the transaction.

---

<div class="post-metadata">

**Author:** ![Vivienne](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/vivienne/32/29170_2.png) [@Vivienne](https://forum.dfinity.org/u/Vivienne)\
**Post date:** [March 22, 2024, 8:04am UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/7 "2024-03-22T08:04:52Z")

</div>

If you want to spend the user’s ckBTC then the user needs to call `icrc2_approve` directly, and not through your canister

---

<div class="post-metadata">

**Author:** ![karangoraniya](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/karangoraniya/32/13972_2.png) [@karangoraniya](https://forum.dfinity.org/u/karangoraniya)\
**Post date:** [March 28, 2024, 10:07am UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/8 "2024-03-28T10:07:55Z")

</div>

I have also tried using the `icrc2_approve` function on the frontend side with the ckBTC ledger. However, I encountered an error while transferring the tokens. Here are the links to the repository and the live demo:

- [Github](https://github.com/karangoraniya/icp-approve)
- [Live Link](https://icp-approve.vercel.app/)
- [Canister ID](https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=bza44-ciaaa-aaaan-qlvna-cai)

There are two arguments, but it’s still giving the  
`wrong number of message arguments' error`.

---

<div class="post-metadata">

**Author:** ![icnerd](https://avatars.discourse-cdn.com/v4/letter/i/e274bd/32.png) [@icnerd](https://forum.dfinity.org/u/icnerd)\
**Post date:** [March 29, 2024, 11:26pm UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/9 "2024-03-29T23:26:31Z")

</div>

there is no `from` field in `ApproveArgs`

```auto
export interface ApproveArgs {
  fee: [] | [bigint];
  memo: [] | [Uint8Array | number[]];
  from_subaccount: [] | [Uint8Array | number[]];
  created_at_time: [] | [bigint];
  amount: bigint;
  expected_allowance: [] | [bigint];
  expires_at: [] | [bigint];
  spender: Account;
}

```

> <https://github.com/karangoraniya/icp-approve/blob/main/src/app/Transfer.tsx#L135>

address of the caller is fetched automatically by the ledger canister.

when the `icrc2_approve` function is called,  
it will perform the step to build the `from`

```rs
fn icrc2_approve(arg: ApproveArgs) -> ... {
  let caller = ic_cdk::caller();
  let from = Account{
    owner: caller,
   subaccount: arg.from_subaccount,
  };
  .....

```

---

<div class="post-metadata">

**Author:** ![karangoraniya](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/karangoraniya/32/13972_2.png) [@karangoraniya](https://forum.dfinity.org/u/karangoraniya)\
**Post date:** [March 31, 2024, 8:30am UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/10 "2024-03-31T08:30:59Z")

</div>

The approve function is working fine. I am getting an error while transferring ckBTC.

I just approved it with this code

[ckBTC Dashboard](https://dashboard.internetcomputer.org/bitcoin/transaction/1332419)

---

<div class="post-metadata">

**Author:** ![karangoraniya](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/karangoraniya/32/13972_2.png) [@karangoraniya](https://forum.dfinity.org/u/karangoraniya)\
**Post date:** [April 6, 2024, 7:12pm UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/11 "2024-04-06T19:12:26Z")

</div>

@Vivienne, could you assist me with this issue ?

---

<div class="post-metadata">

**Author:** ![icnerd](https://avatars.discourse-cdn.com/v4/letter/i/e274bd/32.png) [@icnerd](https://forum.dfinity.org/u/icnerd)\
**Post date:** [April 7, 2024, 6:20am UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/12 "2024-04-07T06:20:16Z")

</div>

> [@karangoraniya](#):
>
> The approve function is working fine. I am getting an error while transferring ckBTC

I don’t think canisters are that lenient to accept non declared argument.

Also the txn fee for CKBTC is 10000.  
you won’t be able to transfer 100.

---

<div class="post-metadata">

**Author:** ![Vivienne](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/vivienne/32/29170_2.png) [@Vivienne](https://forum.dfinity.org/u/Vivienne)\
**Post date:** [April 8, 2024, 9:35am UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/13 "2024-04-08T09:35:01Z")

</div>

What is the error you’re currently stuck with? And can you link me to the lines where you make the transfer?

---

<div class="post-metadata">

**Author:** ![karangoraniya](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/karangoraniya/32/13972_2.png) [@karangoraniya](https://forum.dfinity.org/u/karangoraniya)\
**Post date:** [April 8, 2024, 10:09am UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/14 "2024-04-08T10:09:14Z")

</div>

sure

here is the approve ckBTC code

[Approve Code](https://github.com/karangoraniya/icp-approve/blob/df3fe5339821c0c4953b724ac5c76fe873874279/src/app/Transfer.tsx#L110)

here is the send ckBTC code  
[Transfer ckBTC code](https://github.com/karangoraniya/icp-approve/blob/df3fe5339821c0c4953b724ac5c76fe873874279/src/app/Transfer.tsx#L159)

when i try to transfer the ckBTC i am getting error

Wrong number of message arguments.

---

<div class="post-metadata">

**Author:** ![Vivienne](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/vivienne/32/29170_2.png) [@Vivienne](https://forum.dfinity.org/u/Vivienne)\
**Post date:** [April 8, 2024, 11:18am UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/15 "2024-04-08T11:18:00Z")

</div>

Approve: declaration [says](https://github.com/karangoraniya/icp-approve/blob/df3fe5339821c0c4953b724ac5c76fe873874279/src/utils/ledger.did.js#L264) it takes an `ApproveArgs`, you create an `ApproveArgs` object [here](https://github.com/karangoraniya/icp-approve/blob/df3fe5339821c0c4953b724ac5c76fe873874279/src/app/Transfer.tsx#L134-L150)

Transfer: declaration [says](https://github.com/karangoraniya/icp-approve/blob/df3fe5339821c0c4953b724ac5c76fe873874279/src/utils/bolt.did.js#L7) it takes a `Nat` and a `Principal`, but you [construct an object](https://github.com/karangoraniya/icp-approve/blob/df3fe5339821c0c4953b724ac5c76fe873874279/src/app/Transfer.tsx#L174-L181) with a `amount` and `from`. In Candid notation: expected: `(nat, principal)`, you supply `(record{amount: nat; to: principal})`. The tuple is supposed to be 2 elements, but you give only 1, therefore `Wrong number of arguments`

---

<div class="post-metadata">

**Author:** ![karangoraniya](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/karangoraniya/32/13972_2.png) [@karangoraniya](https://forum.dfinity.org/u/karangoraniya)\
**Post date:** [April 8, 2024, 1:01pm UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/16 "2024-04-08T13:01:32Z")

</div>

> [@Vivienne](#):
>
> Transfer: declaration [says](https://github.com/karangoraniya/icp-approve/blob/df3fe5339821c0c4953b724ac5c76fe873874279/src/utils/bolt.did.js#L7) it takes a `Nat` and a `Principal`, but you [construct an object](https://github.com/karangoraniya/icp-approve/blob/df3fe5339821c0c4953b724ac5c76fe873874279/src/app/Transfer.tsx#L174-L181) with a `amount` and `from`. In Candid notation: expected: `(nat, principal)`, you supply `(record{amount: nat; to: principal})`. The tuple is supposed to be 2 elements, but you give only 1, therefore `Wrong number of arguments`

Okay, got it

I tried to trigger the transaction, but got error

**Unknown transfer error**

which i define in the code the same error i got while using direct in dfx UI

---

<div class="post-metadata">

**Author:** ![Vivienne](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/vivienne/32/29170_2.png) [@Vivienne](https://forum.dfinity.org/u/Vivienne)\
**Post date:** [April 8, 2024, 1:10pm UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/17 "2024-04-08T13:10:06Z")

</div>

For that I’ll ask some other people since this sounds like some ckBTC internal problem…

---

<div class="post-metadata">

**Author:** ![blockbolt](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/blockbolt/32/15640_2.png) [@blockbolt](https://forum.dfinity.org/u/blockbolt)\
**Post date:** [April 10, 2024, 12:20pm UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/18 "2024-04-10T12:20:35Z")

</div>

We would appreciate it if you could provide us with any updates regarding the issue we mentioned earlier. Our infrastructure and backend processes are in place; we just need a solution for the requested error. This will enable us to implement the proposed payment solution on ICP as soon as possible.

---

<div class="post-metadata">

**Author:** ![mariop](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/mariop/32/5114_2.png) [@mariop](https://forum.dfinity.org/u/mariop)\
**Post date:** [April 10, 2024, 1:15pm UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/19 "2024-04-10T13:15:47Z")

</div>

> [@karangoraniya](#):
>
> I tried to trigger the transaction, but got error
> 
> **Unknown transfer error**
> 
> which i define in the code the same error i got while using direct in dfx UI

The Ledger doesn’t not return any **Unknown transfer error**. Where does this error come from?

---

<div class="post-metadata">

**Author:** ![karangoraniya](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/karangoraniya/32/13972_2.png) [@karangoraniya](https://forum.dfinity.org/u/karangoraniya)\
**Post date:** [April 11, 2024, 6:40am UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/20 "2024-04-11T06:40:58Z")

</div>

Initially, I used the ckBTC approve function on the frontend to authorized my canister to access a specific amount of funds. Subsequently, I integrated the ckBTC canister into my contract for fund transfer purposes. I encountered an error from my canister during this process, and the relevant code is available in my GitHub repository [here](https://github.com/karangoraniya/ckBTC-icp/blob/118d038fab05d256b9982b07ffbc447eb7cf9825/src/fortune_cookie_backend/main.mo#L207).

To summarize, our objective is to enable our canister to transfer ckBTC and, simultaneously, send additional values as needed.

---

<div class="post-metadata">

**Author:** ![mariop](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/mariop/32/5114_2.png) [@mariop](https://forum.dfinity.org/u/mariop)\
**Post date:** [April 11, 2024, 7:01am UTC](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677/21 "2024-04-11T07:01:02Z")

</div>

> [@karangoraniya](#):
>
> I encountered an error from my canister during this process, and the relevant code is available in my GitHub repository [here](https://github.com/karangoraniya/ckBTC-icp/blob/118d038fab05d256b9982b07ffbc447eb7cf9825/src/fortune_cookie_backend/main.mo#L207).

It’s difficult to help without knowing the exact error. Can you change [ckBTC-icp/src/fortune\_cookie\_backend/main.mo at 118d038fab05d256b9982b07ffbc447eb7cf9825 · karangoraniya/ckBTC-icp · GitHub](https://github.com/karangoraniya/ckBTC-icp/blob/118d038fab05d256b9982b07ffbc447eb7cf9825/src/fortune_cookie_backend/main.mo#L232) to print out the error received from the Ledger and then try again? I’m sure that will tell us why it is not working.

[Next page](https://forum.dfinity.org/t/ckbtc-transfer-from-canister-after-approval/28677.md?page=2)
