js-sdk icon indicating copy to clipboard operation
js-sdk copied to clipboard

The signature problem on Integrating with Ceramic

Open 0xja-eth opened this issue 1 year ago • 1 comments

Description

I'm trying to approve for Lit Protocol and Ceramic with just one signature. I've managed to do so, but there might be some issues with my solution. I'll describe my problems here and discuss if there's a better approach, or whether it's possible to optimize the code of Lit or Ceramic to better address these issues.

Technical Information

My approach is as follows: first, I call Ceramic's authorization, with the code as below:

const accountId = await getAccountId(ethProvider, address)
      
const authMethod = await getAuthMethod(ethProvider, accountId)
console.log("[AuthCeramic] Authorize", authMethod)

session = await DIDSession.authorize(authMethod, {resources: ["ceramic://*"]})

After the user signs, they get a session as a login credential. In Lit Protocol, similar to session, there's a data structure called AuthSig as a login credential. The structure of AuthSig is as follows:

interface AuthSig {
    sig: any; // Data after signing
    derivedVia: string; // Generally "web3.eth.personal.sign"
    signedMessage: string; // Data before signing
    address: string; // Signing address
}

Actually, session and AuthSig are somewhat interchangeable to a certain extent. Below is my conversion code:

async function getAuthSig(session, chainId = TargetChainId) {
  const {p, s} = session.cacao;
  const address = p.iss.split(":").pop();

  const message = new SiweMessage({
    domain: p.domain, address, 
    statement: p.statement,
    uri: p.aud,
    version: p.version,
    nonce: p.nonce,
    issuedAt: p.iat,
    expirationTime: p.exp,
    chainId: chainId.toString(),
    resources: p.resources,
  })

  return {
    address, derivedVia: "web3.eth.personal.sign",
    sig: s.s, signedMessage: message.toMessage(),
  } as AuthSig
}

Therefore, we can convert the session obtained after authorizing Ceramic into AuthSig and set it in LocalStorage, to authorize Lit:

const LitAuthSigKey = "lit-auth-signature"
const LitProviderKey = "lit-web3-provider"
const LitDefaultProvider = "metamask"

if (authSig) { // Set the default authSig in advance to avoid reconnecting and re-signing
  setLocalStorage(LitProviderKey, LitDefaultProvider)
  setLocalStorage(LitAuthSigKey, authSig)
}
authSig = await LitJsSdk.checkAndSignAuthMessage({
  chain: Chain
});

// Do some encryption/decryptions ....
const res = await LitJsSdk.decryptToString({
  authSig, chain: Chain, ...
}, lit)

This is my approach.

Solution Problem

There's a problem with the above solution, which is the issue of case sensitivity in the address in the signature information.

In the signature information of Ceramic, the address is converted to lowercase, here's an example:

localhost wants you to sign in with your Ethereum account:
0x66d369e52b1a7ee16.......f84025

Give this application access to some of your data on Ceramic

URI: did:key:z6Mkofcp......pnsDJ26j
Version: 1
Chain ID: 1
Nonce: 1CjSZZjMv2
Issued At: 2023-11-15T08:13:19.690Z
Expiration Time: 2023-11-22T08:13:19.690Z
Resources:
- ceramic://*

However, when we convert this signature into AuthSig and authenticate it in Lit, it says that the address does not conform to the EIP-55 format: a1fbbbbb99c57d8ab7f2f9a94c12187 And this is the request data: image

Therefore, I have to insert the following statement in the first section of the code to ensure that the address in the signature information is in EIP-55 format:

const accountId = await getAccountId(ethProvider, address)
accountId.address = address // Prevent the lowercase address

Only then can I successfully authorize Lit. But after converting to EIP-55, the generated PKH-DID looks like this: did:pkh:eip155:1:0x66d369E52b1A7ee16D65e6a052745561C1f84025, which contains case sensitivity, and that's the problem:

  • If I keep the address lowercase, the generated DID is normal and conforms to the rules, but Lit cannot be successfully authorized.
  • If I retain the case sensitivity, I can successfully authorize Lit, but the generated DID will also retain the case sensitivity, but it seems to be able to be used normally in Ceramic.

Therefore, I wonder if there is a better solution, or whether it's possible to make some modifications to Ceramic or Lit to solve this problem?

I have also opened the same issue in Ceramic: https://github.com/ceramicnetwork/js-did/issues/173

0xja-eth avatar Nov 15 '23 18:11 0xja-eth

for anyone who finds this in the future. check out the above linked thread on the Ceramic repo for our discussion about this issue

glitch003 avatar Nov 24 '23 18:11 glitch003