litContracts.addPermittedAction fails for certain IPFS IDs
Is there an existing issue for this?
- [X] 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
addPermittedAction tries to decode CID as base58:
https://github.com/LIT-Protocol/js-sdk/blob/412264bb37ec586785d389fc9a9416f422b91c7f/packages/contracts-sdk/src/lib/contracts-sdk.ts#L1495
https://github.com/LIT-Protocol/js-sdk/blob/412264bb37ec586785d389fc9a9416f422b91c7f/packages/contracts-sdk/src/lib/contracts-sdk.ts#L1709-L1713
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
multiformats library can be used to properly implement getBytesFromMultihash function. CID class from this library provides a way to get the CID as bytes