Skip to content

litContracts.addPermittedAction fails for certain IPFS IDs #763

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
1 task done
ranile opened this issue Jan 13, 2025 · 2 comments
Open
1 task done

litContracts.addPermittedAction fails for certain IPFS IDs #763

ranile opened this issue Jan 13, 2025 · 2 comments

Comments

@ranile
Copy link

ranile commented Jan 13, 2025

Is there an existing issue for this?

  • I have searched the existing issues

SDK version

@lit-protocol/[email protected]
@lit-protocol/[email protected]

Lit Network

datil-test

Description of the bug/issue

When addPermittedAction is called with some IPFS CIDs, it fails with the following error:

/Users/me/code/lit-custom-auth/node_modules/@ethersproject/basex/src.ts/index.ts:112
                throw new Error("Non-base" + this.base + " character");
                      ^
Error: Non-base58 character
    at BaseX.decode (/Users/me/code/lit-custom-auth/node_modules/@ethersproject/basex/src.ts/index.ts:112:23)
    at Object.getBytesFromMultihash (/Users/me/code/lit-custom-auth/packages/contracts-sdk/src/lib/contracts-sdk.ts:1710:43)
    at LitContracts.addPermittedAction (/Users/me/code/lit-custom-auth/packages/contracts-sdk/src/lib/contracts-sdk.ts:1495:36)
    at main (file:///Users/me/code/lit-custom-auth/apps/backend/src/main.ts:137:56)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at file:///Users/me/code/lit-custom-auth/apps/backend/src/main.ts:145:1

Severity of the bug

N/A

Steps To Reproduce

The following code will result in the error:

export const litActionCode = `(async () => {
  const tokenId = await Lit.Actions.pubkeyToTokenId({ publicKey: pkpPublicKey });
  const permittedAuthMethods = await Lit.Actions.getPermittedAuthMethods({ tokenId });
  const isPermitted = permittedAuthMethods.some((permittedAuthMethod) => {
    if (permittedAuthMethod["auth_method_type"] === "0x15f85" &&
        permittedAuthMethod["id"] === customAuthMethod.authMethodId) {
      return true;
    }
    return false;
  });
  LitActions.setResponse({ response: isPermitted ? "true" : "false" });
})();`;
const SELECTED_LIT_NETWORK = LIT_NETWORK.DatilTest

const litNodeClient = new LitNodeClientNodeJs({
  alertWhenUnauthorized: false,
  litNetwork: SELECTED_LIT_NETWORK,
  debug: true
});
await litNodeClient.connect()

const ethersWallet = new ethers.Wallet(
  ETHEREUM_PRIVATE_KEY,
  new ethers.providers.JsonRpcProvider(LIT_RPC.CHRONICLE_YELLOWSTONE)
);

const litContracts = new LitContracts({
  signer: ethersWallet,
  network: SELECTED_LIT_NETWORK,
  debug: false
});
await litContracts.connect();

const stringToCidV0 = async (input: string) => {
  const bytes = new TextEncoder().encode(input)

  const fs = unixfs({ blockstore: new BlackHoleBlockstore() })
  const cid = await fs.addBytes(bytes, { cidVersion: 0 })
  console.log('!!cid', cid); // !!cid CID(bafkreih5onejzpifwy7j3gna37z7i4hi35x4svml4dbilsucaeifi4o5ba)
  return cid
}

async function main() {
  const { pkp } = await litContracts.pkpNftContractUtils.write.mint();

  const authMethodAddReciept = await litContracts.addPermittedAuthMethod({
    pkpTokenId: pkp.tokenId,
    authMethodType: customAuthMethod.authMethodType,
    authMethodId: customAuthMethod.authMethodId,
    authMethodScopes: [AUTH_METHOD_SCOPE.SignAnything],
  });

  const ipfsCid = await stringToCidV0(litActionCode);
  const permittedActionAddReciept = await litContracts.addPermittedAction({
    ipfsId: ipfsCid.toString(),
    pkpTokenId: pkp.tokenId,
    authMethodScopes: [AUTH_METHOD_SCOPE.SignAnything],
  });
  console.log('done????');
}

await main()

Link to code

No response

Anything else?

This is workaroundable (at least for aforementioned lit actions code) by using an ancient library that's used in the examples as well (ipfs-only-hash). The lit actions code is taken from the custom-auth example

@ranile
Copy link
Author

ranile commented Jan 13, 2025

addPermittedAction tries to decode CID as base58:

const ipfsIdBytes = this.utils.getBytesFromMultihash(ipfsId);

getBytesFromMultihash: (multihash: string) => {
const decoded = ethers.utils.base58.decode(multihash);
return `0x${Buffer.from(decoded).toString('hex')}`;
},

This is wrong: Only v0 CIDs are guaranteed base58 (which explains why the ipfs-only-hash library works). V1 CIDs may be base58 but as shown in this issue, this would cause problems:

// this snippet errors

// litActionCode is same as one from "steps to reproduce"
const ipfsCid = await stringToCidV0(litActionCode);
ethers.utils.base58.decode(ipfsCid.toString())

However, this is sucessful:

const code = `(async () => { return LitActions.setResponse({ response: "true" }) })()`;
const ipfsCid = await stringToCidV0(code); // !!cid CID(bafkreifo6c37kt36n7xx27nvpt7mkiqb5ocdxvn62abcdfcnvwdfad3pfe)
const base58 = ethers.utils.base58.decode(ipfsCid.toString());
console.log('!!base58', base58.length); // !!base58 44

@ranile
Copy link
Author

ranile commented Jan 13, 2025

multiformats library can be used to properly implement getBytesFromMultihash function. CID class from this library provides a way to get the CID as bytes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant