Bug: Client initialization always fails

Hi

I’m trying to implement the v3 on javascript/react using @xmtp/browser-sdk by following documentation here Build a chat inbox – Build with XMTP

Unfortunately Im not able to make it run correctly after several trials.
I’m using a provider on top of @ethersproject/* and Particle network as connector (for now just stand with metamask, so no smart wallet yet)

here is the piece of code I’m using now

const useClient = () => {
  const encryptionKeyHex = process.env.REACT_APP_ENCRYPTION_KEY;
  if (!encryptionKeyHex) {
    throw new Error('ENCRYPTION_KEY must be set in the environment');
  }
  const encryptionBytes = toUtf8Bytes(encryptionKeyHex);

  const { account, signMessage, library, chainId } = useWeb3Application();

  const mlsSigner = useMemo(
    () => {
      const signer: Signer = {
        getAddress: () => account,
        signMessage: async (message) => {
          const sig = await signMessage(message);

          const erecover = verifyMessage(message, sig);

          if (erecover.toLowerCase() !== account?.toLowerCase()) {
            return Promise.reject(new Error('XMTP: Invalid signature'));
          }

          return toUtf8Bytes(sig);
        },
        getChainId: () => BigInt(chainId),
      };

      return signer;
    }, [account, library]
  );

  return useCallback(
    (options?: ClientOptions) => Client.create(mlsSigner, encryptionBytes, {
      env: 'dev',
      dbPath: `/db-data/dev/mls-client-${account}.db3`,
      disableAutoRegister: true,
      loggingLevel: 'trace',
      ...(options || {}),
    }),
    [account, mlsSigner]
  );
};

then when I try to initialize the client with

    const initializeClient = async () => {
      try {
        const client = await createClient(options);
        const isRegistered = await client.isRegistered();

        if (!isRegistered) {
          // @todo: figure out why this step always fails
          // to "Signature validation failed"
          await client.register();
        }
      } catch (error) {
        console.error('XMTP', error);
      } finally {
        // teminate initialization
      }
    };

It always land to “Signature error Signature validation failed”
you can notice I explictly set disableAutoRegister: true, to force client to be created before it fails and try to exploit the client (even with the error).

Though, I’d like to get this registration step to succeed, I’ve been searching for this error but it seems to be in the server side (the node-go implementation as of my understanding)

// Tests that signature verification works for a given message and keys.
func TestStaticSignatureRoundTrip(t *testing.T) {
	require.True(t, isValid, "Signature validation failed")
	sig, _ := crypto.SignatureFromBytes(bSig)

do you have any idea of what’s happening? and most of all how can i get it fixed?

thank you

hey @irzhy, can you provide the full source code? i suspect that the toUtf8Bytes may be causing the issue.

on another note, getChainId is not a necessary property of the Signer when using a standard wallet.

Has the problem been resolved? I’m having the same problem.

@rygine @irzhy

1 Like

you are totally right. it was the toUtf8Bytes which is wrongly used here I think.

I had to use a different function so that the input is formatted as hex to bytes instead of passing by UTF-8.

Problem solved with

          return new Uint8Array(
            sig.replace(/^0x/, '')
              .match(/\w{1,2}/g)
              .map((h: string) => parseInt(h, 16))

as replacement of toUtf8Bytes

1 Like