# Unable to release or send coins from contract — missing mt\_index / QualifiedCoinInfo after receive() - jeyem7843

**URL:** <https://forum.midnight.network/t/unable-to-release-or-send-coins-from-contract-missing-mt-index-qualifiedcoininfo-after-receive-jeyem7843/563>\
**Category:** Technical Questions\
**Created:** [October 27, 2025, 10:00am UTC](https://forum.midnight.network/t/unable-to-release-or-send-coins-from-contract-missing-mt-index-qualifiedcoininfo-after-receive-jeyem7843/563 "2025-10-27T10:00:18Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Discord\_Dev\_Query](https://avatars.discourse-cdn.com/v4/letter/d/f07891/32.png) [@Discord\_Dev\_Query](https://forum.midnight.network/u/Discord_Dev_Query)\
**Post date:** [October 27, 2025, 10:00am UTC](https://forum.midnight.network/t/unable-to-release-or-send-coins-from-contract-missing-mt-index-qualifiedcoininfo-after-receive-jeyem7843/563/1 "2025-10-27T10:00:18Z")

</div>

`What are you trying to do?`  
I’m building an escrow-style contract that should be able to both receive and later release coins.

```fn
fn send(input: QualifiedCoinInfo, recipient: Either<ZswapCoinPublicKey, ContractAddress>, value: Uint<128>) { ... }

```

Receiving works fine — the contract correctly accepts assets via receive(coin).  
However, when I attempt to release the assets (send them back out), I need to pass a valid QualifiedCoinInfo, which includes the coin’s mt\_index (Merkle tree index).  
Without the correct mt\_index, the contract cannot identify and spend the coin it holds.

`What’s not working or unclear?`  
The documentation explains that:

The runtime or indexer already knows the mt\_index of each coin’s commitment when the contract receives it.

DApps are supposed to register this mapping by calling:

```auto
queryContext.insertCommitment(commitment, index);

```

The problem is:  
There is no documented or programmatic way for a DApp to obtain that mt\_index (or the commitment) from the indexer or runtime after the contract has received the coin.

As a result:

I can receive coins, but cannot later construct the required QualifiedCoinInfo.

Therefore, the contract cannot release or send out the assets it holds.

This effectively prevents implementing escrow or similar holding/spending patterns.

Questions:

How can a DApp obtain the correct mt\_index for a coin commitment after it’s received by a contract?

Is there an API (current or planned) in the indexer or runtime to expose this data?

How should insertCommitment() be used in practice if we can’t access the index value?

`What have you tried so far?`  
Used the indexer’s Zswap state to estimate the Merkle index:

```auto
const mt_index = zswapState.firstFree - 1;

```

This works inconsistently — only when no other commitments are inserted in the same block.

Reviewed all available docs (docs.midnight.network/develop) — including Contracts, QueryContext, and Coin Handling Proposal — none describe how to fetch mt\_index or register it off-chain.

Contacted support earlier — they confirmed the runtime knows the index, and suggested using queryContext.insertCommitment(commitment, index) — but provided no example or way to retrieve those values.

Verified that the issue is not within contract logic — it’s strictly about obtaining mt\_index to build a valid QualifiedCoinInfo.

Example of the blocked step:

```auto
// Construct QualifiedCoinInfo for release
const input = {
  coin: {
    nonce: deposit.nonce,
    type: deposit.type,
    value: deposit.value
  },
  mt_index: ??? // this is required but unknown
};

// Attempt to send/release
contract.send(input, depositorPublicKey, deposit.value);

```

Without access to the mt\_index, the transaction can’t be signed or validated, so the contract cannot release assets it holds.

`Add any relevant code or error messages.`

```auto

```

---

<div class="post-metadata">

**Author:** ![sergeykisel](https://avatars.discourse-cdn.com/v4/letter/s/ac91a4/32.png) [@sergeykisel](https://forum.midnight.network/u/sergeykisel)\
**Post date:** [October 27, 2025, 2:07pm UTC](https://forum.midnight.network/t/unable-to-release-or-send-coins-from-contract-missing-mt-index-qualifiedcoininfo-after-receive-jeyem7843/563/2 "2025-10-27T14:07:42Z")

</div>

> [@Discord\_Dev\_Query](#):
>
> However, when I attempt to release the assets (send them back out), I need to pass a valid QualifiedCoinInfo, which includes the coin’s mt\_index (Merkle tree index).

There are two possibilities to send, either you use `sendImmediate` which accepts `CoinInfo` as input and immediately sends coins available in the same circuit from the wallet of the user who calls that circuit. Normal call `send` accepts `QualifiedCoinInfo` which is the one written on the ledger, so when you receive a coin to your contract - you should be writing it to the ledger with `writeCoin` which writes ``QualifiedCoinInfo`` to the ledger which you can send later from another transaction.

---

<div class="post-metadata">

**Author:** ![bochaco](https://yyz2.discourse-cdn.com/flex010/user_avatar/forum.midnight.network/bochaco/32/112_2.png) [@bochaco](https://forum.midnight.network/u/bochaco)\
**Post date:** [October 27, 2025, 3:35pm UTC](https://forum.midnight.network/t/unable-to-release-or-send-coins-from-contract-missing-mt-index-qualifiedcoininfo-after-receive-jeyem7843/563/3 "2025-10-27T15:35:29Z")

</div>

> [@I’m developing an escrow-style contract that needs to both receive and later release coins using the documented methods](https://forum.midnight.network/t/i-m-developing-an-escrow-style-contract-that-needs-to-both-receive-and-later-release-coins-using-the-documented-methods/562/2):
>
> If I understand your doubt correctly, I believe you are referring to something like the following for deposits: // Contract's own treasury of native tokens. export ledger treasury: QualifiedCoinInfo; export circuit depositFunds(coinInfo: CoinInfo): [] { assert(coinInfo.color == nativeToken(), "Only native tokens can be deposited"); receive(disclose(coinInfo)); const me = right\<ZswapCoinPublicKey, ContractAddress\>(kernel.self()); treasury.writeCoin(disclose(coinInfo), me); return []; …
