# Failed to do wallet call. Caused by: An error happened during the call: 2: Couldn't send message

**URL:** <https://forum.dfinity.org/t/failed-to-do-wallet-call-caused-by-an-error-happened-during-the-call-2-couldnt-send-message/37188>\
**Category:** Developers\
**Tags:** Discussing\
**Created:** [November 11, 2024, 3:58am UTC](https://forum.dfinity.org/t/failed-to-do-wallet-call-caused-by-an-error-happened-during-the-call-2-couldnt-send-message/37188 "2024-11-11T03:58:57Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![readygo67](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/readygo67/32/13870_2.png) [@readygo67](https://forum.dfinity.org/u/readygo67)\
**Post date:** [November 11, 2024, 3:58am UTC](https://forum.dfinity.org/t/failed-to-do-wallet-call-caused-by-an-error-happened-during-the-call-2-couldnt-send-message/37188/1 "2024-11-11T03:58:57Z")

</div>

I have deployed 2 canisters on ICP,

x5kf3-raaaa-aaaah-aq2xq-cai, which provides a build\_witness function

```rust
#[update]
fn build_witness(tx_id_hex: String, sign_hashes_hex: Vec<String>)->(bool, Vec<u8>){
    let available_cycles = msg_cycles_available();
    if available_cycles < BUILD_WITNESS_FEE {
        ic_cdk::eprintln!("Not enough cycles provided for get build witness operation.");
        return (false, "Not enough cycles provided for get build witness operation.".as_bytes().to_vec());
    }
    let _ = msg_cycles_accept(BUILD_WITNESS_FEE);

    let tx_id_bytes = match hex::decode(tx_id_hex.clone()){
        Ok(bytes) => bytes,
        Err(e) => {
            ic_cdk::eprintln!("hex::decode error {:?}", e);
            return (false, format!("hex::decode error {:?}", e).as_bytes().to_vec());
        }
    };

    let mut sign_hashes_bytes = Vec::with_capacity(sign_hashes_hex.len());
    for hash in &sign_hashes_hex {
        let hash_bytes = match hex::decode(hash.clone()){
            Ok(bytes) => bytes,
            Err(e) => {
                ic_cdk::eprintln!("hex::decode error {:?}", e);
                return (false, format!("hex::decode error {:?}", e).as_bytes().to_vec());
            }
        };
        sign_hashes_bytes.push(hash_bytes);
    }
    
    let genesis_sc_root = GENESIS_SC_ROOT.with(|p| p.borrow().clone());

    let witness = match witness::build_public_witness(genesis_sc_root.as_bytes(),&tx_id_bytes, &sign_hashes_bytes){
        Ok(witness) => witness,
        Err(e) => {
            ic_cdk::eprintln!("witness::build_public_witness error {:?}", e);
            return (false, format!("witness::build_public_witness error {:?}", e).as_bytes().to_vec());
        }
    };
    ic_cdk::println!("witness:{}", hex::encode(witness.clone()));
    return (true, witness)
}

```

xbsjj-qaaaa-aaaai-aqamq-cai, which provides 2 funcitons

```rust
#[update]
pub async fn verify_and_sign(tx_id_hex :String, sign_hashes_hex: Vec<String>, proof_hex:String) -> (bool, Vec<String>) {
    let available_cycles = msg_cycles_available();
    let needed_cycles = PLONK_VERIY_FEE + BUILD_WITNESS_FEE + SIGN_WITH_ECDSA_FEE;
    ic_cdk::println!("available_cycles:{:?}, needed_cycles:{:?}", available_cycles, needed_cycles);
    if available_cycles < needed_cycles {
        ic_cdk::eprintln!("Not enough cycles provided for get sign hashes operation.");
        return (false, vec![]);
    }
    let _ = msg_cycles_accept(needed_cycles);

    let derivation_path = DERIVATION_PATH.with(|d| d.clone());
    let key_name = KEY_NAME.with(|kn| kn.borrow().to_string());
    ic_cdk::println!("tx_hex:{:?}, sign_hashes_hex:{:?}, proof_hex:{:?}", tx_id_hex, sign_hashes_hex, proof_hex);
    
    let proof_bytes = match hex::decode(proof_hex){
        Ok(bytes) => bytes,
        Err(e) => {
            ic_cdk::eprintln!("hex::decode error {:?}", e);
            return (false, vec![]);
        }   
    };

    //build public witness 
    let witness_builder = WITNESS_BUILDER_CANISTER.with(|d| d.borrow().clone());  
    let (build_witness_success, witness_bytes): (bool,Vec<u8>)= match call_with_payment(witness_builder, "build_witness", (tx_id_hex.clone(), sign_hashes_hex.clone()), BUILD_WITNESS_FEE).await {
        Ok((build_witness_success, witness_bytes)) => (build_witness_success, witness_bytes),
        Err(err) => {
            // Handle the error here
            ic_cdk::eprintln!("build_public_witness error: {:?}", err);
            // Return a default value or handle it appropriately
            return (false, vec![])
        }
    };

    if !build_witness_success{
        ic_cdk::eprintln!("build_public_witness failed");
        return (false, vec![]);
    } 

    //verify  
    let plonk_verifier = PLONK_VERIFIER_CANISTER.with(|d: &RefCell<Principal>| d.borrow().clone());  
    let zk_valid: bool = match call_with_payment(plonk_verifier, "plonk_verify", (proof_bytes, witness_bytes,), PLONK_VERIY_FEE).await {
        Ok((valid,)) => valid,
        Err(err) => {
            // Handle the error here
            ic_cdk::eprintln!("plonk verify error: {:?}", err);
            // Return a default value or handle it appropriately
            return (false, vec![])
        }
    };

    if !zk_valid {
        ic_cdk::eprintln!("plonk verify failed");
        return (false, vec![]);
    }

    let mut sigs = Vec::with_capacity(sign_hashes_hex.len());
    for hash in &sign_hashes_hex {
        ic_cdk::println!("{}", hash);
        let hash_bytes = match hex::decode(hash) {
            Ok(bytes) => bytes,
            Err(e) => {
                ic_cdk::eprintln!("hex::decode error {:?}", e);
                return (false, vec![]);
            }
        };
        let sig = ecdsa_api::sign(key_name.clone(), derivation_path.clone(), hash_bytes.clone()).await;
        ic_cdk::println!("hash:{}, sig:{}", hash, hex::encode(sig.clone()));
        sigs.push(hex::encode(sig));
    }

   (true, sigs)
}

```

and

```rust
#[update]
pub async fn verify_and_sign_free(tx_id_hex :String, sign_hashes_hex: Vec<String>, proof_hex:String) -> (bool, Vec<String>) {
    let derivation_path = DERIVATION_PATH.with(|d| d.clone());
    let key_name = KEY_NAME.with(|kn| kn.borrow().to_string());
    ic_cdk::println!("tx_hex:{:?}, sign_hashes_hex:{:?}, proof_hex:{:?}", tx_id_hex, sign_hashes_hex, proof_hex);
    
    let proof_bytes = match hex::decode(proof_hex){
        Ok(bytes) => bytes,
        Err(e) => {
            ic_cdk::eprintln!("hex::decode error {:?}", e);
            return (false, vec![]);
        }   
    };

    //build public witness 
    let witness_builder = WITNESS_BUILDER_CANISTER.with(|d| d.borrow().clone());  
    let (build_witness_success, witness_bytes): (bool,Vec<u8>)= match call_with_payment(witness_builder, "build_witness", (tx_id_hex.clone(), sign_hashes_hex.clone()), BUILD_WITNESS_FEE).await {
        Ok((build_witness_success, witness_bytes)) => (build_witness_success, witness_bytes),
        Err(err) => {
            // Handle the error here
            ic_cdk::eprintln!("build_public_witness error: {:?}", err);
            // Return a default value or handle it appropriately
            return (false, vec![])
        }
    };

    if !build_witness_success{
        ic_cdk::eprintln!("build_public_witness failed");
        return (false, vec![]);
    } 

    //verify  
    let plonk_verifier = PLONK_VERIFIER_CANISTER.with(|d: &RefCell<Principal>| d.borrow().clone());  
    let zk_valid: bool = match call_with_payment(plonk_verifier, "plonk_verify", (proof_bytes, witness_bytes,), PLONK_VERIY_FEE).await {
        Ok((valid,)) => valid,
        Err(err) => {
            // Handle the error here
            ic_cdk::eprintln!("plonk verify error: {:?}", err);
            // Return a default value or handle it appropriately
            return (false, vec![])
        }
    };

    if !zk_valid {
        ic_cdk::eprintln!("plonk verify failed");
        return (false, vec![]);
    }

    let mut sigs = Vec::with_capacity(sign_hashes_hex.len());
    for hash in &sign_hashes_hex {
        ic_cdk::println!("{}", hash);
        let hash_bytes = match hex::decode(hash) {
            Ok(bytes) => bytes,
            Err(e) => {
                ic_cdk::eprintln!("hex::decode error {:?}", e);
                return (false, vec![]);
            }
        };
        let sig = ecdsa_api::sign(key_name.clone(), derivation_path.clone(), hash_bytes.clone()).await;
        ic_cdk::println!("hash:{}, sig:{}", hash, hex::encode(sig.clone()));
        sigs.push(hex::encode(sig));
    }

   (true, sigs)
}

```

_verify\_and\_sign\_free_ is a cycles free version of _verify\_and\_sign_.

## Test Steps

### 1. call x5kf3-raaaa-aaaah-aq2xq-cai with user pay cycles, it works as expceted.

```auto
dfx canister call x5kf3-raaaa-aaaah-aq2xq-cai build_witness '("98da4b13e7508b84712850e723b0f2f339e93df6250a0e93af7f231e85fdac8b", vec{"2cb50594fb592826b00b7e83d70ad96feef2a55a183222409883e1bfc6022662"})' --network ic --with-cycles 100000000 --wallet 4ichq-aqaaa-aaaak-qcosa-cai

(
  true,
  blob "\00\00\00\14\00\00\00\00\00\00\00\14\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\98\da\4b\13\e7\50\8b\84\71\28\50\e7\23\b0\f2\f3\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\39\e9\3d\f6\25\0a\0e\93\af\7f\23\1e\85\fd\ac\8b\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\2c\b5\05\94\fb\59\28\26\b0\0b\7e\83\d7\0a\d9\6f\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\ee\f2\a5\5a\18\32\22\40\98\83\e1\bf\c6\02\26\62\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\5b\96\db\d1\59\14\12\77\77\ef\58\37\32\79\b5\7e\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\c9\ca\81\6e\1f\7b\34\c4\3e\ad\9c\03\bb\46\36\4d",
)

```

### 2. If I call xbsjj-qaaaa-aaaai-aqamq-cai verify\_and\_sign\_free function, it works as expected.

```auto
dfx canister call xbsjj-qaaaa-aaaai-aqamq-cai verify_and_sign_free '("98da4b13e7508b84712850e723b0f2f339e93df6250a0e93af7f231e85fdac8b", vec {"2cb50594fb592826b00b7e83d70ad96feef2a55a183222409883e1bfc6022662"}, "229baaee55571d2454fa2ba9f32e2b07135f0e10972009fd5e8a07b7e4025fe300ae9f755de6d73c11a82eb1b2cbc4fd2ba28c20fc215e51b7201ba31e262eb819709d1d8cfe03e7699b894d71052e6ccb5324c89825c2ecdf46d784f4a2e91510ac3e74bd63e57cd443ab4e8df6f8076742bf9a9e17cb61df35d08241eca8222c02e4390122e9c4b7bebb4a704fd78d96dba4cde80500e7240e15713301a4f8065fe4df227810ad02291f579fab794d24cba12c75c864fd47fcaa96343d2cfe05080197de901ad51b89e1035c6157b658f7b730a952e742b16ab99bb324307e12b6c16a4b4d0edd3af9d1eed0cc0ea001a8f1f3499f770ec6dd943119428db5100ac6efb2d4474c879247fd8d7132e33332c544fced798f85e24230bfd402890144705cf054a8784adf374e32da9729e541ee52963533a4a84abb04b83926aa03d7f95792708d08ae265db38423f35d5cf7b4203ccb28f0d330a7e0de694b6d0f324015bf06d3f7c5e8b5bc9f05018d98d8744f4ae99b16992adcc2b567704c1d7a69ec4b67334842aa1f105c00492fd92898a12b623ae942b0d27257c825191d2391cdc920925c37eddc3955bac7c562891b4f312a77b6cfd14beb54313bab0f92f3aa7b28e0756e51d2b6acee7f91c06f599ef8ac0fc84f3e9ca1a29f7dba05b1fc6dbb885994c78effe92941b231195cf990f4684ce80c8561840418de87134c1940edb3d7bfdc49c7202e28e795bd0547daee1e788764205c5e9b0995552896972dc9f8c8dc460f1b5a16db62ccf95fd27d02ec8972e69ee3e513bc43f01f2202ae9a09043697d1c5d49ed51813d81f51efc2aade8e480d8fff7014b6f41d09419fc87a071f116d4a04ffe99e50016b5b73bdd357c7fd72f0ac4bae6dbe25178b4dd99fe080c219741ccec1e2d713a29f9f4dd97ca323fbb9b49f572672022552b85f7e78be4dae71d3fd2adeef4549c4c584bc9787c51599a6f73c84382768aa27767f314f07cd3b8bcc4bb842daf2b3f43c9918e3513652ad8c9205071403995b6014a4dd5ef2fa03f1b497d0ec387be2a5f4c044f0f33f222a6e8ed5065ae326e0a46db583e874ce5567f0a215ed80ab39fa49159579529b5808f891012accdbb8424f962502df0a3b88b1abeca31104ae5094e83f4121b4774bd94621811743f001c3cb970bfc1f7b0125429963df1c8e4164183b38ad15cfacce942bd22ebc1146292580cee8469b4d870f4e3093987d2efbdb9e3e2147fbbfe0332835a812b42955a77a17c659c8c7b582e05874833abef31cdeb2c2c5b718de13")' --network ic
(
  true,
  vec {
    "7bc8a0bcec5d8e707eea512d819e8d1e5441cd0d328a2c9bd67146634c41a1af1df605305e077d8631310fa990fbd4690533931750f67535f785479d325d7109";
  },
)

```

### 3. If I call xbsjj-qaaaa-aaaai-aqamq-cai verify\_and\_sign, it resports “Couldn’t send messge”

```auto
 %dfx canister call xbsjj-qaaaa-aaaai-aqamq-cai verify_and_sign '("98da4b13e7508b84712850e723b0f2f339e93df6250a0e93af7f231e85fdac8b", vec {"2cb50594fb592826b00b7e83d70ad96feef2a55a183222409883e1bfc6022662"}, "229baaee55571d2454fa2ba9f32e2b07135f0e10972009fd5e8a07b7e4025fe300ae9f755de6d73c11a82eb1b2cbc4fd2ba28c20fc215e51b7201ba31e262eb819709d1d8cfe03e7699b894d71052e6ccb5324c89825c2ecdf46d784f4a2e91510ac3e74bd63e57cd443ab4e8df6f8076742bf9a9e17cb61df35d08241eca8222c02e4390122e9c4b7bebb4a704fd78d96dba4cde80500e7240e15713301a4f8065fe4df227810ad02291f579fab794d24cba12c75c864fd47fcaa96343d2cfe05080197de901ad51b89e1035c6157b658f7b730a952e742b16ab99bb324307e12b6c16a4b4d0edd3af9d1eed0cc0ea001a8f1f3499f770ec6dd943119428db5100ac6efb2d4474c879247fd8d7132e33332c544fced798f85e24230bfd402890144705cf054a8784adf374e32da9729e541ee52963533a4a84abb04b83926aa03d7f95792708d08ae265db38423f35d5cf7b4203ccb28f0d330a7e0de694b6d0f324015bf06d3f7c5e8b5bc9f05018d98d8744f4ae99b16992adcc2b567704c1d7a69ec4b67334842aa1f105c00492fd92898a12b623ae942b0d27257c825191d2391cdc920925c37eddc3955bac7c562891b4f312a77b6cfd14beb54313bab0f92f3aa7b28e0756e51d2b6acee7f91c06f599ef8ac0fc84f3e9ca1a29f7dba05b1fc6dbb885994c78effe92941b231195cf990f4684ce80c8561840418de87134c1940edb3d7bfdc49c7202e28e795bd0547daee1e788764205c5e9b0995552896972dc9f8c8dc460f1b5a16db62ccf95fd27d02ec8972e69ee3e513bc43f01f2202ae9a09043697d1c5d49ed51813d81f51efc2aade8e480d8fff7014b6f41d09419fc87a071f116d4a04ffe99e50016b5b73bdd357c7fd72f0ac4bae6dbe25178b4dd99fe080c219741ccec1e2d713a29f9f4dd97ca323fbb9b49f572672022552b85f7e78be4dae71d3fd2adeef4549c4c584bc9787c51599a6f73c84382768aa27767f314f07cd3b8bcc4bb842daf2b3f43c9918e3513652ad8c9205071403995b6014a4dd5ef2fa03f1b497d0ec387be2a5f4c044f0f33f222a6e8ed5065ae326e0a46db583e874ce5567f0a215ed80ab39fa49159579529b5808f891012accdbb8424f962502df0a3b88b1abeca31104ae5094e83f4121b4774bd94621811743f001c3cb970bfc1f7b0125429963df1c8e4164183b38ad15cfacce942bd22ebc1146292580cee8469b4d870f4e3093987d2efbdb9e3e2147fbbfe0332835a812b42955a77a17c659c8c7b582e05874833abef31cdeb2c2c5b718de13")' --network ic --with-cycles 28000000000 --wallet 4ichq-aqaaa-aaaak-qcosa-cai

Error: Failed to do wallet call.
Caused by: An error happened during the call: 2: Couldn't send message

```

### 4. I check my cycles, enough cycles in this wallet.

```auto
dfx cycles balance --network ic
6.999 TC (trillion cycles).

```

### The following is the snapshot of execution records with dfx v0.22.0

 ![image](https://us1.discourse-cdn.com/flex023/uploads/dfn/original/3X/6/c/6c05d424918b7b3eddeed32666a4fd396dbbeb67.jpeg)

Anybody have idea about this problem?

---

<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:** [November 11, 2024, 8:46am UTC](https://forum.dfinity.org/t/failed-to-do-wallet-call-caused-by-an-error-happened-during-the-call-2-couldnt-send-message/37188/2 "2024-11-11T08:46:55Z")

</div>

> [@readygo67](#):
>
> ### 4. I check my cycles, enough cycles in this wallet.
> 
> ```auto
> dfx cycles balance --network ic
> 6.999 TC (trillion cycles).
> 
> ```

The error could be here. `dfx cycles balance` checks how many cycles you have on the cycles ledger. If you make a call via `--wallet <wallet id>` the the balance of the wallet canister is relevant. `dfx canister status --ic <wallet id>` will tell you how many cycles the wallet has

Edit: just tried with my own wallet that has a bunch of cycles. Worked fine

---

<div class="post-metadata">

**Author:** ![readygo67](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/readygo67/32/13870_2.png) [@readygo67](https://forum.dfinity.org/u/readygo67)\
**Post date:** [November 12, 2024, 3:18am UTC](https://forum.dfinity.org/t/failed-to-do-wallet-call-caused-by-an-error-happened-during-the-call-2-couldnt-send-message/37188/3 "2024-11-12T03:18:12Z")

</div>

@Vivienne It works after top-up wallet canister, thanks very much.
