Indexer: note-prefix query

Hi everybody,

I can’t find good documentation about the “note-prefix” query in the “lookup account transactions” function. How does it actually work?

As far as I can see in the source code (at least in the Java SDK) this function automatically encode in base64 the text I pass… But what If my note field is encoded in MessagePack format? Is there a way to query it?

Thank you

Realistically, only if you query using the entire messagepack string.
It’s a prefix match trying to encode something to match as a prefix, using messagepack will never match the leading bytes of the messagepack field.

The indexer consider all notes as just byte arrays.
Since you cannot include arbitrary bytes in a URL, these bytes need to be encoded in base64.
But at the end of the day, the indexer just converts back base64 to bytes, and find transactions that have a note with a prefix the bytes you indicated.

As @aojjazz explained, if the notes are actually msgpack-encoded structures, most likely this search by prefix will not be helpful. One of the only cases where this search by prefix would work is if the structure you msgpack-encode is always the same and the field you are searching is the first one in the encoding (for that you need to be sure the msgpack-encoder always encode this field the first - which is not guaranteed by most msgpack encoders).

As a side note, the Algorand msgpack encoder ensures that all fields are encoded in alphabetical orders, which may help in some cases. But you would need to ensure that everyone is using the Algorand msgpack-encoder and not another one.

Thank you @fabrice and @aojjazz

I tried different strategies (and I found at least one that works) but in the end you are right… it’s not a good idea to rely on the note-prefix to find info in the note field, especially if it’s encoded as msgpack.

The only alternative I see is to filter the transactions in the application, where I can decode the note field and extract the info I need.
It’s less efficient but I can’t see any other viable options.

In case someone is curious, I post below the code for the note-prefix query with msgpack… It’s a bit clumsy but works. However, as @fabrice already said, it is only useful in very limited cases.

byte[] msgpk = Encoder.encodeToMsgPack(<object-to-encode>);
byte[] m = Arrays.copyOfRange(msgpk 0, <desired-prefix-length>);
indexerClient.lookupAccountTransactions(address).assetId(id).notePrefix(m).execute().body()

I don’t know what scale you plan for your solution. If it grows large enough for you to have your own private indexer, than you could add custom triggers in the database that would decode the relevant fields and filter accordingly.
( this isnt a good idea for proof of concept project… as it might not be easy to implement )