Hi, I encountered an issue when trying to make mutation with Coinbase Smart Wallet.
The error thrown is as follow:
{"error":"Can not verify signature for commit bagcqcerahsfrazlqhkf24arkmujhzcesgsv5nwgchhrupmdylmt5amxswbzq to stream k2t6wzhkhabz1sdy28cfzy1niwdej1anze020pzap6ur6l32kui61hyyhro8zj which has controller DID did:pkh:eip155:84532:0x5e165d772b940178966a7ed155b99050dffbec40: invalid signature string (argument=\"signature\", value=\"0x000000000000000000000000ca11bde05977b3631167028862be2a173976ca110000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000001e482ad56cb0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000ba5ed0c6aa8c49038f819e587e2633c4a9f428a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e43ffba36f0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004024a02452ba731ad67f5510ad5daf632c689485a6296a310c69f702b57fa091d972031cb82784f2fb7d73bf41269dcafa280a335e569a5f8f36d52258b218e98e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000016072f5600a5f28264cbaaede083d456467e942329f038df080eaf60fed2bcee87b0917975318c1b3bea219a4fdcf3333a9f473a37f2c9326b23b3c4ae1685f7a0000000000000000000000000000000000000000000000000000000000000025f198086b2db17256731bc456673b96bcef23f51d1fbacdd7c4379ef65465572f1d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008a7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a226d6150583363643742783441714e4f6f486470496331504366614b574c677276766d76426378756c315a45222c226f726967696e223a2268747470733a2f2f6b6579732e636f696e626173652e636f6d222c2263726f73734f726967696e223a66616c73657d000000000000000000000000000000000000000000006492649264926492649264926492649264926492649264926492649264926492\", code=INVALID_ARGUMENT, version=bytes/5.7.0)"}
After connecting Coinbase Smart Wallet, I am able to create Ceramic session for the wallet as well. The error only happens when I tried to submit mutation.
For more context, I am using Thirdweb SDK to handle login options. Metamask wallet, Coinbase EOA wallet and Thirdweb embedded wallet (MPC) work fine.
I am not sure if I should handle smart wallet differently or which part went wrong.
I appreciate any help or suggestion thanks!
The code below is how I handle DID session:
/**
* Checks localStorage for a stored DID Session. If one is found we authenticate it, otherwise we create a new one.
* @returns Promise<DID-Session> - The User's authenticated sesion.
*/
export const authenticateCeramic = async (
ceramic: CeramicClient,
compose: ComposeClient,
provider: any,
onDone?: () => void,
) => {
const processedProvider = processProvider(provider);
authenticateEthPKH(ceramic, compose, processedProvider, onDone);
};
const authenticateEthPKH = async (
ceramic: CeramicClient,
compose: ComposeClient,
provider: any,
onDone?: () => void,
) => {
const sessionStr = localStorage.getItem(CERAMIC_SESSION_KEY); // for production you will want a better place than localStorage for your sessions.
let session;
if (sessionStr) {
session = await DIDSession.fromSession(sessionStr);
}
if (!session || (session.hasSession && session.isExpired)) {
/** If provider isn't passed we use window.ethereum */
if (!provider) {
if (window.ethereum) {
console.log("in authenticateCeramic func: You need to pass the provider as an argument in the `authenticateCeramic()` function. We will be using window.ethereum by default.");
provider = window.ethereum;
} else {
console.error("ERROR in authenticateCeramic func: no provider args passed and no window.ethereum found.");
return false;
}
}
// We enable the ethereum provider to get the user's addresses.
// request ethereum accounts.
const addresses = await provider.enable({
method: "eth_requestAccounts",
});
const accountId = await getAccountId(provider, addresses[0]);
const authMethod = await EthereumWebAuth.getAuthMethod(provider, accountId);
/**
* Create DIDSession & provide capabilities for resources that we want to access.
* @NOTE: The specific resources (ComposeDB data models) are provided through
* "compose.resources" below.
*/
session = await DIDSession.authorize(authMethod, {
// resources: [`ceramic://*`],
resources: compose.resources,
expiresInSecs: threeMonths
});
console.log({ session }, session.serialize())
// Set the session in localStorage.
localStorage.setItem(CERAMIC_SESSION_KEY, session.serialize());
}
// Set our Ceramic DID to be our session DID.
ceramic.did = session.did;
compose.setDID(session.did);
if (onDone) {
onDone();
}
return;
};
const processProvider = (signer: any) => {
const provider = signer?.provider;
provider.enable = async () => [await signer.getAddress()];
provider.request = async (payload: any) => {
if (payload.method === "personal_sign") {
const message = payload.params[0];
if (/^(0x)?[0-9A-Fa-f]+$/i.test(message)) {
const bufferMessage = Buffer.from(
message.startsWith("0x") ? message.slice(2) : message,
"hex"
);
return signer.signMessage(bufferMessage);
}
return signer.signMessage(message);
}
return provider.send(payload.method, payload.params || []);
};
return provider;
};