ourzora / zora-protocol

Monorepo for Zora Protocol (contracts & sdks)
MIT License
113 stars 70 forks source link

Premint SDK uses `Address` instead of `Account` for `signTypedData` input, which results in error when signing #398

Closed stephancill closed 7 months ago

stephancill commented 8 months ago

Error & Repro

I have the following setup for creating premints on behalf of another account:

const adminAccount = privateKeyToAccount(
  process.env.ZORA_ADMIN_PRIVATE_KEY as `0x${string}`
);

const contractAdminWallet = createWalletClient({
  chain: zora,
  account: adminAccount,
  transport: http(),
});

const premintClient = createPremintClient({
  chain: zora,
});

const collection = {
  contractAdmin: adminAccount.address,
  contractName: title,
  // Collection metadata same as token metadata
  contractURI: tokenMetadataURI,
};

const premint = await premintClient.createPremint({
  premintConfigVersion: PremintConfigVersion.V2,
  checkSignature: true,
  collection,
  creatorAccount: contractAdminWallet.account.address,
  walletClient: contractAdminWallet,
  tokenCreationConfig: {
    tokenURI: tokenMetadataURI,
    payoutRecipient: creator.address,
    // TODO: createReferral: mod creator address,
  },
});

On submit, I get a viem error:

...
api:dev:     shortMessage: 'RPC Request failed.',
api:dev:     version: 'viem@1.20.0',
api:dev:     cause: {
api:dev:       code: -32601,
api:dev:       message: 'the method eth_signTypedData_v4 does not exist/is not available'
api:dev:     },

What's wrong

When you pass a string instead of an Account to the account parameter of viem's walletClient.signTypedData, it falls back to being constructed as JSON RPC Account object rather than the more appropriate local account type, which is the condition for the signature to work with local accounts as mentioned in the docs:

Screenshot 2024-01-11 at 19 51 23

Solution

The solution is to explicitly pass the full Account object to the walletClient.signTypedData call here: https://github.com/ourzora/zora-protocol/blob/main/packages/protocol-sdk/src/premint/premint-client.ts#L669C10-L676

One way of doing that (which is potentially also the most flexible) would most likely be to accept an Account | Address here: https://github.com/ourzora/zora-protocol/blob/main/packages/protocol-sdk/src/premint/premint-client.ts#L328 and handle the differences downstream.

Let me know if I can provide more info

jellohouse commented 8 months ago

I'm in the exact same situation - Hopefully this gets fixed soon!

corbinpage commented 8 months ago

So am I. When will this be resolved? 😢

stephancill commented 8 months ago

@jellohouse @corbinpage this patch is what fixed it for our use case (we're only using local accounts). might be of use to you https://github.com/mod-protocol/mod/blob/main/patches/%40zoralabs%2Bprotocol-sdk%2B0.5.0.patch

jellohouse commented 8 months ago

Ok thanks - yes that works for now :)

iainnash commented 7 months ago

Hey! We've totally missed this and can integrate a fix soon.

iainnash commented 7 months ago

Fixed with https://www.npmjs.com/package/@zoralabs/protocol-sdk/v/0.5.3