diff --git a/local-tests/test.ts b/local-tests/test.ts index 431460344b..a96b93ce87 100644 --- a/local-tests/test.ts +++ b/local-tests/test.ts @@ -108,6 +108,7 @@ import { testBatchGeneratePrivateKeys } from './tests/wrapped-keys/testBatchGene import { setLitActionsCodeToLocal } from './tests/wrapped-keys/util'; import { testUseEoaSessionSigsToRequestSingleResponse } from './tests/testUseEoaSessionSigsToRequestSingleResponse'; +import { testUseTriaAuthAndWrappedKeysSessionSigsGen } from './tests/testUseTriaAuthAndWrappedKeysSessionSigsGen'; // Use the current LIT action code to test against setLitActionsCodeToLocal(); @@ -171,7 +172,10 @@ setLitActionsCodeToLocal(); testUseEoaSessionSigsToEncryptDecryptString, testUseEoaSessionSigsToEncryptDecryptFile, testUseEoaSessionSigsToEncryptDecryptZip, + + // single node execution testUseEoaSessionSigsToRequestSingleResponse, + testUseTriaAuthAndWrappedKeysSessionSigsGen, }; const pkpSessionSigsTests = { diff --git a/local-tests/tests/testUseTriaAuthAndWrappedKeysSessionSigsGen.ts b/local-tests/tests/testUseTriaAuthAndWrappedKeysSessionSigsGen.ts new file mode 100644 index 0000000000..688b7f27a7 --- /dev/null +++ b/local-tests/tests/testUseTriaAuthAndWrappedKeysSessionSigsGen.ts @@ -0,0 +1,112 @@ +import { LitActionResource, LitPKPResource } from '@lit-protocol/auth-helpers'; +import { log } from '@lit-protocol/misc'; +import { LitAbility } from '@lit-protocol/types'; +import { + getLitActionSessionSigs, + getLitActionSessionSigsUsingIpfsId, +} from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; +import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; +import { api, utils } from '@lit-protocol/wrapped-keys'; + +import Hash from "typestub-ipfs-only-hash"; +import { AuthMethodScope } from '@lit-protocol/constants'; + +const { triaBatchGeneratePrivateKeys, exportPrivateKey } = api; +/** + * Test Commands: + * ✅ NETWORK=datil-dev yarn test:local --filter=testUseTriaAuthAndWrappedKeysSessionSigsGen + * ✅ NETWORK=datil-test yarn test:local --filter=testUseTriaAuthAndWrappedKeysSessionSigsGen + * ✅ NETWORK=datil yarn test:local --filter=testUseTriaAuthAndWrappedKeysSessionSigsGen + */ +export const testUseTriaAuthAndWrappedKeysSessionSigsGen = async ( + devEnv: TinnyEnvironment +) => { + const alice = await devEnv.createRandomPerson(); + + // -- Start + const triaAuthMethod = { + // authMethodId: '', <-- Tria's managing this by permitting auth method to the user id + authMethodType: process.env.TRIA_AUTHMETHOD_TYPE, + accessToken: process.env.TRIA_ACCESS_TOKEN, + }; + + // -- mint a pkp + console.log(`🔄 Minting new PKP...`); + const pkpMintRes = + await devEnv.contractsClient.pkpNftContractUtils.write.mint(); + const pkp = pkpMintRes.pkp; + console.log(` ✅ PKP minted:`); + console.log(` - Token ID: ${pkp.tokenId}`); + console.log(` - Public Key: ${pkp.publicKey}`); + console.log(` - ETH Address: ${pkp.ethAddress}`); + + // -- mint capacity token + console.log(`🔄 Minting Capacity Credits NFT...`); + const capacityTokenId = ( + await devEnv.contractsClient.mintCapacityCreditsNFT({ + requestsPerKilosecond: 10, + daysUntilUTCMidnightExpiration: 1, + }) + ).capacityTokenIdStr; + console.log(` ✅ Capacity Credits NFT minted:`); + + // -- create capacity delegation auth sig + console.log(`🔄 Creating Capacity Delegation AuthSig...`); + const authSigResponse = + await devEnv.litNodeClient.createCapacityDelegationAuthSig({ + dAppOwnerWallet: alice.wallet, + capacityTokenId, + delegateeAddresses: [pkp.ethAddress], + uses: '1', + }); + const capacityDelegationAuthSig = authSigResponse.capacityDelegationAuthSig; + console.log(` ✅ Capacity Delegation AuthSig created:`); + console.log(` - AuthSig: ${JSON.stringify(capacityDelegationAuthSig)}`); + console.log(` - Uses: 1`); + console.log(` - Delegatee Address: ${pkp.ethAddress}`); + console.log(` - Capacity Token ID: ${capacityTokenId}`); + + // -- Get the lit action code.. + const { litActionCode, litActionIpfsCid } = utils.getLitActionCodeOrCidCommon( + 'tria_batchGenerateEncryptedKeys' + ); + + // -- detect which one we got + const hashOfLitActionCode = litActionCode + ? await Hash.of(Buffer.from(litActionCode)) + : litActionIpfsCid; + console.log(` ✅ Lit Action Code IPFS CID: ${hashOfLitActionCode}`); + + console.log(`🔄 Adding permitted action...`); + const permitTx = await devEnv.contractsClient.addPermittedAction({ + ipfsId: hashOfLitActionCode, + pkpTokenId: pkp.tokenId, + authMethodScopes: [AuthMethodScope.SignAnything] + }); + console.log(` ✅ Permitted action added:`); + console.log(` - Transaction Hash: ${permitTx.transactionHash}`); + + const solanaMessageToSign = 'This is a test solana message'; + const evmMessageToSign = 'This is a test evm message'; + + const { results } = await triaBatchGeneratePrivateKeys({ + pkpPublicKey: pkp.publicKey, + ipfsId: hashOfLitActionCode, + actions: [ + { + network: 'evm', + signMessageParams: { messageToSign: evmMessageToSign }, + generateKeyParams: { memo: 'Test evm key' }, + }, + { + network: 'solana', + signMessageParams: { messageToSign: solanaMessageToSign }, + generateKeyParams: { memo: 'Test solana key' }, + }, + ], + litNodeClient: devEnv.litNodeClient, + authMethod: triaAuthMethod, + }); + + console.log("results:", results); +}; diff --git a/local-tests/tests/wrapped-keys/util.ts b/local-tests/tests/wrapped-keys/util.ts index 4f3573fe33..c20a9087dd 100644 --- a/local-tests/tests/wrapped-keys/util.ts +++ b/local-tests/tests/wrapped-keys/util.ts @@ -15,6 +15,8 @@ import type { const emptyLitActionRepositoryCommon: LitActionCodeRepositoryCommon = { batchGenerateEncryptedKeys: '', + + tria_batchGenerateEncryptedKeys: '', }; const emptyLitActionRepository: LitActionCodeRepository = { diff --git a/package.json b/package.json index fad1755fd2..7a947b8eda 100644 --- a/package.json +++ b/package.json @@ -79,6 +79,7 @@ "tslib": "^2.3.0", "tweetnacl": "^1.0.3", "tweetnacl-util": "^0.15.1", + "typestub-ipfs-only-hash": "^4.0.0", "uint8arrays": "^4.0.3" }, "devDependencies": { diff --git a/packages/misc/src/index.ts b/packages/misc/src/index.ts index 88be5e3cc5..bb180364ca 100644 --- a/packages/misc/src/index.ts +++ b/packages/misc/src/index.ts @@ -2,5 +2,10 @@ export * from './lib/misc'; export { validateSessionSig, validateSessionSigs, + parseSignedMessage, } from './lib/helper/session-sigs-validator'; -export { formatSessionSigs } from './lib/helper/session-sigs-reader'; +export { + formatSessionSigs, + formatSessionSigsJSON, + getResourcesFromSessionSigs +} from './lib/helper/session-sigs-reader'; diff --git a/packages/misc/src/lib/helper/session-sigs-reader.test.ts b/packages/misc/src/lib/helper/session-sigs-reader.test.ts index dc34aab025..aee39f95ac 100644 --- a/packages/misc/src/lib/helper/session-sigs-reader.test.ts +++ b/packages/misc/src/lib/helper/session-sigs-reader.test.ts @@ -1,4 +1,4 @@ -import { formatSessionSigs } from './session-sigs-reader'; +import { formatSessionSigs, formatSessionSigsJSON } from './session-sigs-reader'; describe('formatSessionSigs', () => { it('should format session signatures correctly', () => { @@ -81,3 +81,74 @@ describe('formatSessionSigs', () => { expect(formattedSessionSigs).toBe(expectedOutput); }); }); + + +describe('formatSessionSigsJson', () => { + + const sessionSigs = { + 'https://178.162.172.88:443': { + sig: 'd8d1311def1e6bfa2dd8ec79fee7f7ba3e770e1b0f2841c13db2a3196febf47b857c48575fd8f2a478c0364cffa9d478f0b0479c784b04f010f0f6fc97a61f09', + derivedVia: 'litSessionSignViaNacl', + signedMessage: `{"sessionKey":"09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0","resourceAbilityRequests":[{"resource":{"resource":"*","resourcePrefix":"lit-pkp"},"ability":"pkp-signing"},{"resource":{"resource":"*","resourcePrefix":"lit-litaction"},"ability":"lit-action-execution"}],"capabilities":[{"sig":"{\\"ProofOfPossession\\":\\"838cf437fa58c2bb7e5c183bd2b184e4ed9da595bdb9bffa34019ca9b47e93f64b83d464eb9237297a829d1aa333560b0d6c55910631334bd9249cc826f8dcbf202f5f2d7d1ec67ec894a0b36b616cabb74f3e582e8b37089b9abdabbfa17e0d\\"}","algo":"LIT_BLS","derivedVia":"lit.bls","signedMessage":"litprotocol.com wants you to sign in with your Ethereum account:\\n0xa19355DD0C6aDfD02a0F8C2B70A26DF4cECea166\\n\\nLit Protocol PKP session signature I further authorize the stated URI to perform the following actions on my behalf: I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Execution' for 'lit-litaction://*'. (2) 'Threshold': 'Signing' for 'lit-pkp://*'. I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Execution' for 'lit-litaction://*'. (2) 'Threshold': 'Signing' for 'lit-pkp://*'. (3) 'Auth': 'Auth' for 'lit-resolvedauthcontext://*'.\\n\\nURI: lit:session:09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0\\nVersion: 1\\nChain ID: 1\\nNonce: 0x244bc2b37cf85c94f37206c2ca0769db6bd353f2795f5b6894829068ad8c8542\\nIssued At: 2024-10-11T18:59:23Z\\nExpiration Time: 2024-10-12T18:59:52.424Z\\nResources:\\n- urn:recap:eyJhdHQiOnsibGl0LWxpdGFjdGlvbjovLyoiOnsiVGhyZXNob2xkL0V4ZWN1dGlvbiI6W3t9XX0sImxpdC1wa3A6Ly8qIjp7IlRocmVzaG9sZC9TaWduaW5nIjpbe31dfSwibGl0LXJlc29sdmVkYXV0aGNvbnRleHQ6Ly8qIjp7IkF1dGgvQXV0aCI6W3siYXV0aF9jb250ZXh0Ijp7ImFjdGlvbklwZnNJZHMiOlsiUW1kNWliQ1JvOURoRW5qY21mQnNNVTZxUkJDdk1DWnc1a0I3b1N2Q2E3aVhEUiJdLCJhdXRoTWV0aG9kQ29udGV4dHMiOltdLCJhdXRoU2lnQWRkcmVzcyI6bnVsbCwiY3VzdG9tQXV0aFJlc291cmNlIjoiKHRydWUsICdBbnl0aGluZyB5b3VyIHdhbnQgdG8gdXNlIGluIGV4ZWN1dGVKcycpIiwicmVzb3VyY2VzIjpbXX19XX19LCJwcmYiOltdfQ","address":"0xa19355DD0C6aDfD02a0F8C2B70A26DF4cECea166"}],"issuedAt":"2024-10-11T18:59:53.489Z","expiration":"2024-10-12T18:59:52.424Z","nodeAddress":"https://178.162.172.88:443"}`, + address: '09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0', + algo: 'ed25519' + }, + 'https://104.245.147.218:443': { + sig: 'f4133963d987cebb05d889488865237e28ee29d86e5de7f0f08b07eb246c6e614a8ac2042431ad5cb8944f9583556838fdfe8d200ba86e620a5351d37119b705', + derivedVia: 'litSessionSignViaNacl', + signedMessage: `{"sessionKey":"09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0","resourceAbilityRequests":[{"resource":{"resource":"*","resourcePrefix":"lit-pkp"},"ability":"pkp-signing"},{"resource":{"resource":"*","resourcePrefix":"lit-litaction"},"ability":"lit-action-execution"}],"capabilities":[{"sig":"{\\"ProofOfPossession\\":\\"838cf437fa58c2bb7e5c183bd2b184e4ed9da595bdb9bffa34019ca9b47e93f64b83d464eb9237297a829d1aa333560b0d6c55910631334bd9249cc826f8dcbf202f5f2d7d1ec67ec894a0b36b616cabb74f3e582e8b37089b9abdabbfa17e0d\\"}","algo":"LIT_BLS","derivedVia":"lit.bls","signedMessage":"litprotocol.com wants you to sign in with your Ethereum account:\\n0xa19355DD0C6aDfD02a0F8C2B70A26DF4cECea166\\n\\nLit Protocol PKP session signature I further authorize the stated URI to perform the following actions on my behalf: I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Execution' for 'lit-litaction://*'. (2) 'Threshold': 'Signing' for 'lit-pkp://*'. I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Execution' for 'lit-litaction://*'. (2) 'Threshold': 'Signing' for 'lit-pkp://*'. (3) 'Auth': 'Auth' for 'lit-resolvedauthcontext://*'.\\n\\nURI: lit:session:09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0\\nVersion: 1\\nChain ID: 1\\nNonce: 0x244bc2b37cf85c94f37206c2ca0769db6bd353f2795f5b6894829068ad8c8542\\nIssued At: 2024-10-11T18:59:23Z\\nExpiration Time: 2024-10-12T18:59:52.424Z\\nResources:\\n- urn:recap:eyJhdHQiOnsibGl0LWxpdGFjdGlvbjovLyoiOnsiVGhyZXNob2xkL0V4ZWN1dGlvbiI6W3t9XX0sImxpdC1wa3A6Ly8qIjp7IlRocmVzaG9sZC9TaWduaW5nIjpbe31dfSwibGl0LXJlc29sdmVkYXV0aGNvbnRleHQ6Ly8qIjp7IkF1dGgvQXV0aCI6W3siYXV0aF9jb250ZXh0Ijp7ImFjdGlvbklwZnNJZHMiOlsiUW1kNWliQ1JvOURoRW5qY21mQnNNVTZxUkJDdk1DWnc1a0I3b1N2Q2E3aVhEUiJdLCJhdXRoTWV0aG9kQ29udGV4dHMiOltdLCJhdXRoU2lnQWRkcmVzcyI6bnVsbCwiY3VzdG9tQXV0aFJlc291cmNlIjoiKHRydWUsICdBbnl0aGluZyB5b3VyIHdhbnQgdG8gdXNlIGluIGV4ZWN1dGVKcycpIiwicmVzb3VyY2VzIjpbXX19XX19LCJwcmYiOltdfQ","address":"0xa19355DD0C6aDfD02a0F8C2B70A26DF4cECea166"}],"issuedAt":"2024-10-11T18:59:53.489Z","expiration":"2024-10-12T18:59:52.424Z","nodeAddress":"https://104.245.147.218:443"}`, + address: '09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0', + algo: 'ed25519' + }, + 'https://184.107.182.142:443': { + sig: 'ae98fca36a1059cd5cbe7578ff94f777cb89e5fb642f8e5e709328e8a2753768925bf203650fcde83a8691e6e2bee1dc80b6fd71714a1c5d1d7f06d6356b1a0a', + derivedVia: 'litSessionSignViaNacl', + signedMessage: `{"sessionKey":"09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0","resourceAbilityRequests":[{"resource":{"resource":"*","resourcePrefix":"lit-pkp"},"ability":"pkp-signing"},{"resource":{"resource":"*","resourcePrefix":"lit-litaction"},"ability":"lit-action-execution"}],"capabilities":[{"sig":"{\\"ProofOfPossession\\":\\"838cf437fa58c2bb7e5c183bd2b184e4ed9da595bdb9bffa34019ca9b47e93f64b83d464eb9237297a829d1aa333560b0d6c55910631334bd9249cc826f8dcbf202f5f2d7d1ec67ec894a0b36b616cabb74f3e582e8b37089b9abdabbfa17e0d\\"}","algo":"LIT_BLS","derivedVia":"lit.bls","signedMessage":"litprotocol.com wants you to sign in with your Ethereum account:\\n0xa19355DD0C6aDfD02a0F8C2B70A26DF4cECea166\\n\\nLit Protocol PKP session signature I further authorize the stated URI to perform the following actions on my behalf: I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Execution' for 'lit-litaction://*'. (2) 'Threshold': 'Signing' for 'lit-pkp://*'. I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Execution' for 'lit-litaction://*'. (2) 'Threshold': 'Signing' for 'lit-pkp://*'. (3) 'Auth': 'Auth' for 'lit-resolvedauthcontext://*'.\\n\\nURI: lit:session:09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0\\nVersion: 1\\nChain ID: 1\\nNonce: 0x244bc2b37cf85c94f37206c2ca0769db6bd353f2795f5b6894829068ad8c8542\\nIssued At: 2024-10-11T18:59:23Z\\nExpiration Time: 2024-10-12T18:59:52.424Z\\nResources:\\n- urn:recap:eyJhdHQiOnsibGl0LWxpdGFjdGlvbjovLyoiOnsiVGhyZXNob2xkL0V4ZWN1dGlvbiI6W3t9XX0sImxpdC1wa3A6Ly8qIjp7IlRocmVzaG9sZC9TaWduaW5nIjpbe31dfSwibGl0LXJlc29sdmVkYXV0aGNvbnRleHQ6Ly8qIjp7IkF1dGgvQXV0aCI6W3siYXV0aF9jb250ZXh0Ijp7ImFjdGlvbklwZnNJZHMiOlsiUW1kNWliQ1JvOURoRW5qY21mQnNNVTZxUkJDdk1DWnc1a0I3b1N2Q2E3aVhEUiJdLCJhdXRoTWV0aG9kQ29udGV4dHMiOltdLCJhdXRoU2lnQWRkcmVzcyI6bnVsbCwiY3VzdG9tQXV0aFJlc291cmNlIjoiKHRydWUsICdBbnl0aGluZyB5b3VyIHdhbnQgdG8gdXNlIGluIGV4ZWN1dGVKcycpIiwicmVzb3VyY2VzIjpbXX19XX19LCJwcmYiOltdfQ","address":"0xa19355DD0C6aDfD02a0F8C2B70A26DF4cECea166"}],"issuedAt":"2024-10-11T18:59:53.489Z","expiration":"2024-10-12T18:59:52.424Z","nodeAddress":"https://184.107.182.142:443"}`, + address: '09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0', + algo: 'ed25519' + }, + 'https://23.82.129.77:443': { + sig: 'e666f0bac0633a2d262e252cfa5d7746084f32a9c75e79a8ed9781a73fde1767c999d1e7898432f3653867ef182a17f013810c5b2d85e87ab0695b7b5cf63b0c', + derivedVia: 'litSessionSignViaNacl', + signedMessage: `{"sessionKey":"09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0","resourceAbilityRequests":[{"resource":{"resource":"*","resourcePrefix":"lit-pkp"},"ability":"pkp-signing"},{"resource":{"resource":"*","resourcePrefix":"lit-litaction"},"ability":"lit-action-execution"}],"capabilities":[{"sig":"{\\"ProofOfPossession\\":\\"838cf437fa58c2bb7e5c183bd2b184e4ed9da595bdb9bffa34019ca9b47e93f64b83d464eb9237297a829d1aa333560b0d6c55910631334bd9249cc826f8dcbf202f5f2d7d1ec67ec894a0b36b616cabb74f3e582e8b37089b9abdabbfa17e0d\\"}","algo":"LIT_BLS","derivedVia":"lit.bls","signedMessage":"litprotocol.com wants you to sign in with your Ethereum account:\\n0xa19355DD0C6aDfD02a0F8C2B70A26DF4cECea166\\n\\nLit Protocol PKP session signature I further authorize the stated URI to perform the following actions on my behalf: I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Execution' for 'lit-litaction://*'. (2) 'Threshold': 'Signing' for 'lit-pkp://*'. I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Execution' for 'lit-litaction://*'. (2) 'Threshold': 'Signing' for 'lit-pkp://*'. (3) 'Auth': 'Auth' for 'lit-resolvedauthcontext://*'.\\n\\nURI: lit:session:09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0\\nVersion: 1\\nChain ID: 1\\nNonce: 0x244bc2b37cf85c94f37206c2ca0769db6bd353f2795f5b6894829068ad8c8542\\nIssued At: 2024-10-11T18:59:23Z\\nExpiration Time: 2024-10-12T18:59:52.424Z\\nResources:\\n- urn:recap:eyJhdHQiOnsibGl0LWxpdGFjdGlvbjovLyoiOnsiVGhyZXNob2xkL0V4ZWN1dGlvbiI6W3t9XX0sImxpdC1wa3A6Ly8qIjp7IlRocmVzaG9sZC9TaWduaW5nIjpbe31dfSwibGl0LXJlc29sdmVkYXV0aGNvbnRleHQ6Ly8qIjp7IkF1dGgvQXV0aCI6W3siYXV0aF9jb250ZXh0Ijp7ImFjdGlvbklwZnNJZHMiOlsiUW1kNWliQ1JvOURoRW5qY21mQnNNVTZxUkJDdk1DWnc1a0I3b1N2Q2E3aVhEUiJdLCJhdXRoTWV0aG9kQ29udGV4dHMiOltdLCJhdXRoU2lnQWRkcmVzcyI6bnVsbCwiY3VzdG9tQXV0aFJlc291cmNlIjoiKHRydWUsICdBbnl0aGluZyB5b3VyIHdhbnQgdG8gdXNlIGluIGV4ZWN1dGVKcycpIiwicmVzb3VyY2VzIjpbXX19XX19LCJwcmYiOltdfQ","address":"0xa19355DD0C6aDfD02a0F8C2B70A26DF4cECea166"}],"issuedAt":"2024-10-11T18:59:53.489Z","expiration":"2024-10-12T18:59:52.424Z","nodeAddress":"https://23.82.129.77:443"}`, + address: '09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0', + algo: 'ed25519' + }, + 'https://199.115.115.103:443': { + sig: '887bfe8581c9e50915638d796c10da8560e2a76f29dd83283efb0654ca6375add37dec073ef25ec74dfd9215ad4a37b3bfdf407579fe987154fabd95bff20b0f', + derivedVia: 'litSessionSignViaNacl', + signedMessage: `{"sessionKey":"09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0","resourceAbilityRequests":[{"resource":{"resource":"*","resourcePrefix":"lit-pkp"},"ability":"pkp-signing"},{"resource":{"resource":"*","resourcePrefix":"lit-litaction"},"ability":"lit-action-execution"}],"capabilities":[{"sig":"{\\"ProofOfPossession\\":\\"838cf437fa58c2bb7e5c183bd2b184e4ed9da595bdb9bffa34019ca9b47e93f64b83d464eb9237297a829d1aa333560b0d6c55910631334bd9249cc826f8dcbf202f5f2d7d1ec67ec894a0b36b616cabb74f3e582e8b37089b9abdabbfa17e0d\\"}","algo":"LIT_BLS","derivedVia":"lit.bls","signedMessage":"litprotocol.com wants you to sign in with your Ethereum account:\\n0xa19355DD0C6aDfD02a0F8C2B70A26DF4cECea166\\n\\nLit Protocol PKP session signature I further authorize the stated URI to perform the following actions on my behalf: I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Execution' for 'lit-litaction://*'. (2) 'Threshold': 'Signing' for 'lit-pkp://*'. I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Execution' for 'lit-litaction://*'. (2) 'Threshold': 'Signing' for 'lit-pkp://*'. (3) 'Auth': 'Auth' for 'lit-resolvedauthcontext://*'.\\n\\nURI: lit:session:09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0\\nVersion: 1\\nChain ID: 1\\nNonce: 0x244bc2b37cf85c94f37206c2ca0769db6bd353f2795f5b6894829068ad8c8542\\nIssued At: 2024-10-11T18:59:23Z\\nExpiration Time: 2024-10-12T18:59:52.424Z\\nResources:\\n- urn:recap:eyJhdHQiOnsibGl0LWxpdGFjdGlvbjovLyoiOnsiVGhyZXNob2xkL0V4ZWN1dGlvbiI6W3t9XX0sImxpdC1wa3A6Ly8qIjp7IlRocmVzaG9sZC9TaWduaW5nIjpbe31dfSwibGl0LXJlc29sdmVkYXV0aGNvbnRleHQ6Ly8qIjp7IkF1dGgvQXV0aCI6W3siYXV0aF9jb250ZXh0Ijp7ImFjdGlvbklwZnNJZHMiOlsiUW1kNWliQ1JvOURoRW5qY21mQnNNVTZxUkJDdk1DWnc1a0I3b1N2Q2E3aVhEUiJdLCJhdXRoTWV0aG9kQ29udGV4dHMiOltdLCJhdXRoU2lnQWRkcmVzcyI6bnVsbCwiY3VzdG9tQXV0aFJlc291cmNlIjoiKHRydWUsICdBbnl0aGluZyB5b3VyIHdhbnQgdG8gdXNlIGluIGV4ZWN1dGVKcycpIiwicmVzb3VyY2VzIjpbXX19XX19LCJwcmYiOltdfQ","address":"0xa19355DD0C6aDfD02a0F8C2B70A26DF4cECea166"}],"issuedAt":"2024-10-11T18:59:53.489Z","expiration":"2024-10-12T18:59:52.424Z","nodeAddress":"https://199.115.115.103:443"}`, + address: '09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0', + algo: 'ed25519' + }, + 'https://207.244.66.41:443': { + sig: '37f4e81fb4a410335b322331f49d43a02d38c893042e2a580fcffe781ea17db7ad0b2d83f36afdeb84968d4901f4a47eef02484ed14adbb301c45fc8937bf400', + derivedVia: 'litSessionSignViaNacl', + signedMessage: `{"sessionKey":"09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0","resourceAbilityRequests":[{"resource":{"resource":"*","resourcePrefix":"lit-pkp"},"ability":"pkp-signing"},{"resource":{"resource":"*","resourcePrefix":"lit-litaction"},"ability":"lit-action-execution"}],"capabilities":[{"sig":"{\\"ProofOfPossession\\":\\"838cf437fa58c2bb7e5c183bd2b184e4ed9da595bdb9bffa34019ca9b47e93f64b83d464eb9237297a829d1aa333560b0d6c55910631334bd9249cc826f8dcbf202f5f2d7d1ec67ec894a0b36b616cabb74f3e582e8b37089b9abdabbfa17e0d\\"}","algo":"LIT_BLS","derivedVia":"lit.bls","signedMessage":"litprotocol.com wants you to sign in with your Ethereum account:\\n0xa19355DD0C6aDfD02a0F8C2B70A26DF4cECea166\\n\\nLit Protocol PKP session signature I further authorize the stated URI to perform the following actions on my behalf: I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Execution' for 'lit-litaction://*'. (2) 'Threshold': 'Signing' for 'lit-pkp://*'. I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Execution' for 'lit-litaction://*'. (2) 'Threshold': 'Signing' for 'lit-pkp://*'. (3) 'Auth': 'Auth' for 'lit-resolvedauthcontext://*'.\\n\\nURI: lit:session:09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0\\nVersion: 1\\nChain ID: 1\\nNonce: 0x244bc2b37cf85c94f37206c2ca0769db6bd353f2795f5b6894829068ad8c8542\\nIssued At: 2024-10-11T18:59:23Z\\nExpiration Time: 2024-10-12T18:59:52.424Z\\nResources:\\n- urn:recap:eyJhdHQiOnsibGl0LWxpdGFjdGlvbjovLyoiOnsiVGhyZXNob2xkL0V4ZWN1dGlvbiI6W3t9XX0sImxpdC1wa3A6Ly8qIjp7IlRocmVzaG9sZC9TaWduaW5nIjpbe31dfSwibGl0LXJlc29sdmVkYXV0aGNvbnRleHQ6Ly8qIjp7IkF1dGgvQXV0aCI6W3siYXV0aF9jb250ZXh0Ijp7ImFjdGlvbklwZnNJZHMiOlsiUW1kNWliQ1JvOURoRW5qY21mQnNNVTZxUkJDdk1DWnc1a0I3b1N2Q2E3aVhEUiJdLCJhdXRoTWV0aG9kQ29udGV4dHMiOltdLCJhdXRoU2lnQWRkcmVzcyI6bnVsbCwiY3VzdG9tQXV0aFJlc291cmNlIjoiKHRydWUsICdBbnl0aGluZyB5b3VyIHdhbnQgdG8gdXNlIGluIGV4ZWN1dGVKcycpIiwicmVzb3VyY2VzIjpbXX19XX19LCJwcmYiOltdfQ","address":"0xa19355DD0C6aDfD02a0F8C2B70A26DF4cECea166"}],"issuedAt":"2024-10-11T18:59:53.489Z","expiration":"2024-10-12T18:59:52.424Z","nodeAddress":"https://207.244.66.41:443"}`, + address: '09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0', + algo: 'ed25519' + }, + 'https://173.208.0.151:443': { + sig: '12496182e7b323943bcea9e0e342d6caee961137c9852dc063ac46ee20705b3f8a70e144249f3fe04d290bf7318f43d1cb641d472894954cdc8f784d333b5300', + derivedVia: 'litSessionSignViaNacl', + signedMessage: `{"sessionKey":"09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0","resourceAbilityRequests":[{"resource":{"resource":"*","resourcePrefix":"lit-pkp"},"ability":"pkp-signing"},{"resource":{"resource":"*","resourcePrefix":"lit-litaction"},"ability":"lit-action-execution"}],"capabilities":[{"sig":"{\\"ProofOfPossession\\":\\"838cf437fa58c2bb7e5c183bd2b184e4ed9da595bdb9bffa34019ca9b47e93f64b83d464eb9237297a829d1aa333560b0d6c55910631334bd9249cc826f8dcbf202f5f2d7d1ec67ec894a0b36b616cabb74f3e582e8b37089b9abdabbfa17e0d\\"}","algo":"LIT_BLS","derivedVia":"lit.bls","signedMessage":"litprotocol.com wants you to sign in with your Ethereum account:\\n0xa19355DD0C6aDfD02a0F8C2B70A26DF4cECea166\\n\\nLit Protocol PKP session signature I further authorize the stated URI to perform the following actions on my behalf: I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Execution' for 'lit-litaction://*'. (2) 'Threshold': 'Signing' for 'lit-pkp://*'. I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Execution' for 'lit-litaction://*'. (2) 'Threshold': 'Signing' for 'lit-pkp://*'. (3) 'Auth': 'Auth' for 'lit-resolvedauthcontext://*'.\\n\\nURI: lit:session:09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0\\nVersion: 1\\nChain ID: 1\\nNonce: 0x244bc2b37cf85c94f37206c2ca0769db6bd353f2795f5b6894829068ad8c8542\\nIssued At: 2024-10-11T18:59:23Z\\nExpiration Time: 2024-10-12T18:59:52.424Z\\nResources:\\n- urn:recap:eyJhdHQiOnsibGl0LWxpdGFjdGlvbjovLyoiOnsiVGhyZXNob2xkL0V4ZWN1dGlvbiI6W3t9XX0sImxpdC1wa3A6Ly8qIjp7IlRocmVzaG9sZC9TaWduaW5nIjpbe31dfSwibGl0LXJlc29sdmVkYXV0aGNvbnRleHQ6Ly8qIjp7IkF1dGgvQXV0aCI6W3siYXV0aF9jb250ZXh0Ijp7ImFjdGlvbklwZnNJZHMiOlsiUW1kNWliQ1JvOURoRW5qY21mQnNNVTZxUkJDdk1DWnc1a0I3b1N2Q2E3aVhEUiJdLCJhdXRoTWV0aG9kQ29udGV4dHMiOltdLCJhdXRoU2lnQWRkcmVzcyI6bnVsbCwiY3VzdG9tQXV0aFJlc291cmNlIjoiKHRydWUsICdBbnl0aGluZyB5b3VyIHdhbnQgdG8gdXNlIGluIGV4ZWN1dGVKcycpIiwicmVzb3VyY2VzIjpbXX19XX19LCJwcmYiOltdfQ","address":"0xa19355DD0C6aDfD02a0F8C2B70A26DF4cECea166"}],"issuedAt":"2024-10-11T18:59:53.489Z","expiration":"2024-10-12T18:59:52.424Z","nodeAddress":"https://173.208.0.151:443"}`, + address: '09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0', + algo: 'ed25519' + }, + 'https://207.244.90.225:443': { + sig: 'da675ce1b939511714116c73c32dec32db60abc42fa596cf4a82e4eeddc4531d85fb15758e4c78db83f990a892f07782a825e459022817d4098a65b736e9d900', + derivedVia: 'litSessionSignViaNacl', + signedMessage: `{"sessionKey":"09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0","resourceAbilityRequests":[{"resource":{"resource":"*","resourcePrefix":"lit-pkp"},"ability":"pkp-signing"},{"resource":{"resource":"*","resourcePrefix":"lit-litaction"},"ability":"lit-action-execution"}],"capabilities":[{"sig":"{\\"ProofOfPossession\\":\\"838cf437fa58c2bb7e5c183bd2b184e4ed9da595bdb9bffa34019ca9b47e93f64b83d464eb9237297a829d1aa333560b0d6c55910631334bd9249cc826f8dcbf202f5f2d7d1ec67ec894a0b36b616cabb74f3e582e8b37089b9abdabbfa17e0d\\"}","algo":"LIT_BLS","derivedVia":"lit.bls","signedMessage":"litprotocol.com wants you to sign in with your Ethereum account:\\n0xa19355DD0C6aDfD02a0F8C2B70A26DF4cECea166\\n\\nLit Protocol PKP session signature I further authorize the stated URI to perform the following actions on my behalf: I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Execution' for 'lit-litaction://*'. (2) 'Threshold': 'Signing' for 'lit-pkp://*'. I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Execution' for 'lit-litaction://*'. (2) 'Threshold': 'Signing' for 'lit-pkp://*'. (3) 'Auth': 'Auth' for 'lit-resolvedauthcontext://*'.\\n\\nURI: lit:session:09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0\\nVersion: 1\\nChain ID: 1\\nNonce: 0x244bc2b37cf85c94f37206c2ca0769db6bd353f2795f5b6894829068ad8c8542\\nIssued At: 2024-10-11T18:59:23Z\\nExpiration Time: 2024-10-12T18:59:52.424Z\\nResources:\\n- urn:recap:eyJhdHQiOnsibGl0LWxpdGFjdGlvbjovLyoiOnsiVGhyZXNob2xkL0V4ZWN1dGlvbiI6W3t9XX0sImxpdC1wa3A6Ly8qIjp7IlRocmVzaG9sZC9TaWduaW5nIjpbe31dfSwibGl0LXJlc29sdmVkYXV0aGNvbnRleHQ6Ly8qIjp7IkF1dGgvQXV0aCI6W3siYXV0aF9jb250ZXh0Ijp7ImFjdGlvbklwZnNJZHMiOlsiUW1kNWliQ1JvOURoRW5qY21mQnNNVTZxUkJDdk1DWnc1a0I3b1N2Q2E3aVhEUiJdLCJhdXRoTWV0aG9kQ29udGV4dHMiOltdLCJhdXRoU2lnQWRkcmVzcyI6bnVsbCwiY3VzdG9tQXV0aFJlc291cmNlIjoiKHRydWUsICdBbnl0aGluZyB5b3VyIHdhbnQgdG8gdXNlIGluIGV4ZWN1dGVKcycpIiwicmVzb3VyY2VzIjpbXX19XX19LCJwcmYiOltdfQ","address":"0xa19355DD0C6aDfD02a0F8C2B70A26DF4cECea166"}],"issuedAt":"2024-10-11T18:59:53.489Z","expiration":"2024-10-12T18:59:52.424Z","nodeAddress":"https://207.244.90.225:443"}`, + address: '09f07199ad48addc9b582cd4d1dd29014c61706b665474a5d10ee3903b2571a0', + algo: 'ed25519' + } + }; + + it('should format session signatures correctly', () => { + const formattedSessionSigsJson = formatSessionSigsJSON(JSON.stringify(sessionSigs)); + + + console.log('formattedSessionSigsJson', formattedSessionSigsJson); + + }); +}) \ No newline at end of file diff --git a/packages/misc/src/lib/helper/session-sigs-reader.ts b/packages/misc/src/lib/helper/session-sigs-reader.ts index 84e05f9d04..034f2fdca3 100644 --- a/packages/misc/src/lib/helper/session-sigs-reader.ts +++ b/packages/misc/src/lib/helper/session-sigs-reader.ts @@ -1,4 +1,39 @@ import { parseSignedMessage } from './session-sigs-validator'; +interface SessionInfo { + requestTime: string; + outerExpiration: { + issuedAt: string; + expiration: string; + duration: string; + status: string; + }; + capabilities: Array<{ + type: string; + issuedAt: string; + expiration: string; + duration: string; + status: string; + resources: { + att: Record>; + prf: string[]; + }; + }>; +} + +interface ResolvedAuthContext { + auth_context: { + actionIpfsIds: string[]; + authMethodContexts: any[]; + authSigAddress: any; + customAuthResource: string; + resources: any[]; + } +} +interface ProcessedSessionInfo { + att?: any; + customAuthSource?: string; + error?: string; +} function formatDuration(start: Date, end: Date): string { const diff = end.getTime() - start.getTime(); @@ -89,3 +124,134 @@ export function formatSessionSigs( return result; } + +function decodeBase64(str: string): string { + try { + return atob(str); + } catch (e) { + console.error('Error decoding base64:', e); + return str; + } +} + +export function formatSessionSigsJSON( + sessionSigs: string, + currentTime: Date = new Date() +): SessionInfo[] { + const parsedSigs = JSON.parse(sessionSigs); + const currentDate = new Date(currentTime); + const results: SessionInfo[] = []; + + Object.entries(parsedSigs).forEach(([nodeKey, nodeValue]: [string, any]) => { + let signedMessage; + + try { + signedMessage = JSON.parse(nodeValue.signedMessage); + } catch (error: unknown) { + const errorMessage = + error instanceof Error ? error.message : 'Unknown error'; + console.error(`Invalid JSON format for signedMessage in node ${nodeKey}: ${errorMessage}`); + return; // Skip this node and continue with the next one + } + + let result: SessionInfo = { + requestTime: currentDate.toISOString(), + outerExpiration: { + issuedAt: '', + expiration: '', + duration: '', + status: '', + }, + capabilities: [], + }; + + // Outer expiration + let issuedAt, expiration; + try { + issuedAt = new Date(signedMessage.issuedAt); + expiration = new Date(signedMessage.expiration); + } catch (error) { + const errorMessage = + error instanceof Error ? error.message : 'Unknown error'; + console.error(`Error parsing issuedAt or expiration in node ${nodeKey}: ${errorMessage}`); + return; // Skip this node and continue with the next one + } + + result.outerExpiration = { + issuedAt: issuedAt.toISOString(), + expiration: expiration.toISOString(), + duration: formatDuration(issuedAt, expiration), + status: formatStatus(expiration, currentDate), + }; + + // Capabilities + signedMessage.capabilities.forEach((cap: any) => { + const capType = cap.derivedVia; + const parsedCapMessage = parseSignedMessage(cap.signedMessage); + + const capIssuedAt = new Date(parsedCapMessage['Issued At'] || ''); + const capExpiration = new Date(parsedCapMessage['Expiration Time'] || ''); + const capResources = parsedCapMessage['- urn'] || ''; + + const encodedStr = (capResources as string).split('recap:')[1]; + const decodedData = decodeBase64(encodedStr); + + let jsonDecodedData; + + try { + jsonDecodedData = JSON.parse(decodedData); + } catch (e) { + console.error('Error parsing JSON:', e); + jsonDecodedData = decodedData; + } + + result.capabilities.push({ + type: capType, + issuedAt: capIssuedAt.toISOString(), + expiration: capExpiration.toISOString(), + duration: formatDuration(capIssuedAt, capExpiration), + status: formatStatus(capExpiration, currentDate), + resources: jsonDecodedData, + }); + }); + + results.push(result); + }); + + return results; +} + +export function getResourcesFromSessionSigs(sessionSigs: string): ProcessedSessionInfo[] { + + const formattedSessionSigs = formatSessionSigsJSON(sessionSigs); + + return formattedSessionSigs.map((sessionInfo): ProcessedSessionInfo => { + const result: ProcessedSessionInfo = {}; + + const capabilities = sessionInfo.capabilities; + const litBlsCapability = capabilities.find((c) => c.type === 'lit.bls'); + + if (litBlsCapability && litBlsCapability.resources) { + const litBlsResources = litBlsCapability.resources; + const resolvedAuthContextKey = Object.keys(litBlsResources.att).find((k) => k.startsWith('lit-resolvedauthcontext')); + + if (resolvedAuthContextKey) { + const resolvedAuthContextObject = litBlsResources.att[resolvedAuthContextKey]; + if (resolvedAuthContextObject['Auth/Auth'] && resolvedAuthContextObject['Auth/Auth'][0]) { + const resolvedAuthContext = resolvedAuthContextObject['Auth/Auth'][0] as unknown as ResolvedAuthContext; + result.att = litBlsResources.att; + result.customAuthSource = resolvedAuthContext.auth_context.customAuthResource; + } else { + result.error = "No Auth/Auth data found in resolvedAuthContextObject"; + } + } else { + result.error = "No lit-resolvedauthcontext key found in resources"; + } + } else { + result.error = "No lit.bls capability found or no resources in the capability"; + } + + return result; + }); +} + diff --git a/packages/types/src/lib/ILitNodeClient.ts b/packages/types/src/lib/ILitNodeClient.ts index 0f8b3646b0..dcee100d72 100644 --- a/packages/types/src/lib/ILitNodeClient.ts +++ b/packages/types/src/lib/ILitNodeClient.ts @@ -18,6 +18,8 @@ import { RejectedNodePromises, SendNodeCommand, SuccessNodePromises, + GetLitActionSessionSigs, + SessionSigsMap, } from './interfaces'; import { ILitResource, ISessionCapabilityObject } from './models'; import { SupportedJsonRequests } from './types'; @@ -227,4 +229,15 @@ export interface ILitNodeClient { generateSessionCapabilityObjectWithWildcards( litResources: ILitResource[] ): Promise; + + /** + * Retrieves session signatures specifically for Lit Actions. + * Unlike `getPkpSessionSigs`, this function requires either `litActionCode` or `litActionIpfsId`, and `jsParams` must be provided. + * + * @param params - The parameters required for retrieving the session signatures. + * @returns A promise that resolves with the session signatures. + */ + getLitActionSessionSigs( + params: GetLitActionSessionSigs + ): Promise; } diff --git a/packages/wrapped-keys-lit-actions/esbuild.config.js b/packages/wrapped-keys-lit-actions/esbuild.config.js index 7b0ba54732..b442a0f8ef 100644 --- a/packages/wrapped-keys-lit-actions/esbuild.config.js +++ b/packages/wrapped-keys-lit-actions/esbuild.config.js @@ -58,6 +58,9 @@ module.exports = { './src/lib/ethereum/generateEncryptedEthereumPrivateKey.js', './src/lib/common/exportPrivateKey.js', './src/lib/common/batchGenerateEncryptedKeys.js', + + // bespoke + './src/lib/common/bespoke/tria_batchGenerateEncryptedKeys.js', ], bundle: true, minify: true, diff --git a/packages/wrapped-keys-lit-actions/package.json b/packages/wrapped-keys-lit-actions/package.json index e3420fbc4c..5417b0589c 100644 --- a/packages/wrapped-keys-lit-actions/package.json +++ b/packages/wrapped-keys-lit-actions/package.json @@ -24,7 +24,8 @@ "genReact": false }, "scripts": { - "generate-lit-actions": "yarn node ./esbuild.config.js" + "generate-lit-actions": "yarn node ./esbuild.config.js", + "sync": "yarn node sync-actions-to-ipfs.js" }, "version": "6.9.0", "main": "./dist/src/index.js", diff --git a/packages/wrapped-keys-lit-actions/src/index.ts b/packages/wrapped-keys-lit-actions/src/index.ts index 8ca684ec8c..13f6fd8699 100644 --- a/packages/wrapped-keys-lit-actions/src/index.ts +++ b/packages/wrapped-keys-lit-actions/src/index.ts @@ -12,6 +12,9 @@ import type { LitActionCodeRepositoryCommon, } from '@lit-protocol/wrapped-keys'; +// bespoke +import * as tria_batchGenerateEncryptedKeys from './generated/common/bespoke/tria_batchGenerateEncryptedKeys'; + const litActionRepository: LitActionCodeRepository = { signTransaction: { evm: signTransactionWithEthereumEncryptedKey.code, @@ -33,6 +36,9 @@ const litActionRepository: LitActionCodeRepository = { const litActionRepositoryCommon: LitActionCodeRepositoryCommon = { batchGenerateEncryptedKeys: batchGenerateEncryptedKeys.code, + + // bespoke + tria_batchGenerateEncryptedKeys: tria_batchGenerateEncryptedKeys.code, }; export { diff --git a/packages/wrapped-keys-lit-actions/src/lib/common/bespoke/tria_batchGenerateEncryptedKeys.js b/packages/wrapped-keys-lit-actions/src/lib/common/bespoke/tria_batchGenerateEncryptedKeys.js new file mode 100644 index 0000000000..3e6f20103f --- /dev/null +++ b/packages/wrapped-keys-lit-actions/src/lib/common/bespoke/tria_batchGenerateEncryptedKeys.js @@ -0,0 +1,274 @@ +const { encryptPrivateKey } = require('./../internal/encryptKey'); +const { + generateEthereumPrivateKey, +} = require('../../ethereum/internal/generatePrivateKey'); +const { + signMessageEthereumKey, +} = require('../../ethereum/internal/signMessage'); +const { + generateSolanaPrivateKey, +} = require('../../solana/internal/generatePrivateKey'); +const { signMessageSolanaKey } = require('../../solana/internal/signMessage'); + +// =========== Global Variables (JsParams) =========== +// Lit Action:: Prepare jsParams +const jsParams = { + authMethod: { + accessToken: authMethod.accessToken, + authMethodType: authMethod.authMethodType, + }, + publicKey: publicKey, + actions: actions, + accessControlConditions: accessControlConditions, +}; + +validateJsParams(jsParams); + +async function processEthereumAction(action) { + const { network, generateKeyParams } = action; + const messageToSign = action.signMessageParams?.messageToSign; + + const ethereumKey = generateEthereumPrivateKey(); + + const [generatedPrivateKey, messageSignature] = await Promise.all([ + encryptPrivateKey({ + accessControlConditions, + publicKey: ethereumKey.publicKey, + privateKey: ethereumKey.privateKey, + }), + messageToSign + ? signMessageEthereumKey({ + messageToSign: messageToSign, + privateKey: ethereumKey.privateKey, + }) + : Promise.resolve(), + ]); + + return { + network, + generateEncryptedPrivateKey: { + ...generatedPrivateKey, + memo: generateKeyParams.memo, + }, + ...(messageSignature + ? { signMessage: { signature: messageSignature } } + : {}), + }; +} + +async function processSolanaAction(action) { + const { network, generateKeyParams } = action; + + const messageToSign = action.signMessageParams?.messageToSign; + + const solanaKey = generateSolanaPrivateKey(); + + const [generatedPrivateKey, messageSignature] = await Promise.all([ + encryptPrivateKey({ + accessControlConditions, + publicKey: solanaKey.publicKey, + privateKey: solanaKey.privateKey, + }), + messageToSign + ? signMessageSolanaKey({ + messageToSign: messageToSign, + privateKey: solanaKey.privateKey, + }) + : Promise.resolve(), + ]); + + return { + network, + generateEncryptedPrivateKey: { + ...generatedPrivateKey, + memo: generateKeyParams.memo, + }, + ...(messageSignature + ? { signMessage: { signature: messageSignature } } + : {}), + }; +} + +async function processActions(actions) { + return Promise.all( + actions.map(async (action, ndx) => { + const { network } = action; + + if (network === 'evm') { + return await processEthereumAction(action, ndx); + } else if (network === 'solana') { + return await processSolanaAction(action, ndx); + } else { + // Just in case :tm: + throw new Error(`Invalid network for action[${ndx}]: ${network}`); + } + }) + ); +} + +/** + * - jsParams: Expected data type: Object (e.g., "{ authMethod: { accessToken: '...', authMethodType: '...' }, publicKey: '...', actions: [...] }") + * + * This parameter is an object containing the following properties: + * - authMethod + * - publicKey + * - actions: Array of action objects, each containing network and key generation params. + * + */ +function validateJsParams(jsParams) { + if (!jsParams.authMethod) { + throw new Error('Missing required field: authMethod'); + } + if (!jsParams.publicKey) { + throw new Error('Missing required field: publicKey'); + } + if (!jsParams.accessControlConditions) { + throw new Error('Missing required field: accessControlConditions'); + } + const { accessToken, authMethodType } = jsParams.authMethod; + + if (!accessToken) { + throw new Error('Missing required field: authMethod.accessToken'); + } + if (!authMethodType) { + throw new Error('Missing required field: authMethod.authMethodType'); + } + + if (!jsParams.actions) { + throw new Error('Missing required field: actions'); + } + + if (!jsParams.actions.length) { + throw new Error('No actions provided (empty array?)'); + } + + jsParams.actions.forEach((action, ndx) => { + if (!['evm', 'solana'].includes(action.network)) { + throw new Error( + `Invalid field: actions[${ndx}].network: ${action.network}` + ); + } + + if (!action.generateKeyParams) { + throw new Error( + `Missing required field: actions[${ndx}].generateKeyParams` + ); + } + + if (!action.generateKeyParams?.memo) { + throw new Error( + `Missing required field: actions[${ndx}].generateKeyParams.memo` + ); + } + + if (action.signMessageParams && !action.signMessageParams?.messageToSign) { + throw new Error( + `Missing required field: actions[${ndx}].signMessageParams.messageToSign` + ); + } + }); +} + +const go = async () => { + // Lit Action:: Prepare jsParams + const jsParams = { + authMethod: { + accessToken: authMethod.accessToken, + authMethodType: authMethod.authMethodType, + }, + publicKey: publicKey, + actions: actions, + accessControlConditions: accessControlConditions, + }; + + validateJsParams(jsParams); + + // ========== Tria's Logic ========== + + // Authentication + const url = 'https://api.development.tria.so/api/v1/user/info'; + const response = await fetch(url, { + method: 'GET', + headers: { + Authorization: `Bearer ${jsParams.authMethod.accessToken}`, + }, + }); + const data = await response.json(); + console.log('data', data); + + if (!data.success) { + Lit.Actions.setResponse({ + response: JSON.stringify({ + success: false, + message: 'Authentication Failed', + }), + }); + return; + } + + // Authorization:: Prepare params + // -- 1. get the authMethodId from unique identify from the response + const authMethodId = `${ethers.utils.keccak256( + ethers.utils.toUtf8Bytes(data.userInfo.uuid) + )}`; + console.log('Computed AuthMethodId', authMethodId); + + // -- 2. get the PKP token id + const tokenId = Lit.Actions.pubkeyToTokenId({ + publicKey: jsParams.publicKey, + }); + console.log('tokenId', tokenId); + + // -- 3. get the permitted auth methods of the PKP token id + const permittedAuthMethods = await Lit.Actions.getPermittedAuthMethods({ + tokenId, + }); + console.log('permittedAuthMethods', permittedAuthMethods); + + // -- 4. only get where authMethod that's equal to the authMethod Id + const permittedAuthMethod = permittedAuthMethods.find( + (method) => method.id === authMethodId + ); + console.log('permittedAuthMethod', permittedAuthMethod); + + // TODO: Uncomment this block to enable Authorization + // Authorization:: Failed Authentication and Authorization + // if ( + // !permittedAuthMethod || + // permittedAuthMethod.auth_method_type !== jsParams.authMethod.authMethodType + // ) { + // Lit.Actions.setResponse({ + // response: JSON.stringify({ + // success: false, + // message: 'Authorization Failed', + // }), + // }); + // return; + // } + + // -- Perform runOnce wrapped-keys actions + try { + let res = await Lit.Actions.runOnce( + { waitForResponse: true, name: 'tria-auth-and-wrapped-keys' }, + async () => { + const batchGeneratePrivateKeysActionResult = await processActions( + jsParams.actions + ); + + return JSON.stringify(batchGeneratePrivateKeysActionResult); + } + ); + + Lit.Actions.setResponse({ + response: JSON.stringify(`(true, ${res})`), + }); + + // 1. Generate both EVM and solana private keys + // 2. Run appropriate signMessage for each key _and_ encrypt the keys for persistence to wrapped-keys backend + // 3. Return results for both signMessage ops and both encrypted key payloads for persistence + } catch (err) { + Lit.Actions.setResponse({ response: `Error: ${err.message}` }); + } +}; + +go(); diff --git a/packages/wrapped-keys/src/index.ts b/packages/wrapped-keys/src/index.ts index ea0b95d524..b5fef315dd 100644 --- a/packages/wrapped-keys/src/index.ts +++ b/packages/wrapped-keys/src/index.ts @@ -8,6 +8,9 @@ import { storeEncryptedKey, listEncryptedKeyMetadata, batchGeneratePrivateKeys, + + // bespoke + triaBatchGeneratePrivateKeys, } from './lib/api'; import { CHAIN_ETHEREUM, @@ -26,6 +29,7 @@ import { LitActionCodeRepositoryCommon, LitActionCodeRepositoryEntry, } from './lib/lit-actions-client/types'; +import { getLitActionCodeOrCidCommon } from './lib/lit-actions-client/utils'; import type { SupportedNetworks } from './lib/service-client/types'; import type { @@ -71,6 +75,9 @@ export const api = { signTransactionWithEncryptedKey, storeEncryptedKey, batchGeneratePrivateKeys, + + // bespoke + triaBatchGeneratePrivateKeys, }; export const config = { @@ -78,6 +85,10 @@ export const config = { setLitActionsCodeCommon, }; +export const utils = { + getLitActionCodeOrCidCommon +} + export { ApiParamsSupportedNetworks, BaseApiParams, diff --git a/packages/wrapped-keys/src/lib/api/bespoke/tria-batch-generate-private-keys.ts b/packages/wrapped-keys/src/lib/api/bespoke/tria-batch-generate-private-keys.ts new file mode 100644 index 0000000000..c5375bfabf --- /dev/null +++ b/packages/wrapped-keys/src/lib/api/bespoke/tria-batch-generate-private-keys.ts @@ -0,0 +1,169 @@ +import { getKeyTypeFromNetwork } from './../utils'; +import { batchGenerateKeysWithLitAction } from '../../lit-actions-client'; +import { getLitActionCodeOrCidCommon } from '../../lit-actions-client/utils'; +import { storePrivateKey } from '../../service-client'; +import { + BatchGeneratePrivateKeysActionResult, + BatchGeneratePrivateKeysParams, + BatchGeneratePrivateKeysResult, +} from '../../types'; +import { + getFirstSessionSig, + getPkpAccessControlCondition, + getPkpAddressFromSessionSig, +} from '../../utils'; +import { LitAbility, LitActionResource, LitPKPResource } from '@lit-protocol/auth-helpers'; +import { SessionSigsMap } from '@lit-protocol/types'; +import { formatSessionSigsJSON, getResourcesFromSessionSigs } from '@lit-protocol/misc'; +import { computeAddress } from 'ethers/lib/utils'; + + +/** + * TODO: Document batch behaviour + * @param { BatchGeneratePrivateKeysParams } params Parameters to use for generating keys and optionally signing messages + * + * @returns { Promise } - The generated keys and, optionally, signed messages + */ +export async function triaBatchGeneratePrivateKeys( + params: Omit & { + pkpPublicKey: string | `0x${string}`; + ipfsId: string | `Qm${string}`; + authMethod: { + authMethodType: string | `0x${string}`; + accessToken: string | `eyJ${string}`; + } + } +): Promise { + + // -- validate + if (!params.litNodeClient) { + throw new Error(`Error: litNodeClient is required`); + } + if (!params.pkpPublicKey) { + throw new Error(`Error: pkpPublicKey is required`); + } + if (!params.ipfsId) { + throw new Error(`Error: ipfsId is required`); + } + + // const sessionSig = getFirstSessionSig(pkpSessionSigs); + // const pkpAddress = getPkpAddressFromSessionSig(sessionSig); + + // const allowPkpAddressToDecrypt = getPkpAccessControlCondition(pkpAddress); + + // const { litActionCode, litActionIpfsCid } = getLitActionCodeOrCidCommon( + // 'tria_batchGenerateEncryptedKeys' + // ); + + let pkpPubKey = params.pkpPublicKey; + + if (pkpPubKey.startsWith('0x')) { + pkpPubKey = pkpPubKey.slice(2); + } + const pkpPubkeyBuffer = Buffer.from(pkpPubKey, 'hex'); + + const pkpEthAddress = computeAddress(pkpPubkeyBuffer); + + console.log("pkpEthAddress:", pkpEthAddress); + + const allowPkpAddressToDecrypt = getPkpAccessControlCondition(pkpEthAddress); + + // Here we should use getLitActionSessionSigs rather than executeJs + console.log(`🔄 Getting Lit Action Session Sigs`); + let litActionSessionSigs: SessionSigsMap; + + const _jsParams = { + authMethod: { + accessToken: params.authMethod.accessToken, + authMethodType: params.authMethod.authMethodType, + }, + actions: params.actions, + publicKey: params.pkpPublicKey, + accessControlConditions: [allowPkpAddressToDecrypt], + }; + + console.log("_jsParams:", _jsParams); + + try { + litActionSessionSigs = await params.litNodeClient.getLitActionSessionSigs({ + pkpPublicKey: params.pkpPublicKey, + resourceAbilityRequests: [ + { + resource: new LitPKPResource('*'), + ability: LitAbility.PKPSigning, + }, + { + resource: new LitActionResource('*'), + ability: LitAbility.LitActionExecution, + }, + ], + litActionIpfsId: params.ipfsId, + jsParams: _jsParams, + }); + } catch (e) { + throw new Error(`Error getting Lit Action Session Sigs: ${e}`); + } + + console.log("litActionSessionSigs:", litActionSessionSigs); + + const sessionSigsResources = getResourcesFromSessionSigs(JSON.stringify(litActionSessionSigs)); + + console.log("sessionSigsResources:", sessionSigsResources); + + // select a random resource from the array + const firstResource = sessionSigsResources[0]; + + if (!firstResource.customAuthSource) { + throw new Error(`Error: customAuthSource is required`); + } + + // remove "(true, from the beginning of the string and )" at the end of the string + const customAuthSource = firstResource.customAuthSource.slice(8, -2); + console.log("customAuthSource:", customAuthSource); + + + process.exit(); + + // // This is the original code + // const actionResults = await batchGenerateKeysWithLitAction({ + // ...params, + // litActionIpfsCid: litActionCode ? undefined : litActionIpfsCid, + // litActionCode: litActionCode ? litActionCode : undefined, + // accessControlConditions: [allowPkpAddressToDecrypt], + // pkpSessionSigs, + // }); + + // const results = await Promise.all( + // actionResults.map( + // async (result): Promise => { + // const { generateEncryptedPrivateKey, network } = result; + + // const signature = result.signMessage?.signature; + + // const { id } = await storePrivateKey({ + // sessionSig, + // storedKeyMetadata: { + // ...generateEncryptedPrivateKey, + // keyType: getKeyTypeFromNetwork(network), + // pkpAddress, + // }, + // litNetwork: litNodeClient.config.litNetwork, + // }); + + // return { + // ...(signature ? { signMessage: { signature } } : {}), + // generateEncryptedPrivateKey: { + // memo: generateEncryptedPrivateKey.memo, + // id, + // generatedPublicKey: generateEncryptedPrivateKey.publicKey, + // pkpAddress, + // }, + // }; + // } + // ) + // ); + + // return { pkpAddress, results }; + + return { pkpAddress: '', results: [] }; +} diff --git a/packages/wrapped-keys/src/lib/api/index.ts b/packages/wrapped-keys/src/lib/api/index.ts index d13292a017..c2ad1b823c 100644 --- a/packages/wrapped-keys/src/lib/api/index.ts +++ b/packages/wrapped-keys/src/lib/api/index.ts @@ -7,6 +7,7 @@ import { listEncryptedKeyMetadata } from './list-encrypted-key-metadata'; import { signMessageWithEncryptedKey } from './sign-message-with-encrypted-key'; import { signTransactionWithEncryptedKey } from './sign-transaction-with-encrypted-key'; import { storeEncryptedKey } from './store-encrypted-key'; +import { triaBatchGeneratePrivateKeys } from './bespoke/tria-batch-generate-private-keys'; export { listEncryptedKeyMetadata, @@ -18,4 +19,7 @@ export { storeEncryptedKey, getEncryptedKey, batchGeneratePrivateKeys, + + // bespoke + triaBatchGeneratePrivateKeys, }; diff --git a/packages/wrapped-keys/src/lib/lit-actions-client/bespoke/tria-batch-generate-keys.ts b/packages/wrapped-keys/src/lib/lit-actions-client/bespoke/tria-batch-generate-keys.ts new file mode 100644 index 0000000000..ab8f521af8 --- /dev/null +++ b/packages/wrapped-keys/src/lib/lit-actions-client/bespoke/tria-batch-generate-keys.ts @@ -0,0 +1,101 @@ +import { GLOBAL_OVERWRITE_IPFS_CODE_BY_NETWORK } from '@lit-protocol/constants'; +import { AccessControlConditions } from '@lit-protocol/types'; + +import { postLitActionValidation } from '../utils'; +import { BatchGeneratePrivateKeysParams, Network } from '../../types'; + +import { LitActionResource, LitPKPResource } from '@lit-protocol/auth-helpers'; +import { LitAbility, LitResourceAbilityRequest } from '@lit-protocol/types'; +import { formatSessionSigsJSON, parseSignedMessage } from '@lit-protocol/misc'; + +interface BatchGeneratePrivateKeysWithLitActionParams + extends BatchGeneratePrivateKeysParams { + accessControlConditions: AccessControlConditions; + litActionIpfsCid?: string; + litActionCode?: string; +} + +interface GeneratePrivateKeyLitActionResult { + ciphertext: string; + dataToEncryptHash: string; + publicKey: string; + memo: string; +} + +interface BatchGeneratePrivateKeysWithLitActionResult { + network: Network; + signMessage?: { signature: string }; + generateEncryptedPrivateKey: GeneratePrivateKeyLitActionResult; +} + +export async function triaBatchGenerateKeysWithLitActionSessionSigs( + args: Omit & { + authMethod: { + accessToken: string | `eyJ${string}`; + authMethodType: string | `0x${string}`; + }, + publicKey: string; + } +): Promise { + + // print all the params out + // console.log("args:", args); + // process.exit(); + + const sessionSigs = await args.litNodeClient.getLitActionSessionSigs({ + pkpPublicKey: args.publicKey, + resourceAbilityRequests: [ + { + resource: new LitPKPResource('*'), + ability: LitAbility.PKPSigning, + }, + { + resource: new LitActionResource('*'), + ability: LitAbility.LitActionExecution, + }, + ], + litActionCode: args.litActionCode ? + Buffer.from(args.litActionCode).toString('base64') : + undefined, + + // @ts-ignore - this is a test + litActionIpfsCid: args.litActionIpfsCid ? + undefined : + args.litActionIpfsCid, + + jsParams: { + publicKey: args.publicKey, + sigName: 'tria-batch-generate-keys-combined-sig', + actions: args.actions, + authMethod: { + accessToken: args.authMethod.accessToken, + authMethodType: args.authMethod.authMethodType, + } + } + }); + + console.log("sessionSigs:", sessionSigs); + + const parsedSignedMessage = formatSessionSigsJSON(JSON.stringify(sessionSigs)); + + console.log("parsedSignedMessage:", parsedSignedMessage); + process.exit(); + + // const result = await litNodeClient.executeJs({ + // useSingleNode: true, + // sessionSigs: pkpSessionSigs, + // ipfsId: litActionIpfsCid, + // code: litActionCode, + // jsParams: { + // actions, + // accessControlConditions, + // }, + // ipfsOptions: { + // overwriteCode: + // GLOBAL_OVERWRITE_IPFS_CODE_BY_NETWORK[litNodeClient.config.litNetwork], + // }, + // }); + + // const response = postLitActionValidation(result); + // return JSON.parse(response); +} diff --git a/packages/wrapped-keys/src/lib/lit-actions-client/code-repository.ts b/packages/wrapped-keys/src/lib/lit-actions-client/code-repository.ts index 54363e47a2..2323d99a5c 100644 --- a/packages/wrapped-keys/src/lib/lit-actions-client/code-repository.ts +++ b/packages/wrapped-keys/src/lib/lit-actions-client/code-repository.ts @@ -53,11 +53,9 @@ function assertIsLitActionRepositoryEntry( ): asserts entry is LitActionCodeRepositoryEntry { if ( typeof entry !== 'object' || - !entry || - // @ts-expect-error assert function - ('evm' in entry && typeof entry.evm !== 'string') || - // @ts-expect-error assert function - ('solana' in entry && typeof entry.solana !== 'string') || + entry === null || // Ensure entry is not null + ('evm' in entry && typeof (entry as any).evm !== 'string') || + ('solana' in entry && typeof (entry as any).solana !== 'string') || Object.keys(entry).some((key) => !['evm', 'solana'].includes(key)) ) { throw new Error( @@ -89,6 +87,9 @@ function setLitActionsCode(repository: LitActionCodeRepositoryInput) { */ const litActionCodeRepositoryCommon: LitActionCodeRepositoryCommon = { batchGenerateEncryptedKeys: '', + + // bespoke + tria_batchGenerateEncryptedKeys: '', }; function assertIsLitActionKeyCommon( diff --git a/packages/wrapped-keys/src/lib/lit-actions-client/constants.ts b/packages/wrapped-keys/src/lib/lit-actions-client/constants.ts index 83360f84fc..7b4304c12a 100644 --- a/packages/wrapped-keys/src/lib/lit-actions-client/constants.ts +++ b/packages/wrapped-keys/src/lib/lit-actions-client/constants.ts @@ -21,6 +21,7 @@ const LIT_ACTION_CID_REPOSITORY: LitCidRepository = Object.freeze({ const LIT_ACTION_CID_REPOSITORY_COMMON: LitCidRepositoryCommon = Object.freeze({ batchGenerateEncryptedKeys: 'QmR8Zs7ctSEctxBrSnAYhMXFXCC1ub8K1xvMn5Js3NCSAA', + tria_batchGenerateEncryptedKeys: 'xxx', }); export { LIT_ACTION_CID_REPOSITORY, LIT_ACTION_CID_REPOSITORY_COMMON }; diff --git a/packages/wrapped-keys/src/lib/lit-actions-client/types.ts b/packages/wrapped-keys/src/lib/lit-actions-client/types.ts index bda28ecd57..ce87c80680 100644 --- a/packages/wrapped-keys/src/lib/lit-actions-client/types.ts +++ b/packages/wrapped-keys/src/lib/lit-actions-client/types.ts @@ -6,7 +6,17 @@ export type LitActionType = | 'generateEncryptedKey' | 'exportPrivateKey'; -export type LitActionTypeCommon = 'batchGenerateEncryptedKeys'; +export type LitActionTypeCommon = + | 'batchGenerateEncryptedKeys' + | BespokeLitActionTypes; + +export type BespokeLitActionTypes = Tria_LitActionTypeCommon; +// | Foo_LitActionTypeCommon +// | Bar_LitActionTypeCommon + +export type Tria_LitActionTypeCommon = 'tria_batchGenerateEncryptedKeys'; +// export type Foo_LitActionTypeCommon = 'FooBatchGenerateEncryptedKeys'; +// export type Bar_LitActionTypeCommon = 'BarBatchGenerateEncryptedKeys'; export type LitCidRepositoryEntry = Readonly>; diff --git a/tsconfig.json b/tsconfig.json index d79d1c4238..e8f4e19b50 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,15 +10,24 @@ "importHelpers": true, "target": "ES2020", "module": "ES2020", - "lib": ["ES2020", "dom", "ES2021.String"], + "lib": [ + "ES2020", + "dom", + "ES2021.String" + ], "skipLibCheck": true, "skipDefaultLibCheck": true, "baseUrl": ".", "allowSyntheticDefaultImports": true, "resolveJsonModule": true, "paths": { - "@lit-protocol/*": ["packages/*/src"] + "@lit-protocol/*": [ + "packages/*/src" + ] } }, - "exclude": ["node_modules", "tmp"] -} + "exclude": [ + "node_modules", + "tmp" + ] +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index bd29e4cc9b..5a933819e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3594,6 +3594,11 @@ "@motionone/dom" "^10.16.4" tslib "^2.3.1" +"@multiformats/base-x@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@multiformats/base-x/-/base-x-4.0.1.tgz#95ff0fa58711789d53aefb2590a8b7a4e715d121" + integrity sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw== + "@multiformats/murmur3@^2.0.0": version "2.1.8" resolved "https://registry.yarnpkg.com/@multiformats/murmur3/-/murmur3-2.1.8.tgz#81c1c15b6391109f3febfca4b3205196615a04e9" @@ -9294,6 +9299,16 @@ cids@^0.7.1: multicodec "^1.0.0" multihashes "~0.4.15" +cids@^1.0.0, cids@^1.1.5, cids@^1.1.6: + version "1.1.9" + resolved "https://registry.yarnpkg.com/cids/-/cids-1.1.9.tgz#402c26db5c07059377bcd6fb82f2a24e7f2f4a4f" + integrity sha512-l11hWRfugIcbGuTZwAM5PwpjPPjyb6UZOGwlHSnOBV5o07XhQ4gNpBN67FbODvpjyHtd+0Xs6KNvUcGBiDRsdg== + dependencies: + multibase "^4.0.1" + multicodec "^3.0.1" + multihashes "^4.0.1" + uint8arrays "^3.0.0" + cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" @@ -11401,7 +11416,7 @@ err-code@^2.0.2: resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== -err-code@^3.0.1: +err-code@^3.0.0, err-code@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/err-code/-/err-code-3.0.1.tgz#a444c7b992705f2b120ee320b09972eef331c920" integrity sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA== @@ -14078,6 +14093,14 @@ h3@^1.10.2, h3@^1.11.1: uncrypto "^0.1.3" unenv "^1.9.0" +hamt-sharding@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/hamt-sharding/-/hamt-sharding-2.0.1.tgz#f45686d0339e74b03b233bee1bde9587727129b6" + integrity sha512-vnjrmdXG9dDs1m/H4iJ6z0JFI2NtgsW5keRkTcM85NGak69Mkf5PHUqBz+Xs0T4sg0ppvj9O5EGAJo40FTxmmA== + dependencies: + sparse-array "^1.3.1" + uint8arrays "^3.0.0" + hamt-sharding@^3.0.0: version "3.0.6" resolved "https://registry.yarnpkg.com/hamt-sharding/-/hamt-sharding-3.0.6.tgz#3643107a3021af66ac95684aec87b196add5ba57" @@ -14843,6 +14866,15 @@ interface-blockstore@^4.0.0: interface-store "^3.0.0" multiformats "^11.0.0" +interface-ipld-format@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/interface-ipld-format/-/interface-ipld-format-1.0.1.tgz#bee39c70c584a033e186ff057a2be89f215963e3" + integrity sha512-WV/ar+KQJVoQpqRDYdo7YPGYIUHJxCuOEhdvsRpzLqoOIVCqPKdMMYmsLL1nCRsF3yYNio+PAJbCKiv6drrEAg== + dependencies: + cids "^1.1.6" + multicodec "^3.0.1" + multihashes "^4.0.2" + interface-store@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/interface-store/-/interface-store-3.0.4.tgz#670d95ef45f3b7061d154c3cbfaf39a538167ad7" @@ -14903,6 +14935,14 @@ ipaddr.js@1.9.1: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== +ipfs-only-hash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/ipfs-only-hash/-/ipfs-only-hash-4.0.0.tgz#b3bd60a244d9eb7394961aa9d812a2e5ac7c04d6" + integrity sha512-TE1DZCvfw8i3gcsTq3P4TFx3cKFJ3sluu/J3XINkJhIN9OwJgNMqKA+WnKx6ByCb1IoPXsTp1KM7tupElb6SyA== + dependencies: + ipfs-unixfs-importer "^7.0.1" + meow "^9.0.0" + ipfs-unixfs-importer@12.0.1: version "12.0.1" resolved "https://registry.yarnpkg.com/ipfs-unixfs-importer/-/ipfs-unixfs-importer-12.0.1.tgz#316a52d8a793e9e006b1ee43edc50b83e00ef306" @@ -14924,6 +14964,34 @@ ipfs-unixfs-importer@12.0.1: uint8arraylist "^2.3.3" uint8arrays "^4.0.2" +ipfs-unixfs-importer@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/ipfs-unixfs-importer/-/ipfs-unixfs-importer-7.0.3.tgz#b850e831ca9647d589ef50bc33421f65bab7bba6" + integrity sha512-qeFOlD3AQtGzr90sr5Tq1Bi8pT5Nr2tSI8z310m7R4JDYgZc6J1PEZO3XZQ8l1kuGoqlAppBZuOYmPEqaHcVQQ== + dependencies: + bl "^5.0.0" + cids "^1.1.5" + err-code "^3.0.1" + hamt-sharding "^2.0.0" + ipfs-unixfs "^4.0.3" + ipld-dag-pb "^0.22.2" + it-all "^1.0.5" + it-batch "^1.0.8" + it-first "^1.0.6" + it-parallel-batch "^1.0.9" + merge-options "^3.0.4" + multihashing-async "^2.1.0" + rabin-wasm "^0.1.4" + uint8arrays "^2.1.2" + +ipfs-unixfs@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/ipfs-unixfs/-/ipfs-unixfs-4.0.3.tgz#7c43e5726052ade4317245358ac541ef3d63d94e" + integrity sha512-hzJ3X4vlKT8FQ3Xc4M1szaFVjsc1ZydN+E4VQ91aXxfpjFn9G2wsMo1EFdAXNq/BUnN5dgqIOMP5zRYr3DTsAw== + dependencies: + err-code "^3.0.1" + protobufjs "^6.10.2" + ipfs-unixfs@^9.0.0: version "9.0.1" resolved "https://registry.yarnpkg.com/ipfs-unixfs/-/ipfs-unixfs-9.0.1.tgz#d06e688e07ef4ce08d610337ba2fe8c143c386e7" @@ -14932,6 +15000,19 @@ ipfs-unixfs@^9.0.0: err-code "^3.0.1" protobufjs "^7.0.0" +ipld-dag-pb@^0.22.2: + version "0.22.3" + resolved "https://registry.yarnpkg.com/ipld-dag-pb/-/ipld-dag-pb-0.22.3.tgz#6d5af28b5752236a5cb0e0a1888c87dd733b55cd" + integrity sha512-dfG5C5OVAR4FEP7Al2CrHWvAyIM7UhAQrjnOYOIxXGQz5NlEj6wGX0XQf6Ru6or1na6upvV3NQfstapQG8X2rg== + dependencies: + cids "^1.0.0" + interface-ipld-format "^1.0.0" + multicodec "^3.0.1" + multihashing-async "^2.0.0" + protobufjs "^6.10.2" + stable "^0.1.8" + uint8arrays "^2.0.5" + iron-webcrypto@^1.1.1: version "1.2.1" resolved "https://registry.yarnpkg.com/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz#aa60ff2aa10550630f4c0b11fd2442becdb35a6f" @@ -15632,21 +15713,43 @@ isurl@^1.0.0-alpha5: has-to-string-tag-x "^1.2.0" is-object "^1.0.1" +it-all@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/it-all/-/it-all-1.0.6.tgz#852557355367606295c4c3b7eff0136f07749335" + integrity sha512-3cmCc6Heqe3uWi3CVM/k51fa/XbMFpQVzFoDsV0IZNHSQDyAXl3c4MjHkFX5kF3922OGj7Myv1nSEUgRtcuM1A== + it-all@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/it-all/-/it-all-2.0.1.tgz#45d530ecf6e13fb81d7ba583cdfd55ffdb376b05" integrity sha512-9UuJcCRZsboz+HBQTNOau80Dw+ryGaHYFP/cPYzFBJBFcfDathMYnhHk4t52en9+fcyDGPTdLB+lFc1wzQIroA== +it-batch@^1.0.8, it-batch@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/it-batch/-/it-batch-1.0.9.tgz#7e95aaacb3f9b1b8ca6c8b8367892171d6a5b37f" + integrity sha512-7Q7HXewMhNFltTsAMdSz6luNhyhkhEtGGbYek/8Xb/GiqYMtwUmopE1ocPSiJKKp3rM4Dt045sNFoUu+KZGNyA== + it-batch@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/it-batch/-/it-batch-2.0.1.tgz#a0822be9b18743c41d8525835f788a7f297ba41f" integrity sha512-2gWFuPzamh9Dh3pW+OKjc7UwJ41W4Eu2AinVAfXDMfrC5gXfm3b1TF+1UzsygBUgKBugnxnGP+/fFRyn+9y1mQ== +it-first@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/it-first/-/it-first-1.0.7.tgz#a4bef40da8be21667f7d23e44dae652f5ccd7ab1" + integrity sha512-nvJKZoBpZD/6Rtde6FXqwDqDZGF1sCADmr2Zoc0hZsIvnE449gRFnGctxDf09Bzc/FWnHXAdaHVIetY6lrE0/g== + it-first@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/it-first/-/it-first-2.0.1.tgz#75d66b254c385ae3a1906def060a69006a437cef" integrity sha512-noC1oEQcWZZMUwq7VWxHNLML43dM+5bviZpfmkxkXlvBe60z7AFRqpZSga9uQBo792jKv9otnn1IjA4zwgNARw== +it-parallel-batch@^1.0.9: + version "1.0.11" + resolved "https://registry.yarnpkg.com/it-parallel-batch/-/it-parallel-batch-1.0.11.tgz#f889b4e1c7a62ef24111dbafbaaa010b33d00f69" + integrity sha512-UWsWHv/kqBpMRmyZJzlmZeoAMA0F3SZr08FBdbhtbe+MtoEBgr/ZUAKrnenhXCBrsopy76QjRH2K/V8kNdupbQ== + dependencies: + it-batch "^1.0.9" + it-parallel-batch@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/it-parallel-batch/-/it-parallel-batch-2.0.1.tgz#23eb07bbeb73521253d7c8a1566b53137103077c" @@ -17781,6 +17884,24 @@ meow@^8.0.0: type-fest "^0.18.0" yargs-parser "^20.2.3" +meow@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-9.0.0.tgz#cd9510bc5cac9dee7d03c73ee1f9ad959f4ea364" + integrity sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ== + dependencies: + "@types/minimist" "^1.2.0" + camelcase-keys "^6.2.2" + decamelize "^1.2.0" + decamelize-keys "^1.1.0" + hard-rejection "^2.1.0" + minimist-options "4.1.0" + normalize-package-data "^3.0.0" + read-pkg-up "^7.0.1" + redent "^3.0.0" + trim-newlines "^3.0.0" + type-fest "^0.18.0" + yargs-parser "^20.2.3" + merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -18264,6 +18385,13 @@ multibase@^0.7.0: base-x "^3.0.8" buffer "^5.5.0" +multibase@^4.0.1: + version "4.0.6" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-4.0.6.tgz#6e624341483d6123ca1ede956208cb821b440559" + integrity sha512-x23pDe5+svdLz/k5JPGCVdfn7Q5mZVMBETiC+ORfO+sor9Sgs0smJzAjfTbM5tckeCqnaUuMYoz+k3RXMmJClQ== + dependencies: + "@multiformats/base-x" "^4.0.1" + multibase@~0.6.0: version "0.6.1" resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.6.1.tgz#b76df6298536cc17b9f6a6db53ec88f85f8cc12b" @@ -18287,6 +18415,14 @@ multicodec@^1.0.0: buffer "^5.6.0" varint "^5.0.0" +multicodec@^3.0.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-3.2.1.tgz#82de3254a0fb163a107c1aab324f2a91ef51efb2" + integrity sha512-+expTPftro8VAW8kfvcuNNNBgb9gPeNYV9dn+z1kJRWF2vih+/S79f2RVeIwmrJBUJ6NT9IUPWnZDQvegEh5pw== + dependencies: + uint8arrays "^3.0.0" + varint "^6.0.0" + multiformats@^11.0.0, multiformats@^11.0.2: version "11.0.2" resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-11.0.2.tgz#b14735efc42cd8581e73895e66bebb9752151b60" @@ -18316,6 +18452,27 @@ multihashes@^0.4.15, multihashes@~0.4.15: multibase "^0.7.0" varint "^5.0.0" +multihashes@^4.0.1, multihashes@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-4.0.3.tgz#426610539cd2551edbf533adeac4c06b3b90fb05" + integrity sha512-0AhMH7Iu95XjDLxIeuCOOE4t9+vQZsACyKZ9Fxw2pcsRmlX4iCn1mby0hS0bb+nQOVpdQYWPpnyusw4da5RPhA== + dependencies: + multibase "^4.0.1" + uint8arrays "^3.0.0" + varint "^5.0.2" + +multihashing-async@^2.0.0, multihashing-async@^2.1.0: + version "2.1.4" + resolved "https://registry.yarnpkg.com/multihashing-async/-/multihashing-async-2.1.4.tgz#26dce2ec7a40f0e7f9e732fc23ca5f564d693843" + integrity sha512-sB1MiQXPSBTNRVSJc2zM157PXgDtud2nMFUEIvBrsq5Wv96sUclMRK/ecjoP1T/W61UJBqt4tCTwMkUpt2Gbzg== + dependencies: + blakejs "^1.1.0" + err-code "^3.0.0" + js-sha3 "^0.8.0" + multihashes "^4.0.1" + murmurhash3js-revisited "^3.0.0" + uint8arrays "^3.0.0" + multimatch@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-5.0.0.tgz#932b800963cea7a31a033328fa1e0c3a1874dbe6" @@ -20324,7 +20481,7 @@ proto-list@~1.2.1: resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== -protobufjs@^6.8.8, protobufjs@~6.11.2, protobufjs@~6.11.3: +protobufjs@^6.10.2, protobufjs@^6.8.8, protobufjs@~6.11.2, protobufjs@~6.11.3: version "6.11.4" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.4.tgz#29a412c38bf70d89e537b6d02d904a6f448173aa" integrity sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw== @@ -22245,6 +22402,11 @@ ssri@^9.0.0, ssri@^9.0.1: dependencies: minipass "^3.1.1" +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + stack-trace@0.0.x: version "0.0.10" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" @@ -23489,6 +23651,13 @@ typescript@~5.3.2: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== +typestub-ipfs-only-hash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/typestub-ipfs-only-hash/-/typestub-ipfs-only-hash-4.0.0.tgz#12e7d0e13947884b5b7d8091b9a17073fdf71d2d" + integrity sha512-HKLePX0XiPiyqoueSfvCLL9SIzvKBXjASaRoR0yk/gUbbK7cqejU6/tjhihwmzBCvWbx5aMQ2LYsYIpMK7Ikpg== + dependencies: + ipfs-only-hash "^4.0.0" + u2f-api@0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/u2f-api/-/u2f-api-0.2.7.tgz#17bf196b242f6bf72353d9858e6a7566cc192720" @@ -23518,6 +23687,13 @@ uint8arrays@3.1.0: dependencies: multiformats "^9.4.2" +uint8arrays@^2.0.5, uint8arrays@^2.1.2: + version "2.1.10" + resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-2.1.10.tgz#34d023c843a327c676e48576295ca373c56e286a" + integrity sha512-Q9/hhJa2836nQfEJSZTmr+pg9+cDJS9XEAp7N2Vg5MzL3bK/mkMVfjscRGYruP9jNda6MAdf4QD/y78gSzkp6A== + dependencies: + multiformats "^9.4.2" + uint8arrays@^3.0.0, uint8arrays@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.1.1.tgz#2d8762acce159ccd9936057572dade9459f65ae0" @@ -24031,11 +24207,16 @@ valtio@1.11.0: proxy-compare "2.5.1" use-sync-external-store "1.2.0" -varint@^5.0.0: +varint@^5.0.0, varint@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4" integrity sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow== +varint@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0" + integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg== + varuint-bitcoin@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz#e76c138249d06138b480d4c5b40ef53693e24e92"