metaplex-foundation / umi-hotline

2 stars 0 forks source link

Serialising public key into strings and back #9

Closed sohrab- closed 1 year ago

sohrab- commented 1 year ago

Umi version

0.7.6

Code

const text = "66PBVcmJyky1vrCkxnefehNABwe7d1p2WYNWeMSPx2qn";
const byteArray = umi.serializer.publicKey().serialize(text);
console.log(byteArray.length) // prints 32

const s = umi.serializer.string({ size: "variable" });
const [text32b] = s.deserialize(byteArray);
console.log(s.serialize(text32b).length); // prints 60

Error

I was expecting to get back to a 32 unit8 array by the end.

The context for this is that I am trying to use a public key as a seed for a Hydra wallet. And this is kinda what findFanoutPda() is doing, which is resulting in Max seed length exceeded (on the account of it being 60, rather than 32).

Please let me know if I can do this ☝️ in a different manner.

lorisleiva commented 1 year ago

Hey there,

That's because umi.serializer.string() defaults to encoding your string in utf8 and not base58.

You can configure that using the encoding option like so.

import { base58 } from '@metaplex-foundation/umi';

// Configure the encoding.
const s = umi.serializer.string({ size: "variable", encoding: base58 });

// Serialize.
const publicKeyAsText = "66PBVcmJyky1vrCkxnefehNABwe7d1p2WYNWeMSPx2qn";
const bytes = s.serialize(publicKeyAsText);
console.log(bytes.length) // prints 32

// Deserialize.
const [decodedPublicKeyAsText] = s.deserialize(bytes);
console.log(publicKeyAsText === decodedPublicKeyAsText); // true

As far as the findFanoutPda() goes, as a library maintainer, we have to decide on a good default encoding that pleases most users and utf8 here makes more sense than base58 as it can be any name (not just using the characters of the base58 family) but you can use the underlying code and replace the encoding to whatever you want.

I hope this helps. 🍀

sohrab- commented 1 year ago

Thanks for the response, Loris. I did try to change the encoding, but as you mentioned, it won't matter because the on-chain program will still try to deserialise with utf8 and the seed ending up being too large.

I'll likely find another unique string to use as the seed here since I want to avoid forking the Hydra program.