coral-xyz / anchor

⚓ Solana Sealevel Framework
https://anchor-lang.com
Apache License 2.0
3.73k stars 1.37k forks source link

view() function cannot decode imported / tupple struct #3220

Open jusikXL opened 2 months ago

jusikXL commented 2 months ago

Hello there. We are building Bakstag - Omnichain OTC Market protocol. We are using anchor lang as the main framework for developing Solana contracts.

Currently, we are experiencing the following issues: 1. The .view() method builder cannot decode the result if the function returns the external type (imported from the other library).

Here is an example

use oapp::endpoint::MessagingFee;
... -> Result<MessagingFee>

If we are to use .view() as a read function, it throws the following error:

IdlError: Type not found: {"type": {"defined":"MessagingFee"}}

If we are to add MessagingFee implicitly so that it appears in IDL, the problem will be gone.

2. There is another issue: If we are to use .view() for the function which returns tuple type:

... -> Result<(CreateOfferReceipt, MessagingFee)>

it again throws with:

IdlError: Type not found: {"type": {"defined":"(CreateOfferReceipt, MessagingFee)"}}

no matter that both types are defined implicitly

acheroncrypto commented 2 months ago

These are not related to the view method, as you'd get the same errors using other methods.

  1. To use a custom type in a client, you'd need the type to be included in the IDL. If it's an external type, you can include it programatically like in this example rather than manually adding the type to the IDL.
  2. Tuples are currently not supported. This is not due to a technical limitation, but rather an explicit decision to make APIs readable by default. Rather than returning (CreateOfferReceipt, MessagingFee), define a struct with fields create_offer_receipt and messaging_fee so that it's clear for the consumers of your API. You can also use unnamed (tuple) structs MyRetunType(CreateOfferReceipt, MessagingFee), but I wouldn't recommend it.
jusikXL commented 2 months ago

Could you assist me with that example of wrapping a non-Anchor external type to include it in the IDL?

I don't understand where I should do it. The things happen at lib.rs of the new-idl...

jusikXL commented 2 months ago

Is it available for anchor 0.29.0 - we use that one?

acheroncrypto commented 2 months ago

It was somewhat supported in 0.29.0 but it was an experimental feature. Full support was added in https://github.com/coral-xyz/anchor/pull/2824 (v0.30) and the example I shared above is also for 0.30.0.