diff --git a/.env.ci b/.env.ci index a07d05981f..546d7e0f87 100644 --- a/.env.ci +++ b/.env.ci @@ -1,6 +1,6 @@ #Tinny ENV Vars MAX_ATTEMTPS=1 -NETWORK=localchain +NETWORK=custom DEBUG=true WAIT_FOR_KEY_INTERVAL=3000 TIME_TO_RELEASE_KEY=10000 @@ -10,6 +10,7 @@ NO_SETUP=false USE_SHIVA=true NETWORK_CONFIG=./networkContext.json TEST_TIMEOUT=45000 +LIT_RPC_URL=http://127.0.0.1:8545 #Shiva Client ENV Vars STOP_TESTNET=false diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 87b29d4f74..b00c1c14e8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,20 +18,22 @@ jobs: uses: actions/checkout@v2 with: fetch-depth: 0 - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: '20' - cache: 'yarn' - - name: Install project dependencies - run: yarn --frozen-lockfile - uses: nrwl/nx-set-shas@v3 with: main-branch-name: 'master' + - uses: actions/checkout@v3 + - name: Use Node.js + uses: buildjet/setup-node@v3 + with: + node-version: 20 + cache: yarn + cache-dependency-path: ${{ github.workspace }}/yarn.lock + - name: Install Dependencies + run: yarn - name: Build run: yarn build:dev - name: Run Unit tests - run: yarn tools --test --unit + run: yarn test:ci integration-tests: runs-on: ubuntu-latest timeout-minutes: 30 @@ -57,7 +59,13 @@ jobs: rust/lit-node - name: Check LA dir run: ls -la ${{github.workspace}}/lit-assets - - name: Install LA Blockchain Dependencies + - name: Setup Lit Bockchain Dependencies + uses: buildjet/setup-node@v3 + with: + node-version: 20 + cache: npm + cache-dependency-path: ${{ github.workspace }}/lit-assets/blockchain/contracts/package-lock.json + - name: Install Blockchain Deps run: npm i working-directory: ${{github.workspace}}/lit-assets/blockchain/contracts - name: Docker login @@ -69,12 +77,8 @@ jobs: - name: Run Shiva Container id: shiva-runner run: docker run -d -m 32g -p 8000:8000 -p 8545:8545 -p 7470:7470 -p 7471:7471 -p 7472:7472 -p 7473:7473 -p 7474:7474 -p 7475:7475 -v ${{github.workspace}}/lit-assets:/data -e GH_PAT=${{secrets.GH_PAT}} -e HASH=$DATIL_COMMIT_HASH -e IPFS_API_KEY=${{secrets.IPFS_API_KEY}} --name shiva ghcr.io/lit-protocol/shiva:latest - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: '20' - name: Install project dependencies - run: yarn --frozen-lockfile + run: yarn - uses: nrwl/nx-set-shas@v3 with: main-branch-name: 'master' @@ -83,9 +87,18 @@ jobs: run: yarn build:dev - name: Copy ENV File run: cp .env.ci .env - - name: Run End to End Tests + - name: End to End Tests - Connection + id: connection if: steps.build.outputs.exit_code == 0 - run: yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigning,testUseEoaSessionSigsToPkpSign,testUsePkpSessionSigsToExecuteJsSigning,testUsePkpSessionSigsToPkpSign,testUseValidLitActionCodeGeneratedSessionSigsToPkpSign,testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning,testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs,testEthAuthSigToEncryptDecryptString,testExecuteJsSignAndCombineEcdsa,testExecutJsDecryptAndCombine,testExecuteJsBroadcastAndCollect --exclude=Parallel + run: yarn test:e2e -t 'Connections' + - name: End Tests Session Compaitiblity + id: session + if: steps.connection.outputs.exit_code == 0 + run: yarn test:e2e -t 'SessionSigs' + - name: End to End Tests - PKP Ethers + if: steps.session.outputs.exit_code == 0 + id: pkp + run: yarn test:e2e -t 'PKP Ethers' - name: Get Container Logs if: always() run: docker logs shiva @@ -93,6 +106,4 @@ jobs: id: container-stop if: steps.shiva-pull.outputs.exit_code == 0 run: docker stop shiva && docker rm shiva - - name: Post Pull Shiva Image - if: steps.shiva-pull.outputs.exit_code == 0 - run: docker rmi ghcr.io/lit-protocol/shiva \ No newline at end of file + diff --git a/README.md b/README.md index 8551e64259..973d9fa811 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ If you're a tech-savvy user and wish to utilize only specific submodules that ou | [@lit-protocol/contracts-sdk](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/contracts-sdk) | ![contracts-sdk](https://img.shields.io/badge/-universal-8A6496 'contracts-sdk') | | | [@lit-protocol/core](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/core) | ![core](https://img.shields.io/badge/-universal-8A6496 'core') | | | [@lit-protocol/crypto](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/crypto) | ![crypto](https://img.shields.io/badge/-universal-8A6496 'crypto') | | +| [@lit-protocol/e2e-tests](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/e2e-tests) | ![e2e-tests](https://img.shields.io/badge/-universal-8A6496 'e2e-tests') | | | [@lit-protocol/ecdsa-sdk](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/ecdsa-sdk) | ![ecdsa-sdk](https://img.shields.io/badge/-universal-8A6496 'ecdsa-sdk') | | | [@lit-protocol/encryption](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/encryption) | ![encryption](https://img.shields.io/badge/-universal-8A6496 'encryption') | | | [@lit-protocol/logger](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/logger) | ![logger](https://img.shields.io/badge/-universal-8A6496 'logger') | | @@ -131,14 +132,14 @@ yarn build ## Run unit tests -``` +```sh yarn test:unit ``` ## Run E2E tests in nodejs -``` -yarn test:local +```sh +yarn test:e2e ``` # Advanced diff --git a/jest.preset.js b/jest.preset.js index f078ddcec1..cac6acca6d 100644 --- a/jest.preset.js +++ b/jest.preset.js @@ -1,3 +1,11 @@ +/** + * Direct link to nx presets + * https://github.com/nrwl/nx/blob/master/packages/jest/preset/jest-preset.ts + */ const nxPreset = require('@nx/jest/preset').default; -module.exports = { ...nxPreset }; +const presets = { + ...nxPreset, +}; + +presets.testEnviorment = 'node'; diff --git a/jest.setup.js b/jest.setup.js index f44e2a7ef9..80ce51090b 100644 --- a/jest.setup.js +++ b/jest.setup.js @@ -1,3 +1,5 @@ +require('dotenv').config({ path: '../../.env' }); +console.log('loaded configuration from .env'); const crypto = require('crypto'); global.TextEncoder = require('util').TextEncoder; diff --git a/local-tests/README.md b/local-tests/README.md deleted file mode 100644 index 065e528056..0000000000 --- a/local-tests/README.md +++ /dev/null @@ -1,142 +0,0 @@ -# Tinny - -Tinny is a mini test framework, serving as a temporary solution for running e2e tests in TypeScript until we can integrate `Jest`. It utilizes `esbuild` for its rapid compilation speed to bundle all the tests into a single `test.mjs` file, then runs the built `test.mjs` file immediately. See [Benchmark](#esbuild-benchmark) - -# Prerequisite - -- Node v20 or above -- The generated file `networkContext.ts` after running `npm run deploy -- --network localchain` in the `lit-assets` repo - -# How to run - -In most cases, you will only need the following two environment variables, and a `--filter` flag. See [API](#api) - -The `testName` specified in the filter **must be the same as the function name**. - -## to run all tests - -``` -// run all tests on localchain -DEBUG=true NETWORK=localchain yarn test:local - -// run filtered tests on manzano -DEBUG=true NETWORK=manzano yarn test:local --filter=testExample -DEBUG=true NETWORK=manzano yarn test:local --filter=testExample,testBundleSpeed - -// run filtered tests by keyword -DEBUG=true NETWORK=manzano yarn test:local --filter=Encrypt - -// eg. -yarn test:local --filter=testExample,testBundleSpeed - -``` - -## API - -Below is the API documentation for the `ProcessEnvs` interface, detailing the configurable environment variables and their purposes: - -**NOTE: a `.env.sample` is contained in the repository root for the below env tables** - -| Variable | Description | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `MAX_ATTEMPTS` | Each test is executed in a loop with a maximum number of attempts specified by `devEnv.processEnvs.MAX_ATTEMPTS`. | -| `TEST_TIMEOUT` | The maximum number of milliseconds to wait for a test to complete. | -| `NETWORK` | The network to use for testing, which can be one of the following: `LIT_TESTNET.LOCALCHAIN`, `LIT_TESTNET.MANZANO`, or `LIT_TESTNET.CAYENNE`. | -| `DEBUG` | Specifies whether to enable debug mode. | -| `REQUEST_PER_KILOSECOND` | To execute a transaction with Lit, you must reserve capacity on the network using Capacity Credits. These allow a set number of requests over a period (default 2 days). | -| `WAIT_FOR_KEY_INTERVAL` | Wait time in milliseconds if no private keys are available. | -| `TIME_TO_RELEASE_KEY` | Time to wait before releasing the key after requesting it. | -| `RUN_IN_BAND` | Run all tests in a single thread. | -| `RUN_IN_BAND_INTERVAL` | The interval in milliseconds to run the tests in a single thread. | -| `LIT_RPC_URL` | The URL of the Lit RPC server:
- For local Anvil: `http://127.0.0.1:8545`
- For Chronicle: `https://chain-rpc.litprotocol.com/http`
- For Yellowstone: `https://yellowstone-rpc.litprotocol.com` | -| `STOP_TESTNET` | Flag to stop a single running testnet after the test run concludes. | -| `USE_SHIVA` | A flag to determine if `Shiva` should be used for the `localchain` network. | -| `PRIVATE_KEYS` | A set of private keys to use which will be used to perform chain operations. | -| `CHUNK_SIZE` | Determines the number of tests run concurrently during parallel execution | - -Below is the API Documentation for the `ProccessEnvs` interface for the `shiva-client` detailing the configurable environment variables and their purposes: - -| Variable | Description | -| ------------------------ | ----------------------------------------------------------------------------------------------------------- | -| `TESTNET_MANANGER_URL` | URl to connect to Shiva (our testing tool for network management). | -| `LIT_NODE_BINARY_PATH` | Binary path for the lit node version you wish to run. | -| `LIT_Action_BINARY_PATH` | Binary path for the lit node version you wish to run. | -| `USE_LIT_BINARIES` | Flag to indicate if a binary path should be used for testnet spawning or if it should be built from source. | -| `STOP_TESTNET` | Flag to stop a single running testnet after the test run concludes. | - -# Writing a test - -Writing a test is the same as writing any other code, except that you must throw an error if any occur. There are no assertion libraries, so all tests are written using basic `if-else` statements. - -In the test function, a `devEnv` variable will automatically be added as the first parameter to your function. - -## Using the devEnv API in the test - -```ts -export const testExample = async (devEnv: TinnyEnvironment) => { - - // ========== Enviorment ========== - // This test will be skipped if we are testing on the Cayenne network - devEnv.setUnavailable(LIT_TESTNET.CAYENNE); - - // Using litNodeClient - const res = await devEnv.litNodeClient.executeJs({...}); - - // ========== Creating a new identify/user profile ========== - const alice = await devEnv.createRandomPerson(); - - // Alice minting a capacity creditrs NFT - const aliceCcNft = await alice.mintCapacityCreditsNFT(); - - // Alice creating a capacity delegation authSig - const aliceCcAuthSig = await alice.createCapacityDelegationAuthSig(); -}; -``` - -## TinnyPerson Class API - -The `TinnyPerson` class encapsulates various functionalities to manage wallet operations, authentication, and contract interactions for testing purposes. Below is a detailed API documentation: - -### Alice's Properties - -| Property | Description | -| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| `privateKey` | The private key used to instantiate the wallet associated with the TinnyPerson instance. | -| `wallet` | An `ethers.Wallet` instance created using the provided `privateKey` and connected to the specified provider. | -| `siweMessage` | A string that holds the Sign-In with Ethereum (SIWE) message used for authentication. | -| `pkp` | EOA/Hot wallet owned PKP NFT | -| `authSig` | An `AuthSig` object that stores the authentication signature derived from the SIWE message. | -| `authMethod` | An `AuthMethod` object representing the authentication method used, typically related to blockchain wallet authentication. | -| `authMethodOwnedPkp` | PKP information specifically tied to the authentication method of the wallet. | -| `contractsClient` | An instance of `LitContracts`, used to interact with Lit Protocol smart contracts for operations such as minting tokens or PKP NFTs. | -| `provider` | An `ethers.providers.JsonRpcProvider` instance connected to the blockchain network specified in `envConfig`. | -| `loveLetter` | A `Uint8Array` containing a keccak256 hashed value, typically used as unsigned data to be passed to the `executeJs` and `pkpSign` functions | - -### Methods - -| Method | Description | -| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `constructor({privateKey, envConfig})` | Initializes a new instance of `TinnyPerson` with the specified private key and environment configuration. Sets up the wallet and provider based on these settings. | -| `spawn()` | Performs several operations to set up the TinnyPerson instance fully, including authentication and contract client setup. It also mints a PKP using the specified authentication method. | -| `mintCapacityCreditsNFT()` | Mints a Capacity Credits NFT based on the `REQUEST_PER_KILOSECOND` setting in `envConfig`. Returns the token ID of the minted NFT. | -| `createCapacityDelegationAuthSig(addresses)` | Mints a Capacity Credits NFT and creates an authentication signature for delegating capacity, which can be used to authorize other addresses to use the minted credits. | - -## - -# esbuild benchmark - -```ts - -// test-bundle-speed.ts -export const testBundleSpeed = async (devEnv: TinnyEnvironment) => { - const a = await import('@lit-protocol/lit-node-client'); - const b = await import('@lit-protocol/contracts-sdk'); - const c = await import('@lit-protocol/auth-helpers'); - const d = await import('@lit-protocol/constants'); - const e = await import('@lit-protocol/lit-auth-client'); - - console.log(a, b, c, d, e); -}; ----------------- -Build time: 77ms -``` diff --git a/local-tests/build.mjs b/local-tests/build.mjs deleted file mode 100644 index 79fd5883d7..0000000000 --- a/local-tests/build.mjs +++ /dev/null @@ -1,65 +0,0 @@ -import * as esbuild from 'esbuild'; -import { nodeExternalsPlugin } from 'esbuild-node-externals'; -import fs from 'fs'; - -const TEST_DIR = 'local-tests'; - -/** - * Builds the project using esbuild. - * @returns {Promise} A promise that resolves when the build is complete. - */ -export const build = async () => { - await esbuild.build({ - entryPoints: [`${TEST_DIR}/test.ts`], - outfile: `./${TEST_DIR}/build/test.mjs`, - bundle: true, - plugins: [ - nodeExternalsPlugin({ - allowList: [ - 'ethers', - '@lit-protocol/accs-schemas', - '@lit-protocol/contracts', - 'crypto', - 'secp256k1', - ], - }), - ], - platform: 'node', - target: 'esnext', - format: 'esm', - inject: [`./${TEST_DIR}/shim.mjs`], - mainFields: ['module', 'main'], - }); -}; - -/** - * Inserts a polyfill at the beginning of a file. - * The polyfill ensures that the global `fetch` function is available. - * @returns {void} - */ -export const postBuildPolyfill = () => { - try { - const file = fs.readFileSync(`./${TEST_DIR}/build/test.mjs`, 'utf8'); - const content = `import fetch from 'node-fetch'; -try { - if (!globalThis.fetch) { - globalThis.fetch = fetch; - } -} catch (error) { - console.error('❌ Error in polyfill', error); -} -`; - const newFile = content + file; - fs.writeFileSync(`./${TEST_DIR}/build/test.mjs`, newFile); - } catch (e) { - throw new Error(`Error in postBuildPolyfill: ${e}`); - } -}; - -// Go! -(async () => { - const start = Date.now(); - await build(); - postBuildPolyfill(); - console.log(`[build.mjs] πŸš€ Build time: ${Date.now() - start}ms`); -})(); diff --git a/local-tests/setup/tinny-operations.ts b/local-tests/setup/tinny-operations.ts deleted file mode 100644 index c0f70aceb9..0000000000 --- a/local-tests/setup/tinny-operations.ts +++ /dev/null @@ -1,270 +0,0 @@ -import { TinnyEnvironment } from './tinny-environment'; -import { withTimeout } from './tinny-utils'; - -/** - * Retrieves filter flags from the command line arguments to determine which tests to run. - * It parses the process arguments to find flags that specify filters, typically used to limit test execution to specific tests. - * - * @returns {string[]} An array of filter strings extracted from the command line arguments. - * - * @example - * // Assume the command line is: node script.js --filter=test1,test2 - */ -export const getFiltersFlag = (): string[] => { - const filterArg = process.argv.find((arg) => arg.startsWith('--filter=')); - return filterArg ? filterArg.replace('--filter=', '').split(',') : []; -}; - -/** - * Retrieves the exclude flags from the command line arguments. - * @returns An array of strings representing the exclude flags. - */ -export const getExcludeFlags = (): string[] => { - const filterArg = process.argv.find((arg) => arg.startsWith('--exclude=')); - return filterArg ? filterArg.replace('--exclude=', '').split(',') : []; -}; - -/** - * Runs the tests in the provided `tests` object in a synchronous manner. - * Each test is executed in a loop with a maximum number of attempts specified by `devEnv.processEnvs.MAX_ATTEMPTS`. - * Skipped, failed, and passed tests are tracked and logged. - * At the end, a test report is printed with the number of passed, failed, and skipped tests. - * If any test fails, the process exits with an error code. Otherwise, it exits successfully. - * - * @param {Object} options - The options object. - * @param {Object} options.tests - The tests to run. - * @param {TinnyEnvironment} options.devEnv - The development environment. - * @returns {Promise} - A promise that resolves when all tests have been executed. - */ -export const runInBand = async ({ - tests, - devEnv, -}: { - tests: any; - devEnv: TinnyEnvironment; -}): Promise => { - const filters = getFiltersFlag(); - const testsToRun = Object.entries(tests).filter( - ([testName]) => filters.length === 0 || filters.includes(testName) - ); - - // Initialize arrays to keep track of skipped, failed, and passed tests - let skippedTests: string[] = []; - let failedTests: string[] = []; - let passedTests: string[] = []; - - // Iterate over each test and run it in series - for (const [testName, testFunction] of testsToRun) { - const maxAttempts = devEnv.processEnvs.MAX_ATTEMPTS; - let attempts = 0; - let testPassed = false; - - while (attempts < maxAttempts && !testPassed) { - const startTime = performance.now(); - - try { - console.log(`Attempt ${attempts + 1} for ${testName}...`); - - // @ts-ignore - await testFunction(devEnv); - testPassed = true; - - const endTime = performance.now(); - const timeTaken = (endTime - startTime).toFixed(2); - console.log(`${testName} - Passed (${timeTaken} ms)`); - passedTests.push(`${testName} (Passed in ${timeTaken} ms)`); - } catch (error) { - if (error.message === 'LIT_IGNORE_TEST') { - skippedTests.push(`${testName} (Skipped)`); - break; - } - attempts++; - if (attempts >= maxAttempts) { - const endTime = performance.now(); - const timeTaken = (endTime - startTime).toFixed(2); - console.error( - `${testName} - Failed after ${maxAttempts} attempts (${timeTaken} ms)` - ); - console.error(`Error: ${error}`); - failedTests.push( - `${testName} (Failed in ${timeTaken} ms) - Error: ${error}` - ); - } - } - - await new Promise((resolve) => - setTimeout(resolve, devEnv.processEnvs.RUN_IN_BAND_INTERVAL) - ); - } - } - - passedTests.forEach((test) => console.log(`- ${test}`)); - failedTests.forEach((test) => console.log(`- ${test}`)); - skippedTests.forEach((test) => console.log(`- ${test}`)); - - console.log(); - // Print results - console.log( - `Test Report: ${passedTests.length} test(s) passed, ${failedTests.length} failed, ${skippedTests.length} skipped.` - ); - - if (failedTests.length > 0) { - return 1; // Exit with error code if any test failed - } else { - return 0; // Exit successfully if all tests passed - } -}; - -/** - * Runs tests in parallel with a limit of 5 concurrent tests and reports the results. - * @param {Object} options - The options for running the tests. - * @param {any} options.tests - The tests to run. - * @param {TinnyEnvironment} options.devEnv - The development environment. - * @returns {Promise} - A promise that resolves to 0 if all tests passed, 1 otherwise. - */ -export const runTestsParallel = async ({ - tests, - devEnv, - chunkSize, -}: { - tests: any; - devEnv: TinnyEnvironment; - chunkSize?: number; -}): Promise => { - const CHUNK_SIZE = chunkSize || parseInt(process.env.CHUNK_SIZE) || 5; - const filters = getFiltersFlag(); - const excludeFilters = getExcludeFlags(); - - // Filter the tests based on include and exclude filters - const testsToRun = Object.entries(tests).filter( - ([testName]) => - (filters.length === 0 || - filters.some((filter) => testName.includes(filter))) && - (excludeFilters.length === 0 || - !excludeFilters.some((exclude) => testName.includes(exclude))) - ); - - if (!testsToRun || testsToRun.length <= 0) { - throw new Error( - '❌ No tests to run. You might have provided an invalid filter or no tests are available.' - ); - } - - const runTest = async ( - [testName, testFunction]: [string, any], - testIndex: number - ): Promise => { - const maxAttempts = devEnv.processEnvs.MAX_ATTEMPTS; - const testTimeout = devEnv.processEnvs.TEST_TIMEOUT; - - let attempts = 0; - let testPassed = false; - - while (attempts < maxAttempts && !testPassed) { - const startTime = performance.now(); - try { - console.log( - `\x1b[90m[runTestsParallel] Attempt ${attempts + 1} for ${ - testIndex + 1 - }. ${testName}...\x1b[0m` - ); - - await withTimeout(testFunction(devEnv), testTimeout); - testPassed = true; - - const endTime = performance.now(); - const timeTaken = (endTime - startTime).toFixed(2); - console.log( - `\x1b[32mβœ”\x1b[90m ${ - testIndex + 1 - }. ${testName} - Passed (${timeTaken} ms)\x1b[0m` - ); - return `${testName} (Passed in ${timeTaken} ms)`; - } catch (error) { - if (error.message === 'LIT_IGNORE_TEST') { - return `${testName} (Skipped)`; - } - attempts++; - - const endTime = performance.now(); - const timeTaken = (endTime - startTime).toFixed(2); - - if (error.message === 'Timed out') { - console.error( - `\x1b[31mβœ–\x1b[90m ${ - testIndex + 1 - }. ${testName} - Timed out after ${testTimeout}ms (${timeTaken} ms)\x1b[0m` - ); - return `${testName} (Timed out in ${timeTaken} ms)`; - } - - if (attempts >= maxAttempts) { - console.error( - `\x1b[31mβœ–\x1b[90m ${ - testIndex + 1 - }. ${testName} - Failed after ${maxAttempts} attempts (${timeTaken} ms)\x1b[0m` - ); - console.error( - `\x1b[31m❌Error:\x1b[90m ${JSON.stringify(error) || error}\x1b[0m` - ); - return `${testName} (Failed in ${timeTaken} ms) - Error: ${JSON.stringify( - error - )}`; - } - } - } - }; - - const results: string[] = []; - - for (let i = 0; i < testsToRun.length; i += CHUNK_SIZE) { - const chunk = testsToRun.slice(i, i + CHUNK_SIZE); - const chunkResults = await Promise.all( - chunk.map((test, index) => runTest(test, i + index)) - ); - - // wait for 3 seconds before running the next chunk - await new Promise((resolve) => setTimeout(resolve, 3000)); - - results.push(...chunkResults); - } - - const skippedTests = results.filter((result) => result.includes('Skipped')); - const failedTests = results.filter( - (result) => result.includes('Failed') || result.includes('Timed out') - ); - const passedTests = results.filter((result) => result.includes('Passed')); - - if (skippedTests.length > 0) { - console.log(`\x1b[90mTest Report: Some tests were skipped.\x1b[0m`); - skippedTests.forEach((skippedTest) => - console.log(`\x1b[90m- ${skippedTest}\x1b[0m`) - ); - } - - if (failedTests.length > 0) { - console.log(`\x1b[31mTest Report: Some tests failed.\x1b[0m`); - failedTests.forEach((failedTest) => - console.log(`\x1b[31m- ${failedTest}\x1b[0m`) - ); - } - - if (passedTests.length > 0) { - console.log( - `\x1b[32mTest Report: ${passedTests.length} test(s) passed.\x1b[0m` - ); - passedTests.forEach((passedTest) => - console.log(`\x1b[32m- ${passedTest}\x1b[0m`) - ); - } - - if (failedTests.length > 0) { - console.log( - `\x1b[31mTest Report: ${failedTests.length} test(s) failed.\x1b[0m` - ); - return 1; // Exit with error code if any test failed - } else { - console.log('\x1b[32mTest Report: All tests passed.\x1b[0m'); - return 0; // Exit successfully if all tests passed - } -}; diff --git a/local-tests/shim.mjs b/local-tests/shim.mjs deleted file mode 100644 index 32068375c1..0000000000 --- a/local-tests/shim.mjs +++ /dev/null @@ -1,3 +0,0 @@ -import { createRequire } from 'module'; -const require = createRequire(import.meta.url); -global.require = require; diff --git a/local-tests/test.ts b/local-tests/test.ts deleted file mode 100644 index c66998d30b..0000000000 --- a/local-tests/test.ts +++ /dev/null @@ -1,324 +0,0 @@ -import { TinnyEnvironment } from './setup/tinny-environment'; -import { runInBand, runTestsParallel } from './setup/tinny-operations'; -// import { testBundleSpeed } from './tests/test-bundle-speed'; -// import { testExample } from './tests/test-example'; -import { testUseEoaSessionSigsToExecuteJsSigning } from './tests/testUseEoaSessionSigsToExecuteJsSigning'; -import { testUseEoaSessionSigsToPkpSign } from './tests/testUseEoaSessionSigsToPkpSign'; -import { testUsePkpSessionSigsToExecuteJsSigning } from './tests/testUsePkpSessionSigsToExecuteJsSigning'; -import { testUsePkpSessionSigsToPkpSign } from './tests/testUsePkpSessionSigsToPkpSign'; -import { testUseValidLitActionCodeGeneratedSessionSigsToPkpSign } from './tests/testUseValidLitActionCodeGeneratedSessionSigsToPkpSign'; -import { testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning } from './tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning'; -import { testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning } from './tests/testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning'; -import { testUseEoaSessionSigsToExecuteJsSigningInParallel } from './tests/testUseEoaSessionSigsToExecuteJsSigningInParallel'; -import { testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs } from './tests/testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs'; -import { testDelegatingCapacityCreditsNFTToAnotherWalletToPkpSign } from './tests/testDelegatingCapacityCreditsNFTToAnotherWalletToPkpSign'; -import { testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToPkpSign } from './tests/testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToPkpSign'; -import { testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs } from './tests/testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs'; -import { testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToPkpSign } from './tests/testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToPkpSign'; -import { testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToExecuteJs } from './tests/testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToExecuteJs'; -import { testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs } from './tests/testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs'; -import { testUseEoaSessionSigsToExecuteJsClaimKeys } from './tests/testUseEoaSessionSigsToExecuteJsClaimKeys'; -import { testUseEoaSessionSigsToExecuteJsClaimMultipleKeys } from './tests/testUseEoaSessionSigsToExecuteJsClaimMultipleKeys'; -import { testUseEoaSessionSigsToExecuteJsJsonResponse } from './tests/testUseEoaSessionSigsToExecuteJsJsonResponse'; -import { testUseEoaSessionSigsToExecuteJsConsoleLog } from './tests/testUseEoaSessionSigsToExecuteJsConsoleLog'; -import { testUseEoaSessionSigsToEncryptDecryptString } from './tests/testUseEoaSessionSigsToEncryptDecryptString'; -import { testUsePkpSessionSigsToEncryptDecryptString } from './tests/testUsePkpSessionSigsToEncryptDecryptString'; -import { testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString } from './tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString'; -import { testUseInvalidLitActionCodeToGenerateSessionSigs } from './tests/testUseInvalidLitActionCodeToGenerateSessionSigs'; -import { testUseEoaSessionSigsToEncryptDecryptFile } from './tests/testUseEoaSessionSigsToEncryptDecryptFile'; -import { testUseEoaSessionSigsToEncryptDecryptZip } from './tests/testUseEoaSessionSigsToEncryptDecryptZip'; -import { testUsePkpSessionSigsToExecuteJsSigningInParallel } from './tests/testUsePkpSessionSigsToExecuteJsSigningInParallel'; -import { testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel } from './tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel'; -import { testUsePkpSessionSigsToExecuteJsClaimKeys } from './tests/testUsePkpSessionSigsToExecuteJsClaimKeys'; -import { testUsePkpSessionSigsToExecuteJsClaimMultipleKeys } from './tests/testUsePkpSessionSigsToExecuteJsClaimMultipleKeys'; -import { testUsePkpSessionSigsToExecuteJsJsonResponse } from './tests/testUsePkpSessionSigsToExecuteJsJsonResponse'; -import { testUsePkpSessionSigsToExecuteJsConsoleLog } from './tests/testUsePkpSessionSigsToExecuteJsConsoleLog'; -import { testUsePkpSessionSigsToEncryptDecryptFile } from './tests/testUsePkpSessionSigsToEncryptDecryptFile'; -import { testUsePkpSessionSigsToEncryptDecryptZip } from './tests/testUsePkpSessionSigsToEncryptDecryptZip'; -import { testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys } from './tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys'; -import { testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys } from './tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys'; -import { testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse } from './tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse'; -import { testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog } from './tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog'; -import { testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile } from './tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile'; -import { testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip } from './tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip'; -import { testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign } from './tests/testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign'; -import { testUseInvalidLitActionIpfsCodeToGenerateSessionSigs } from './tests/testUseInvalidLitActionIpfsCodeToGenerateSessionSigs'; -import { testSolAuthSigToEncryptDecryptString } from './tests/testSolAuthSigToEncryptDecryptString'; -import { testEthAuthSigToEncryptDecryptString } from './tests/testEthAuthSigToEncryptDecryptString'; -import { testCosmosAuthSigToEncryptDecryptString } from './tests/testCosmosAuthSigToEncryptDecryptString'; -import { testPkpEthersWithEoaSessionSigsToSignMessage } from './tests/testPkpEthersWithEoaSessionSigsToSignMessage'; -import { testPkpEthersWithEoaSessionSigsToSignWithAuthContext } from './tests/testPkpEthersWithEoaSessionSigsToSignWithAuthContext'; -import { testPkpEthersWithEoaSessionSigsToEthSign } from './tests/testPkpEthersWithEoaSessionSigsToEthSign'; -import { testPkpEthersWithEoaSessionSigsToPersonalSign } from './tests/testPkpEthersWithEoaSessionSigsToPersonalSign'; -import { testPkpEthersWithEoaSessionSigsToSendTx } from './tests/testPkpEthersWithEoaSessionSigsToSendTx'; -import { testPkpEthersWithPkpSessionSigsToSignMessage } from './tests/testPkpEthersWithPkpSessionSigsToSignMessage'; -import { testPkpEthersWithPkpSessionSigsToEthSign } from './tests/testPkpEthersWithPkpSessionSigsToEthSign'; -import { testPkpEthersWithPkpSessionSigsToPersonalSign } from './tests/testPkpEthersWithPkpSessionSigsToPersonalSign'; -import { testPkpEthersWithPkpSessionSigsToSendTx } from './tests/testPkpEthersWithPkpSessionSigsToSendTx'; -import { testPkpEthersWithEoaSessionSigsToEthSignTransaction } from './tests/testPkpEthersWithEoaSessionSigsToEthSignTransaction'; - -import { testPkpEthersWithPkpSessionSigsToEthSignTransaction } from './tests/testPkpEthersWithPkpSessionSigsToEthSignTransaction'; -import { testPkpEthersWithLitActionSessionSigsToEthSignTransaction } from './tests/testPkpEthersWithLitActionSessionSigsToEthSignTransaction'; -import { testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1 } from './tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1'; -import { testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1 } from './tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1'; -import { testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1 } from './tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1'; -import { testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3 } from './tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3'; -import { testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4 } from './tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4'; -import { testPkpEthersWithEoaSessionSigsToEthSignTypedData } from './tests/testPkpEthersWithEoaSessionSigsToEthSignTypedData'; -import { testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil } from './tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil'; -import { testPkpEthersWithLitActionSessionSigsToSignMessage } from './tests/testPkpEthersWithLitActionSessionSigsToSignMessage'; -import { testPkpEthersWithLitActionSessionSigsToEthSign } from './tests/testPkpEthersWithLitActionSessionSigsToEthSign'; -import { testPkpEthersWithLitActionSessionSigsToPersonalSign } from './tests/testPkpEthersWithLitActionSessionSigsToPersonalSign'; -import { testPkpEthersWithLitActionSessionSigsToSendTx } from './tests/testPkpEthersWithLitActionSessionSigsToSendTx'; -import { testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3 } from './tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3'; -import { testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3 } from './tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3'; -import { testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4 } from './tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4'; -import { testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4 } from './tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4'; -import { testPkpEthersWithPkpSessionSigsToEthSignTypedData } from './tests/testPkpEthersWithPkpSessionSigsToEthSignTypedData'; -import { testPkpEthersWithLitActionSessionSigsToEthSignTypedData } from './tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedData'; -import { testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil } from './tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil'; -import { testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil } from './tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil'; -import { testUseCustomAuthSessionSigsToPkpSignExecuteJs } from './tests/testUseCustomAuthSessionSigsToPkpSignExecuteJs'; -import { testExecuteJsSignAndCombineEcdsa } from './tests/testExecuteJsSignAndCombineEcdsa'; -import { testExecutJsDecryptAndCombine } from './tests/testExecuteJsDecryptAndCombine'; -import { testExecuteJsBroadcastAndCollect } from './tests/testExecuteJsBroadcastAndCollect'; -import { testRelayer } from './tests/testRelayer'; - -import { testEthereumSignMessageGeneratedKey } from './tests/wrapped-keys/testEthereumSignMessageGeneratedKey'; -import { testEthereumBroadcastTransactionGeneratedKey } from './tests/wrapped-keys/testEthereumBroadcastTransactionGeneratedKey'; -import { testEthereumSignMessageWrappedKey } from './tests/wrapped-keys/testEthereumSignMessageWrappedKey'; -import { testFailEthereumSignTransactionWrappedKeyInvalidDecryption } from './tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyInvalidDecryption'; -import { testEthereumSignTransactionWrappedKey } from './tests/wrapped-keys/testEthereumSignTransactionWrappedKey'; -import { testFailEthereumSignTransactionWrappedKeyWithInvalidParam } from './tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyWithInvalidParam'; -import { testFailEthereumSignTransactionWrappedKeyWithMissingParam } from './tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyWithMissingParam'; -import { testEthereumBroadcastTransactionWrappedKey } from './tests/wrapped-keys/testEthereumBroadcastTransactionWrappedKey'; -import { testEthereumBroadcastWrappedKeyWithFetchGasParams } from './tests/wrapped-keys/testEthereumBroadcastWrappedKeyWithFetchGasParams'; -import { testImportWrappedKey } from './tests/wrapped-keys/testImportWrappedKey'; -import { testGenerateEthereumWrappedKey } from './tests/wrapped-keys/testGenerateEthereumWrappedKey'; -import { testGenerateSolanaWrappedKey } from './tests/wrapped-keys/testGenerateSolanaWrappedKey'; -import { testFailImportWrappedKeysWithSamePrivateKey } from './tests/wrapped-keys/testFailImportWrappedKeysWithSamePrivateKey'; -import { testFailImportWrappedKeysWithEoaSessionSig } from './tests/wrapped-keys/testFailImportWrappedKeysWithEoaSessionSig'; -import { testFailImportWrappedKeysWithMaxExpirySessionSig } from './tests/wrapped-keys/testFailImportWrappedKeysWithMaxExpirySessionSig'; -import { testFailImportWrappedKeysWithInvalidSessionSig } from './tests/wrapped-keys/testFailImportWrappedKeysWithInvalidSessionSig'; -import { testFailImportWrappedKeysWithExpiredSessionSig } from './tests/wrapped-keys/testFailImportWrappedKeysWithExpiredSessionSig'; -import { testExportWrappedKey } from './tests/wrapped-keys/testExportWrappedKey'; -import { testSignMessageWithSolanaEncryptedKey } from './tests/wrapped-keys/testSignMessageWithSolanaEncryptedKey'; -import { testSignTransactionWithSolanaEncryptedKey } from './tests/wrapped-keys/testSignTransactionWithSolanaEncryptedKey'; -import { testBatchGeneratePrivateKeys } from './tests/wrapped-keys/testBatchGeneratePrivateKeys'; -import { testFailBatchGeneratePrivateKeysAtomic } from './tests/wrapped-keys/testFailStoreEncryptedKeyBatchIsAtomic'; - -import { setLitActionsCodeToLocal } from './tests/wrapped-keys/util'; -import { testUseEoaSessionSigsToRequestSingleResponse } from './tests/testUseEoaSessionSigsToRequestSingleResponse'; - -// Use the current LIT action code to test against -setLitActionsCodeToLocal(); - -(async () => { - console.log('[𐬺πŸ§ͺ Tinny𐬺] Running tests...'); - const devEnv = new TinnyEnvironment(); - - await devEnv.init(); - - const relayerTests = { - testRelayer, - }; - - // --filter=WrappedKey - const wrappedKeysTests = { - // -- valid cases - testBatchGeneratePrivateKeys, - testEthereumSignMessageGeneratedKey, - testEthereumBroadcastTransactionGeneratedKey, - testEthereumSignMessageWrappedKey, - testEthereumSignTransactionWrappedKey, - testEthereumBroadcastTransactionWrappedKey, - testEthereumBroadcastWrappedKeyWithFetchGasParams, - - // -- generate wrapped keys - testGenerateEthereumWrappedKey, - testGenerateSolanaWrappedKey, - - // -- import wrapped keys - testImportWrappedKey, - - // -- export wrapped keys - testExportWrappedKey, - - // -- solana wrapped keys - testSignMessageWithSolanaEncryptedKey, - testSignTransactionWithSolanaEncryptedKey, - - // -- invalid cases - testFailEthereumSignTransactionWrappedKeyWithMissingParam, - testFailEthereumSignTransactionWrappedKeyWithInvalidParam, - testFailEthereumSignTransactionWrappedKeyInvalidDecryption, - testFailBatchGeneratePrivateKeysAtomic, - - // -- import wrapped keys - testFailImportWrappedKeysWithSamePrivateKey, - testFailImportWrappedKeysWithEoaSessionSig, - testFailImportWrappedKeysWithMaxExpirySessionSig, - testFailImportWrappedKeysWithInvalidSessionSig, - testFailImportWrappedKeysWithExpiredSessionSig, - }; - - const eoaSessionSigsTests = { - testUseEoaSessionSigsToExecuteJsSigning, - testUseEoaSessionSigsToPkpSign, - testUseEoaSessionSigsToExecuteJsSigningInParallel, - testUseEoaSessionSigsToExecuteJsClaimKeys, - testUseEoaSessionSigsToExecuteJsClaimMultipleKeys, - testUseEoaSessionSigsToExecuteJsJsonResponse, - testUseEoaSessionSigsToExecuteJsConsoleLog, - testUseEoaSessionSigsToEncryptDecryptString, - testUseEoaSessionSigsToEncryptDecryptFile, - testUseEoaSessionSigsToEncryptDecryptZip, - testUseEoaSessionSigsToRequestSingleResponse, - }; - - const pkpSessionSigsTests = { - testUsePkpSessionSigsToExecuteJsSigning, - testUsePkpSessionSigsToPkpSign, - testUsePkpSessionSigsToExecuteJsSigningInParallel, - testUsePkpSessionSigsToExecuteJsClaimKeys, - testUsePkpSessionSigsToExecuteJsClaimMultipleKeys, - testUsePkpSessionSigsToExecuteJsJsonResponse, - testUsePkpSessionSigsToExecuteJsConsoleLog, - testUsePkpSessionSigsToEncryptDecryptString, - testUsePkpSessionSigsToEncryptDecryptFile, - testUsePkpSessionSigsToEncryptDecryptZip, - }; - - const litActionSessionSigsTests = { - testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning, - testUseValidLitActionCodeGeneratedSessionSigsToPkpSign, - testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel, - testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys, - testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys, - testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse, - testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog, - testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString, - testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile, - testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip, - - // -- invalid cases - testUseInvalidLitActionIpfsCodeToGenerateSessionSigs, - - // -- custom auth methods - testUseCustomAuthSessionSigsToPkpSignExecuteJs, - }; - - const litActionIpfsIdSessionSigsTests = { - testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign, - testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning, - - // -- invalid cases - testUseInvalidLitActionCodeToGenerateSessionSigs, - }; - - const capacityDelegationTests = { - testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs, - testDelegatingCapacityCreditsNFTToAnotherWalletToPkpSign, - testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs, - testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToExecuteJs, - testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToPkpSign, - testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs, - testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToPkpSign, - }; - - const bareAuthSigTests = { - // -- eth auth sig - testEthAuthSigToEncryptDecryptString, - - // -- solana auth sig - testSolAuthSigToEncryptDecryptString, - - // -- cosmos auth sig - testCosmosAuthSigToEncryptDecryptString, - }; - - const pkpEthersTest = { - eoaSessionSigs: { - testPkpEthersWithEoaSessionSigsToSignWithAuthContext, - testPkpEthersWithEoaSessionSigsToSignMessage, - testPkpEthersWithEoaSessionSigsToEthSign, - testPkpEthersWithEoaSessionSigsToPersonalSign, - testPkpEthersWithEoaSessionSigsToSendTx, - testPkpEthersWithEoaSessionSigsToEthSignTransaction, - testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1, - testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3, - testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4, - testPkpEthersWithEoaSessionSigsToEthSignTypedData, - testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil, - }, - pkpSessionSigs: { - testPkpEthersWithPkpSessionSigsToSignMessage, - testPkpEthersWithPkpSessionSigsToEthSign, - testPkpEthersWithPkpSessionSigsToPersonalSign, - testPkpEthersWithPkpSessionSigsToSendTx, - testPkpEthersWithPkpSessionSigsToEthSignTransaction, - testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1, - testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3, - testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4, - testPkpEthersWithPkpSessionSigsToEthSignTypedData, - testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil, - }, - litActionSessionSigs: { - testPkpEthersWithLitActionSessionSigsToSignMessage, - testPkpEthersWithLitActionSessionSigsToEthSign, - testPkpEthersWithLitActionSessionSigsToPersonalSign, - testPkpEthersWithLitActionSessionSigsToSendTx, - testPkpEthersWithLitActionSessionSigsToEthSignTransaction, - testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1, - testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3, - testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4, - testPkpEthersWithLitActionSessionSigsToEthSignTypedData, - testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil, - }, - }; - - const litActionCombiningTests = { - ecdsaSignAndCombine: { - testExecuteJsSignAndCombineEcdsa, - }, - decryptAndCombine: { - testExecutJsDecryptAndCombine, - }, - broadcastAndCombine: { - testExecuteJsBroadcastAndCollect, - }, - }; - - const testConfig = { - tests: { - // testExample, - // testBundleSpeed, - ...eoaSessionSigsTests, - ...pkpSessionSigsTests, - ...litActionSessionSigsTests, - ...litActionIpfsIdSessionSigsTests, - ...capacityDelegationTests, - ...bareAuthSigTests, - - ...pkpEthersTest.eoaSessionSigs, - ...pkpEthersTest.pkpSessionSigs, - ...pkpEthersTest.litActionSessionSigs, - - ...litActionCombiningTests.broadcastAndCombine, - ...litActionCombiningTests.decryptAndCombine, - ...litActionCombiningTests.ecdsaSignAndCombine, - - ...relayerTests, - ...wrappedKeysTests, - }, - devEnv, - }; - let res; - if (devEnv.processEnvs.RUN_IN_BAND) { - res = await runInBand(testConfig); - } else { - res = await runTestsParallel(testConfig); - } - await devEnv.stopTestnet(); - process.exit(res); -})(); diff --git a/local-tests/tests/test-bundle-speed.ts b/local-tests/tests/test-bundle-speed.ts deleted file mode 100644 index 703b9017f3..0000000000 --- a/local-tests/tests/test-bundle-speed.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test bundle speed - * @param devEnv - */ -export const testBundleSpeed = async (devEnv: TinnyEnvironment) => { - const a = await import('@lit-protocol/lit-node-client'); - const b = await import('@lit-protocol/contracts-sdk'); - const c = await import('@lit-protocol/auth-helpers'); - const d = await import('@lit-protocol/constants'); - const e = await import('@lit-protocol/lit-auth-client'); - - console.log(a, b, c, d, e); -}; diff --git a/local-tests/tests/test-example.ts b/local-tests/tests/test-example.ts deleted file mode 100644 index 9deedaebac..0000000000 --- a/local-tests/tests/test-example.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; - -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -export const testExample = async (devEnv: TinnyEnvironment) => { - // Note: This test will be skipped if we are testing on the Cayenne network - devEnv.setUnavailable(LIT_TESTNET.CAYENNE); - - const alice = await devEnv.createRandomPerson(); - - const aliceEoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - const aliceExecuteJsRes = await devEnv.litNodeClient.executeJs({ - sessionSigs: aliceEoaSessionSigs, - code: `(async () => { - const sigShare = await LitActions.signEcdsa({ - toSign: dataToSign, - publicKey, - sigName: "sig", - }); - })();`, - jsParams: { - dataToSign: alice.loveLetter, - publicKey: alice.pkp.publicKey, - }, - }); - - console.log('aliceExecuteJsRes:', aliceExecuteJsRes); - - devEnv.releasePrivateKeyFromUser(alice); - - // console.log('aliceEoaSessionSigs: ', aliceEoaSessionSigs); - - // const alicePkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - // console.log('alicePkpSessionSigs: ', alicePkpSessionSigs); - - // const aliceLitActionSessionSigs = await getLitActionSessionSigs( - // devEnv, - // alice - // ); - // console.log('aliceLitActionSessionSigs: ', aliceLitActionSessionSigs); -}; diff --git a/local-tests/tests/testCosmosAuthSigToEncryptDecryptString.ts b/local-tests/tests/testCosmosAuthSigToEncryptDecryptString.ts deleted file mode 100644 index 0b2589a916..0000000000 --- a/local-tests/tests/testCosmosAuthSigToEncryptDecryptString.ts +++ /dev/null @@ -1,77 +0,0 @@ -import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs'; -import { ILitNodeClient } from '@lit-protocol/types'; -import { AccessControlConditions } from 'local-tests/setup/accs/accs'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * ❌ NETWORK=cayenne yarn test:local --filter=testCosmosAuthSigToEncryptDecryptString - * ❌ NETWORK=manzano yarn test:local --filter=testCosmosAuthSigToEncryptDecryptString - * ❌ NETWORK=localchain yarn test:local --filter=testCosmosAuthSigToEncryptDecryptString - * ❌ NETWORK=datil-dev yarn test:local --filter=testCosmosAuthSigToEncryptDecryptString - */ -export const testCosmosAuthSigToEncryptDecryptString = async ( - devEnv: TinnyEnvironment -) => { - console.log('❌❌ THIS IS A KNOWN FAILING TEST, PLEASE IGNORE FOR NOW. ❌❌'); - - devEnv.setUnavailable(LIT_TESTNET.CAYENNE); - devEnv.setUnavailable(LIT_TESTNET.LOCALCHAIN); - devEnv.setUnavailable(LIT_TESTNET.MANZANO); - devEnv.setUnavailable(LIT_TESTNET.DATIL_DEV); - - const accs = AccessControlConditions.getCosmosBasicAccessControlConditions({ - userAddress: devEnv.bareCosmosAuthSig.address, - }); - - const encryptRes = await LitJsSdk.encryptString( - { - unifiedAccessControlConditions: accs, - dataToEncrypt: 'Hello world', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - console.log('encryptRes:', encryptRes); - - // -- Expected output:Β΄ - // { - // ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D", - // dataToEncryptHash: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c", - // } - - // -- assertions - if (!encryptRes.ciphertext) { - throw new Error(`Expected "ciphertext" in encryptRes`); - } - - if (!encryptRes.dataToEncryptHash) { - throw new Error(`Expected "dataToEncryptHash" to in encryptRes`); - } - - // -- Decrypt the encrypted string - try { - const decryptRes = await LitJsSdk.decryptToString( - { - unifiedAccessControlConditions: accs, - ciphertext: encryptRes.ciphertext, - dataToEncryptHash: encryptRes.dataToEncryptHash, - authSig: devEnv.bareCosmosAuthSig, - chain: 'cosmos', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - console.log('decryptRes:', decryptRes); - - if (decryptRes !== 'Hello world') { - throw new Error( - `Expected decryptRes to be 'Hello world' but got ${decryptRes}` - ); - } - - console.log('βœ… decryptRes:', decryptRes); - } catch (e) { - console.log('❌ ERROR:', e); - } -}; diff --git a/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs.ts b/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs.ts deleted file mode 100644 index 40f980c158..0000000000 --- a/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { - AuthMethodScope, - AuthMethodType, - LIT_ENDPOINT_VERSION, -} from '@lit-protocol/constants'; -import { LitAuthClient } from '@lit-protocol/lit-auth-client'; -import { LitActionResource, LitPKPResource } from '@lit-protocol/auth-helpers'; -import { LitAbility } from '@lit-protocol/types'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; - -/** - * ## Scenario: - * Delegating capacity credits NFT to Bob (delegatee) for him to execute JS code to sign with his PKP - * - Given: The capacity credits NFT is minted by the dApp owner - * - When: The dApp owner creates a capacity delegation authSig - * - And: The dApp owner delegates the capacity credits NFT to Bob - * - Then: The delegated (Bob's) wallet can execute JS code to sign with his PKP using the capacity from the capacity credits NFT - * - * - * ## Test Commands: - * - ❌ Not supported in Cayenne - * - βœ… NETWORK=manzano yarn test:local --filter=testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs - * - βœ… NETWORK=localchain yarn test:local --filter=testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs - */ -export const testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const bob = await devEnv.createRandomPerson(); - - // Checking the scopes of the PKP owned by Bob - const bobsAuthMethodAuthId = await LitAuthClient.getAuthIdByAuthMethod( - bob.authMethod - ); - - const scopes = - await bob.contractsClient.pkpPermissionsContract.read.getPermittedAuthMethodScopes( - bob.authMethodOwnedPkp.tokenId, - AuthMethodType.EthWallet, - bobsAuthMethodAuthId, - 3 - ); - - if (!scopes[AuthMethodScope.SignAnything]) { - throw new Error('Bob does not have the "SignAnything" scope on his PKP'); - } - - // As a dApp owner, create a capacity delegation authSig for Bob's PKP wallet - const capacityDelegationAuthSig = await alice.createCapacityDelegationAuthSig( - [bob.authMethodOwnedPkp.ethAddress] - ); - - // As a dApp owner, delegate the capacity credits NFT to Bob - const bobPkpSessionSigs = await devEnv.litNodeClient.getPkpSessionSigs({ - pkpPublicKey: bob.authMethodOwnedPkp.publicKey, - authMethods: [bob.authMethod], - resourceAbilityRequests: [ - { - resource: new LitPKPResource('*'), - ability: LitAbility.PKPSigning, - }, - { - resource: new LitActionResource('*'), - ability: LitAbility.LitActionExecution, - }, - ], - capabilityAuthSigs: [capacityDelegationAuthSig], - }); - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: bobPkpSessionSigs, - code: `(async () => { - const sigShare = await LitActions.signEcdsa({ - toSign: dataToSign, - publicKey, - sigName: "sig", - }); - })();`, - jsParams: { - dataToSign: alice.loveLetter, - publicKey: bob.authMethodOwnedPkp.publicKey, - }, - }); - - console.log('βœ… res:', res); - - devEnv.releasePrivateKeyFromUser(alice); - devEnv.releasePrivateKeyFromUser(bob); - - // -- Expected output: - // { - // claims: {}, - // signatures: { - // sig: { - // r: "00fdf6f2fc3f13410393939bb678c8ec26c0eb46bfc39dbecdcf58540b7f9237", - // s: "480b578c78137150db2420669c47b220001b42a0bb4e92194ce7b76f6fd78ddc", - // recid: 0, - // signature: "0x00fdf6f2fc3f13410393939bb678c8ec26c0eb46bfc39dbecdcf58540b7f9237480b578c78137150db2420669c47b220001b42a0bb4e92194ce7b76f6fd78ddc1b", - // publicKey: "0465BFEE5CCFF60C0AF1D9B9481B680C2E34894A88F68F44CC094BA27501FD062A3C4AC61FA850BFA22D81D41AF72CBF983909501440FE51187F5FB3D1BC55C44E", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // }, - // }, - // decryptions: [], - // response: undefined, - // logs: "", - // } - - // -- assertions - if (!res.signatures.sig.r) { - throw new Error(`Expected "r" in res.signatures.sig`); - } - if (!res.signatures.sig.s) { - throw new Error(`Expected "s" in res.signatures.sig`); - } - - if (!res.signatures.sig.dataSigned) { - throw new Error(`Expected "dataSigned" in res.signatures.sig`); - } - - if (!res.signatures.sig.publicKey) { - throw new Error(`Expected "publicKey" in res.signatures.sig`); - } - - // -- signatures.sig.signature must start with 0x - if (!res.signatures.sig.signature.startsWith('0x')) { - throw new Error(`Expected "signature" to start with 0x`); - } -}; diff --git a/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs.ts b/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs.ts deleted file mode 100644 index ea397ebd8e..0000000000 --- a/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getEoaSessionSigsWithCapacityDelegations } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * ## Scenario: - * Delegating capacity credits NFT to Bob (delegatee) for him to execute JS code to sign with his PKP - * - Given: The capacity credits NFT is minted by the dApp owner - * - When: The dApp owner creates a capacity delegation authSig - * - And: The dApp owner delegates the capacity credits NFT to Bob - * - Then: The delegated (Bob's) wallet can execute JS code to sign with his PKP using the capacity from the capacity credits NFT - * - * - * ## Test Commands: - * - ❌ Not supported in Cayenne, but session sigs would still work - * - βœ… NETWORK=manzano yarn test:local --filter=testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs - * - βœ… NETWORK=localchain yarn test:local --filter=testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs - */ -export const testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs = - async (devEnv: TinnyEnvironment) => { - const alice = await devEnv.createRandomPerson(); - const bob = await devEnv.createRandomPerson(); - - const appOwnersCapacityDelegationAuthSig = - await alice.createCapacityDelegationAuthSig([bob.wallet.address]); - - // 4. Bob receives the capacity delegation authSig use it to generate session sigs - const bobsSessionSigs = await getEoaSessionSigsWithCapacityDelegations( - devEnv, - bob.wallet, - appOwnersCapacityDelegationAuthSig - ); - - // -- printing out the recaps from the session sigs - const bobsSingleSessionSig = - bobsSessionSigs[devEnv.litNodeClient.config.bootstrapUrls[0]]; - - console.log('bobsSingleSessionSig:', bobsSingleSessionSig); - - const regex = /urn:recap:[\w+\/=]+/g; - - const recaps = bobsSingleSessionSig.signedMessage.match(regex) || []; - - recaps.forEach((r) => { - const encodedRecap = r.split(':')[2]; - const decodedRecap = Buffer.from(encodedRecap, 'base64').toString(); - console.log(decodedRecap); - }); - - // 5. Bob can now execute JS code using the capacity credits NFT - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: bobsSessionSigs, - code: `(async () => { - const sigShare = await LitActions.signEcdsa({ - toSign: dataToSign, - publicKey, - sigName: "sig", - }); - })();`, - jsParams: { - dataToSign: alice.loveLetter, - publicKey: bob.pkp.publicKey, - }, - }); - - devEnv.releasePrivateKeyFromUser(alice); - devEnv.releasePrivateKeyFromUser(bob); - - // Expected output: - // { - // claims: {}, - // signatures: { - // sig: { - // r: "0f4b8b20369a8a021aae7c2083076715820e32d2b18826ea7ccea525a9adadc2", - // s: "43aa338fa2c90e13c88d9b432d7ee6c8e3df006b8ef94ad5b4ab32d64b507f17", - // recid: 1, - // signature: "0x0f4b8b20369a8a021aae7c2083076715820e32d2b18826ea7ccea525a9adadc243aa338fa2c90e13c88d9b432d7ee6c8e3df006b8ef94ad5b4ab32d64b507f171c", - // publicKey: "0406A76D2A6E3E729A537640C8C41592BBC2675799CCBBF310CD410691C028C529C5A8DE8016933CEC0B06EC7AA0FFAFBA2791158A11D382C558376DF392F436AD", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // }, - // }, - // decryptions: [], - // response: undefined, - // logs: "", - // } - - // -- assertions - if (!res.signatures.sig.r) { - throw new Error(`Expected "r" in res.signatures.sig`); - } - if (!res.signatures.sig.s) { - throw new Error(`Expected "s" in res.signatures.sig`); - } - - if (!res.signatures.sig.dataSigned) { - throw new Error(`Expected "dataSigned" in res.signatures.sig`); - } - - if (!res.signatures.sig.publicKey) { - throw new Error(`Expected "publicKey" in res.signatures.sig`); - } - - // -- signatures.sig.signature must start with 0x - if (!res.signatures.sig.signature.startsWith('0x')) { - throw new Error(`Expected "signature" to start with 0x`); - } - - // -- signatures.sig.recid must be parseable as a number - if (isNaN(res.signatures.sig.recid)) { - throw new Error(`Expected "recid" to be parseable as a number`); - } - - console.log( - 'βœ… testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs' - ); - }; diff --git a/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherWalletToPkpSign.ts b/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherWalletToPkpSign.ts deleted file mode 100644 index 1d625ad771..0000000000 --- a/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherWalletToPkpSign.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getEoaSessionSigsWithCapacityDelegations } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * ## Scenario: - * Delegating capacity credits NFT to Bob (delegatee) for him to execute JS code to sign with his PKP - * - Given: The capacity credits NFT is minted by the dApp owner - * - When: The dApp owner creates a capacity delegation authSig - * - And: The dApp owner delegates the capacity credits NFT to Bob - * - Then: The delegated (Bob's) wallet can execute JS code to sign with his PKP using the capacity from the capacity credits NFT - * - * - * ## Test Commands: - * - ❌ Not supported in Cayenne, but session sigs would still work - * - βœ… NETWORK=manzano yarn test:local --filter=testDelegatingCapacityCreditsNFTToAnotherWalletToPkpSign - * - βœ… NETWORK=localchain yarn test:local --filter=testDelegatingCapacityCreditsNFTToAnotherWalletToPkpSign - */ -export const testDelegatingCapacityCreditsNFTToAnotherWalletToPkpSign = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const bob = await devEnv.createRandomPerson(); - - const appOwnersCapacityDelegationAuthSig = - await alice.createCapacityDelegationAuthSig([bob.wallet.address]); - - // 4. Bob receives the capacity delegation authSig use it to generate session sigs - const bobsSessionSigs = await getEoaSessionSigsWithCapacityDelegations( - devEnv, - bob.wallet, - appOwnersCapacityDelegationAuthSig - ); - - // -- printing out the recaps from the session sigs - const bobsSingleSessionSig = - bobsSessionSigs[devEnv.litNodeClient.config.bootstrapUrls[0]]; - - console.log('bobsSingleSessionSig:', bobsSingleSessionSig); - - const regex = /urn:recap:[\w+\/=]+/g; - - const recaps = bobsSingleSessionSig.signedMessage.match(regex) || []; - - recaps.forEach((r) => { - const encodedRecap = r.split(':')[2]; - const decodedRecap = Buffer.from(encodedRecap, 'base64').toString(); - console.log(decodedRecap); - }); - - // 5. Bob can now execute JS code using the capacity credits NFT - const res = await devEnv.litNodeClient.pkpSign({ - sessionSigs: bobsSessionSigs, - toSign: alice.loveLetter, - pubKey: bob.pkp.publicKey, - }); - - devEnv.releasePrivateKeyFromUser(alice); - devEnv.releasePrivateKeyFromUser(bob); - - // -- Expected output: - // { - // r: "25e04b2abdf220b1374b19228bc292bab71a3224a635726a46d4cbe3a62bb636", - // s: "1e5d96ffa6ec7cca961ec7bfa90e524a08b1c4fc9a833b69d8727eff1453064c", - // recid: 0, - // signature: "0x25e04b2abdf220b1374b19228bc292bab71a3224a635726a46d4cbe3a62bb6361e5d96ffa6ec7cca961ec7bfa90e524a08b1c4fc9a833b69d8727eff1453064c1b", - // publicKey: "041FF0DC7B69D2B3C3E452AF9E0D30C7FDA6729A1B394059BDC8C4530D7F584FFCAEEEC19B1F22EFB054A22E5EF13AA0B5804994469570929066F5474D490B8A1F", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // } - - // -- assertions - if (!res.r) { - throw new Error(`Expected "r" in res`); - } - if (!res.s) { - throw new Error(`Expected "s" in res`); - } - - if (!res.dataSigned) { - throw new Error(`Expected "dataSigned" in res`); - } - - if (!res.publicKey) { - throw new Error(`Expected "publicKey" in res`); - } - - // -- signature must start with 0x - if (!res.signature.startsWith('0x')) { - throw new Error(`Expected "signature" to start with 0x`); - } - - // -- recid must be parseable as a number - if (isNaN(res.recid)) { - throw new Error(`Expected "recid" to be parseable as a number`); - } - - console.log('βœ… res:', res); -}; diff --git a/local-tests/tests/testEthAuthSigToEncryptDecryptString.ts b/local-tests/tests/testEthAuthSigToEncryptDecryptString.ts deleted file mode 100644 index 744dc55cdc..0000000000 --- a/local-tests/tests/testEthAuthSigToEncryptDecryptString.ts +++ /dev/null @@ -1,75 +0,0 @@ -import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs'; -import { ILitNodeClient } from '@lit-protocol/types'; -import { AccessControlConditions } from 'local-tests/setup/accs/accs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { log } from '@lit-protocol/misc'; -import { CENTRALISATION_BY_NETWORK } from '@lit-protocol/constants'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testEthAuthSigToEncryptDecryptString - * βœ… NETWORK=manzano yarn test:local --filter=testEthAuthSigToEncryptDecryptString - * βœ… NETWORK=localchain yarn test:local --filter=testEthAuthSigToEncryptDecryptString - */ -export const testEthAuthSigToEncryptDecryptString = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - if (CENTRALISATION_BY_NETWORK[devEnv.network] === 'decentralised') { - // The capacity credits NFT owner automatically uses the capacity credits - // to pay for the encryption - await alice.mintCapacityCreditsNFT(); - } - - const accs = AccessControlConditions.getEmvBasicAccessControlConditions({ - userAddress: alice.authSig.address, - }); - - const encryptRes = await LitJsSdk.encryptString( - { - accessControlConditions: accs, - dataToEncrypt: 'Hello world', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - log('encryptRes:', encryptRes); - - // await 5 seconds for the encryption to be mined - - // -- Expected output:Β΄ - // { - // ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D", - // dataToEncryptHash: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c", - // } - - // -- assertions - if (!encryptRes.ciphertext) { - throw new Error(`Expected "ciphertext" in encryptRes`); - } - - if (!encryptRes.dataToEncryptHash) { - throw new Error(`Expected "dataToEncryptHash" to in encryptRes`); - } - - // -- Decrypt the encrypted string - const decryptRes = await LitJsSdk.decryptToString( - { - accessControlConditions: accs, - ciphertext: encryptRes.ciphertext, - dataToEncryptHash: encryptRes.dataToEncryptHash, - authSig: alice.authSig, - chain: 'ethereum', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - if (decryptRes !== 'Hello world') { - throw new Error( - `Expected decryptRes to be 'Hello world' but got ${decryptRes}` - ); - } - - console.log('βœ… decryptRes:', decryptRes); -}; diff --git a/local-tests/tests/testExecuteJsBroadcastAndCollect.ts b/local-tests/tests/testExecuteJsBroadcastAndCollect.ts deleted file mode 100644 index 3b056db7f5..0000000000 --- a/local-tests/tests/testExecuteJsBroadcastAndCollect.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { AccessControlConditions } from 'local-tests/setup/accs/accs'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString - * ❌ NOT AVAILABLE IN MANZANO - * βœ… NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString - * βœ… NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString - * - */ -export const testExecuteJsBroadcastAndCollect = async ( - devEnv: TinnyEnvironment -) => { - devEnv.setUnavailable(LIT_TESTNET.MANZANO); - - const alice = await devEnv.createRandomPerson(); - // set access control conditions for encrypting and decrypting - const accs = AccessControlConditions.getEmvBasicAccessControlConditions({ - userAddress: alice.authMethodOwnedPkp.ethAddress, - }); - - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice); - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: litActionSessionSigs, - code: `(async () => { - let rand = Math.floor(Math.random() * 100); - const resp = await Lit.Actions.broadcastAndCollect({ - name: "temperature", - value: rand.toString(), - }); - Lit.Actions.setResponse({ - response: JSON.stringify(resp) - }); - })();`, - jsParams: {}, - }); - devEnv.releasePrivateKeyFromUser(alice); - - const response = res.response; - if (!response) { - throw new Error('Should contained broadcast data'); - } -}; diff --git a/local-tests/tests/testExecuteJsDecryptAndCombine.ts b/local-tests/tests/testExecuteJsDecryptAndCombine.ts deleted file mode 100644 index 3b24cd4416..0000000000 --- a/local-tests/tests/testExecuteJsDecryptAndCombine.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs'; -import { ILitNodeClient, LitAbility } from '@lit-protocol/types'; -import { AccessControlConditions } from 'local-tests/setup/accs/accs'; -import { - LitAccessControlConditionResource, - LitActionResource, -} from '@lit-protocol/auth-helpers'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { log } from '@lit-protocol/misc'; -import * as accessControlConditions from '@lit-protocol/access-control-conditions'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString - * ❌ NOT AVAILABLE IN MANZANO - * βœ… NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString - * βœ… NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString - * - */ -export const testExecutJsDecryptAndCombine = async ( - devEnv: TinnyEnvironment -) => { - devEnv.setUnavailable(LIT_TESTNET.MANZANO); - - const alice = await devEnv.createRandomPerson(); - // set access control conditions for encrypting and decrypting - const accs = AccessControlConditions.getEmvBasicAccessControlConditions({ - userAddress: alice.authMethodOwnedPkp.ethAddress, - }); - - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice); - - const encryptRes = await LitJsSdk.encryptString( - { - accessControlConditions: accs, - dataToEncrypt: 'Hello world', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - log('encryptRes:', encryptRes); - - // -- Expected output: - // { - // ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D", - // dataToEncryptHash: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c", - // } - - // -- assertions - if (!encryptRes.ciphertext) { - throw new Error(`Expected "ciphertext" in encryptRes`); - } - - if (!encryptRes.dataToEncryptHash) { - throw new Error(`Expected "dataToEncryptHash" to in encryptRes`); - } - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: litActionSessionSigs, - code: `(async () => { - const resp = await Lit.Actions.decryptAndCombine({ - accessControlConditions, - ciphertext, - dataToEncryptHash, - authSig: null, - chain: 'ethereum', - }); - Lit.Actions.setResponse({ - response: resp - }); - })();`, - jsParams: { - accessControlConditions: accs, - dataToEncryptHash: encryptRes.dataToEncryptHash, - ciphertext: encryptRes.ciphertext, - }, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - if (res.response !== 'Hello world') { - throw new Error('content does not match what was expected'); - } -}; diff --git a/local-tests/tests/testExecuteJsSignAndCombineEcdsa.ts b/local-tests/tests/testExecuteJsSignAndCombineEcdsa.ts deleted file mode 100644 index d2c808e776..0000000000 --- a/local-tests/tests/testExecuteJsSignAndCombineEcdsa.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getEoaSessionSigsWithCapacityDelegations } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * ## Scenario: - * Testing unrestricted access to execute js code using a capacity delegation authSig without specific delegatee restrictions - * - Given: A capacity delegation authSig is created by the dApp owner - * - When: The authSig does not specifically restrict delegatees - * - And: Any user attempts to execute js code using the capacity from the capacity credits NFT - * - Then: The user should be able to sign with his/her PKP using the capacity without restrictions due to the absence of delegatee limits - * - * - * ## Test Commands: - * - ❌ Not supported in Cayenne, but session sigs would still work - * - βœ… NETWORK=manzano yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs - * - βœ… NETWORK=localchain yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs - */ -export const testExecuteJsSignAndCombineEcdsa = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const bob = await devEnv.createRandomPerson(); - - const appOwnersCapacityDelegationAuthSig = ( - await devEnv.litNodeClient.createCapacityDelegationAuthSig({ - dAppOwnerWallet: alice.wallet, - }) - ).capacityDelegationAuthSig; - - // 3. Bob gets the capacity delegation authSig from somewhere and uses it to get session sigs - const bobsSessionSigs = await getEoaSessionSigsWithCapacityDelegations( - devEnv, - bob.wallet, - appOwnersCapacityDelegationAuthSig - ); - - // -- printing out the recaps from the session sigs - const bobsSingleSessionSig = - bobsSessionSigs[devEnv.litNodeClient.config.bootstrapUrls[0]]; - - console.log('bobsSingleSessionSig:', bobsSingleSessionSig); - - const regex = /urn:recap:[\w+\/=]+/g; - - const recaps = bobsSingleSessionSig.signedMessage.match(regex) || []; - - recaps.forEach((r) => { - const encodedRecap = r.split(':')[2]; - const decodedRecap = Buffer.from(encodedRecap, 'base64').toString(); - console.log(decodedRecap); - }); - - // 4. Bob can now execute JS code using the capacity credits NFT - // 5. Bob can now execute JS code using the capacity credits NFT - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: bobsSessionSigs, - code: `(async () => { - const sigShare = await LitActions.signAndCombineEcdsa({ - toSign: dataToSign, - publicKey, - sigName: "sig", - }); - Lit.Actions.setResponse({ - response: sigShare - }); - })();`, - jsParams: { - dataToSign: alice.loveLetter, - publicKey: bob.pkp.publicKey, - }, - }); - - devEnv.releasePrivateKeyFromUser(alice); - devEnv.releasePrivateKeyFromUser(bob); - - /** - Response format - { - "success": true, - "signedData": {}, - "decryptedData": {}, - "claimData": {}, - "response": "{\"r\":\"026eede14267ca76064a7e22dbe6f9e44d786c7b5917b7d023f45ee4e84ce1ea47\",\"s\":\"22a6048bcb88d724d45bdb6161fefd151483f41d592d167e5c33f42e9fe6dac6\",\"v\":0}", - "logs": "" - } - */ - - if (!res.response) { - throw new Error('Response not found, expecting signature in response'); - } - - const sig = JSON.parse(res.response as string); - console.log('signature returned as a response', sig); - - if (!sig.r) { - throw new Error('invalid signature returned from lit action'); - } - - if (!sig.s) { - throw new Error('invalid signature returned from lit action'); - } - - if (sig.v === undefined) { - throw new Error('invalid signature returned from lit action'); - } - console.log('βœ… testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs'); -}; diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSign.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSign.ts deleted file mode 100644 index ff681d6c07..0000000000 --- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSign.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSign - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSign - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSign - */ -export const testPkpEthersWithEoaSessionSigsToEthSign = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - console.log('devEnv.network:', devEnv.network); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: eoaSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- test eth_sign - try { - // Message to sign - const message = 'Hello world'; - const hexMsg = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(message)); - - // DATA, 20 Bytes - address - // DATA, N Bytes - message to sign - // Reference: https://ethereum.github.io/execution-apis/api-documentation/#eth_sign - const signature = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_sign', - params: [alice.pkp.ethAddress, hexMsg], - }, - }); - const recoveredAddr = ethers.utils.verifyMessage(message, signature); - - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr !== alice.pkp.ethAddress) { - throw new Error( - `❌ test eth_sign recoveredAddr should be ${alice.pkp.ethAddress} but got ${recoveredAddr}` - ); - } - - console.log('βœ… recoveredAddr:', recoveredAddr); - } catch (e) { - throw new Error('❌ Error: ' + e.message); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTransaction.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTransaction.ts deleted file mode 100644 index accf022ad0..0000000000 --- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTransaction.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTransaction - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTransaction - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTransaction - */ -export const testPkpEthersWithEoaSessionSigsToEthSignTransaction = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: eoaSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- eth_sendTransaction parameters - try { - // Transaction to sign and send - const from = alice.pkp.ethAddress; - const to = alice.pkp.ethAddress; - const gasLimit = ethers.BigNumber.from('21000'); - const value = ethers.BigNumber.from('0'); - const data = '0x'; - - // pkp-ethers signer will automatically add missing fields (nonce, chainId, gasPrice, gasLimit) - const tx = { - from: from, - to: to, - gasLimit, - value, - data, - }; - - // eth_sendTransaction parameters - // Transaction - Object - // Reference: https://ethereum.github.io/execution-apis/api-documentation/#eth_sendTransaction - // A serialized form of the whole transaction - const rawSignedTx = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_signTransaction', - params: [tx], - }, - }); - - const parsedTransaction = ethers.utils.parseTransaction(rawSignedTx); - - const signature = ethers.utils.joinSignature({ - r: parsedTransaction.r, - s: parsedTransaction.s, - v: parsedTransaction.v, - }); - - const rawTx = { - nonce: parsedTransaction.nonce, - gasPrice: parsedTransaction.gasPrice, - gasLimit: parsedTransaction.gasLimit, - to: parsedTransaction.to, - value: parsedTransaction.value, - data: parsedTransaction.data, - chainId: parsedTransaction.chainId, // Include chainId if the transaction is EIP-155 - }; - - const txHash = ethers.utils.keccak256( - ethers.utils.serializeTransaction(rawTx) - ); - - const { v, r, s } = parsedTransaction; - - const recoveredAddress = ethers.utils.recoverAddress(txHash, { r, s, v }); - - // ==================== Post-Validation ==================== - if (!parsedTransaction) { - throw new Error('❌ parsedTransaction should not be null'); - } - - if (signature.length !== 132) { - throw new Error( - `❌ signature should be 132 characters long, got ${signature.length}` - ); - } - - if (recoveredAddress.toLowerCase() !== alice.pkp.ethAddress.toLowerCase()) { - throw new Error( - `❌ recoveredAddres should be ${alice.pkp.ethAddress}, got ${recoveredAddress}` - ); - } - } catch (e) { - if (e.message.includes('insufficient FPE funds')) { - console.log( - `πŸ§ͺ PKPEthersWallet should be able to send tx (insufficient FPE funds ❗️)` - ); - } else { - throw new Error(`❌ Error: ${e.toString()}`); - } - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedData.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedData.ts deleted file mode 100644 index c1d7c29a4b..0000000000 --- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedData.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedData - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedData - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedData - */ -export const testPkpEthersWithEoaSessionSigsToEthSignTypedData = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: eoaSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- eth_signTypedData parameters - try { - // Example from https://github.com/MetaMask/test-dapp/blob/main/src/index.js#L1033 - const msgParams = { - types: { - EIP712Domain: [ - { name: 'name', type: 'string' }, - { name: 'version', type: 'string' }, - { name: 'chainId', type: 'uint256' }, - { name: 'verifyingContract', type: 'address' }, - ], - Person: [ - { name: 'name', type: 'string' }, - { name: 'wallet', type: 'address' }, - ], - Mail: [ - { name: 'from', type: 'Person' }, - { name: 'to', type: 'Person' }, - { name: 'contents', type: 'string' }, - ], - }, - primaryType: 'Mail', - domain: { - name: 'Ether Mail', - version: '1', - chainId: 80001, - verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', - }, - message: { - from: { - name: 'Cow', - wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', - }, - to: { - name: 'Bob', - wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - }, - contents: 'Hello, Bob!', - }, - }; - - const signature = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_signTypedData', - params: [alice.pkp.ethAddress, JSON.stringify(msgParams)], - }, - }); - - // https://docs.ethers.io/v5/api/utils/signing-key/#utils-verifyTypedData - const recoveredAddr = ethers.utils.verifyTypedData( - msgParams.domain, - { Person: msgParams.types.Person, Mail: msgParams.types.Mail }, - msgParams.message, - signature - ); - - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr.toLowerCase() !== alice.pkp.ethAddress.toLowerCase()) { - throw new Error( - `❌ recoveredAddr ${recoveredAddr} should be ${alice.pkp.ethAddress}` - ); - } - } catch (e) { - throw new Error(`❌ ${e.toString()}`); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil.ts deleted file mode 100644 index 41b0d7f2e4..0000000000 --- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { - PKPEthersWallet, - ethRequestHandler, - signTypedData, -} from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil - */ -export const testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: eoaSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- eth_signTypedData parameters - try { - // Example from https://github.com/MetaMask/test-dapp/blob/main/src/index.js#L1033 - const msgParams = { - types: { - EIP712Domain: [ - { name: 'name', type: 'string' }, - { name: 'version', type: 'string' }, - { name: 'chainId', type: 'uint256' }, - { name: 'verifyingContract', type: 'address' }, - ], - Person: [ - { name: 'name', type: 'string' }, - { name: 'wallet', type: 'address' }, - ], - Mail: [ - { name: 'from', type: 'Person' }, - { name: 'to', type: 'Person' }, - { name: 'contents', type: 'string' }, - ], - }, - primaryType: 'Mail', - domain: { - name: 'Ether Mail', - version: '1', - chainId: 80001, - verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', - }, - message: { - from: { - name: 'Cow', - wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', - }, - to: { - name: 'Bob', - wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - }, - contents: 'Hello, Bob!', - }, - }; - const signature = await signTypedData(pkpEthersWallet, msgParams); - - // https://docs.ethers.io/v5/api/utils/signing-key/#utils-verifyTypedData - const recoveredAddr = ethers.utils.verifyTypedData( - msgParams.domain, - { Person: msgParams.types.Person, Mail: msgParams.types.Mail }, - msgParams.message, - signature - ); - - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr.toLowerCase() !== alice.pkp.ethAddress.toLowerCase()) { - throw new Error( - `❌ recoveredAddr ${recoveredAddr} should be ${alice.pkp.ethAddress}` - ); - } - } catch (e) { - throw new Error(`❌ ${e.toString()}`); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1.ts deleted file mode 100644 index a63712d77a..0000000000 --- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { - SignTypedDataVersion, - recoverTypedSignature, -} from '@metamask/eth-sig-util'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1 - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1 - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1 - */ -export const testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1 = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: eoaSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- eth_signTypedData_v1 parameters - try { - const msgParams = [ - { - type: 'string', - name: 'Message', - value: 'Hi, Alice!', - }, - { - type: 'uint32', - name: 'A number', - value: '1337', - }, - ]; - - const signature = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_signTypedData_v1', - params: [msgParams, alice.pkp.ethAddress], - }, - }); - - const signatureBytes = ethers.utils.arrayify(signature); - - const recoveredAddr = recoverTypedSignature({ - data: msgParams, - signature: signatureBytes as any, - version: SignTypedDataVersion.V1, - }); - - // ==================== Post-Validation ==================== - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr.toLowerCase() !== alice.pkp.ethAddress.toLowerCase()) { - throw new Error( - `❌ recoveredAddr ${recoveredAddr} should be ${alice.pkp.ethAddress}` - ); - } - - console.log('signature: ', signature); - console.log('recoveredAddr: ', recoveredAddr); - } catch (e) { - throw new Error(`❌ ${e.toString()}`); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3.ts deleted file mode 100644 index 96c1727b14..0000000000 --- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { - SignTypedDataVersion, - recoverTypedSignature, -} from '@metamask/eth-sig-util'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3 - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3 - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3 - */ -export const testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3 = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: eoaSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- eth_signTypedData_v3 parameters - try { - const msgParams = { - types: { - EIP712Domain: [ - { name: 'name', type: 'string' }, - { name: 'version', type: 'string' }, - { name: 'chainId', type: 'uint256' }, - { name: 'verifyingContract', type: 'address' }, - ], - Person: [ - { name: 'name', type: 'string' }, - { name: 'wallet', type: 'address' }, - ], - Mail: [ - { name: 'from', type: 'Person' }, - { name: 'to', type: 'Person' }, - { name: 'contents', type: 'string' }, - ], - }, - primaryType: 'Mail', - domain: { - name: 'Ether Mail', - version: '1', - chainId: 80001, - verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', - }, - message: { - from: { - name: 'Cow', - wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', - }, - to: { - name: 'Bob', - wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - }, - contents: 'Hello, Bob!', - }, - }; - - const signature = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_signTypedData_v3', - params: [alice.pkp.ethAddress, JSON.stringify(msgParams)], - }, - }); - - const recoveredAddr = recoverTypedSignature({ - data: { - // @ts-ignore - types: msgParams.types, - // @ts-ignore - domain: msgParams.domain, - // @ts-ignore - primaryType: msgParams.primaryType, - // @ts-ignore - message: msgParams.message, - }, - signature: signature, - version: SignTypedDataVersion.V3, - }); - - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr.toLowerCase() !== alice.pkp.ethAddress.toLowerCase()) { - throw new Error( - `❌ recoveredAddr ${recoveredAddr} should be ${alice.pkp.ethAddress}` - ); - } - } catch (e) { - throw new Error(`❌ ${e.toString()}`); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4.ts deleted file mode 100644 index 1f2c6ff0a7..0000000000 --- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { - SignTypedDataVersion, - recoverTypedSignature, -} from '@metamask/eth-sig-util'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4 - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4 - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4 - */ -export const testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4 = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: eoaSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- eth_signTypedData_v3 parameters - try { - const msgParams = { - domain: { - chainId: 80001, - name: 'Ether Mail', - verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', - version: '1', - }, - message: { - contents: 'Hello, Bob!', - from: { - name: 'Cow', - wallets: [ - '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', - '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF', - ], - }, - to: [ - { - name: 'Bob', - wallets: [ - '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - '0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57', - '0xB0B0b0b0b0b0B000000000000000000000000000', - ], - }, - ], - }, - primaryType: 'Mail', - types: { - EIP712Domain: [ - { name: 'name', type: 'string' }, - { name: 'version', type: 'string' }, - { name: 'chainId', type: 'uint256' }, - { name: 'verifyingContract', type: 'address' }, - ], - Mail: [ - { name: 'from', type: 'Person' }, - { name: 'to', type: 'Person[]' }, - { name: 'contents', type: 'string' }, - ], - Person: [ - { name: 'name', type: 'string' }, - { name: 'wallets', type: 'address[]' }, - ], - }, - }; - - const signature = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_signTypedData_v4', - params: [alice.pkp.ethAddress, JSON.stringify(msgParams)], - }, - }); - - const recoveredAddr = recoverTypedSignature({ - data: msgParams as any, - signature: signature, - version: SignTypedDataVersion.V4, - }); - - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr.toLowerCase() !== alice.pkp.ethAddress.toLowerCase()) { - throw new Error( - `❌ recoveredAddr ${recoveredAddr} should be ${alice.pkp.ethAddress}` - ); - } - } catch (e) { - throw new Error(`❌ ${e.toString()}`); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToPersonalSign.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToPersonalSign.ts deleted file mode 100644 index b4cb9f79df..0000000000 --- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToPersonalSign.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToPersonalSign - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToPersonalSign - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToPersonalSign - */ -export const testPkpEthersWithEoaSessionSigsToPersonalSign = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: eoaSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- personal_sign parameters - try { - // Message to sign - const message = 'Free the web'; - const hexMsg = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(message)); - - // personal_sign parameters - // DATA, N Bytes - message to sign. - // DATA, 20 Bytes - address - // Reference: https://metamask.github.io/api-playground/api-documentation/#personal_sign - const signature = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'personal_sign', - params: [hexMsg, alice.pkp.ethAddress], - }, - }); - - const recoveredAddr = ethers.utils.verifyMessage(message, signature); - - // ==================== Post-Validation ==================== - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr !== alice.pkp.ethAddress) { - throw new Error( - `❌ recoveredAddr should be ${alice.pkp.ethAddress} but got ${recoveredAddr}` - ); - } - - console.log('βœ… personal_sign recoveredAddr:', recoveredAddr); - } catch (e) { - throw new Error('❌ Error: ' + e.message); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToSendTx.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToSendTx.ts deleted file mode 100644 index ad333351d3..0000000000 --- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToSendTx.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSendTx - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSendTx - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSendTx - */ -export const testPkpEthersWithEoaSessionSigsToSendTx = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: eoaSessionSigs, - }); - - await devEnv.getFunds(alice.pkp.ethAddress); - - await pkpEthersWallet.init(); - - // -- eth_sendTransaction parameters - try { - // Transaction to sign and send - const from = alice.pkp.ethAddress; - const to = alice.pkp.ethAddress; - const gasLimit = ethers.BigNumber.from('21000'); - const value = ethers.BigNumber.from('0'); - const data = '0x'; - - // pkp-ethers signer will automatically add missing fields (nonce, chainId, gasPrice, gasLimit) - const tx = { - from: from, - to: to, - gasLimit, - value, - data, - }; - - const txRes = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_sendTransaction', - params: [tx], - }, - }); - - console.log('βœ… txRes:', txRes); - } catch (e) { - if (e.message.includes('insufficient FPE funds')) { - console.log( - `πŸ§ͺ PKPEthersWallet should be able to send tx (insufficient FPE funds ❗️)` - ); - } else { - throw new Error(`❌ Error: ${e.toString()}`); - } - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToSignMessage.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToSignMessage.ts deleted file mode 100644 index d3e5e4cb98..0000000000 --- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToSignMessage.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSignMessage - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSignMessage - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSignMessage - */ -export const testPkpEthersWithEoaSessionSigsToSignMessage = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: eoaSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- test signMessage - try { - const signature = await pkpEthersWallet.signMessage(alice.loveLetter); - console.log('βœ… signature:', signature); - } catch (e) { - throw new Error('❌ Error: ' + e.message); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToSignWithAuthContext.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToSignWithAuthContext.ts deleted file mode 100644 index 456aa2692c..0000000000 --- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToSignWithAuthContext.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { - LitAbility, - LitActionResource, - LitPKPResource, - createSiweMessageWithRecaps, - generateAuthSig, -} from '@lit-protocol/auth-helpers'; -import { PKPEthersWallet } from '@lit-protocol/pkp-ethers'; -import { AuthCallbackParams, AuthSig } from '@lit-protocol/types'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSignWithAuthContext - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSignWithAuthContext - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSignWithAuthContext - */ -export const testPkpEthersWithEoaSessionSigsToSignWithAuthContext = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - const pkpEthersWallet = new PKPEthersWallet({ - pkpPubKey: alice.pkp.publicKey, - litNodeClient: devEnv.litNodeClient, - authContext: { - client: devEnv.litNodeClient, - getSessionSigsProps: { - authNeededCallback: async function ( - params: AuthCallbackParams - ): Promise { - const toSign = await createSiweMessageWithRecaps({ - uri: params.uri, - expiration: params.expiration, - resources: params.resourceAbilityRequests, - walletAddress: alice.wallet.address, - nonce: await devEnv.litNodeClient.getLatestBlockhash(), - litNodeClient: devEnv.litNodeClient, - }); - - const authSig = await generateAuthSig({ - signer: alice.wallet, - toSign, - }); - - return authSig; - }, - resourceAbilityRequests: [ - { - resource: new LitPKPResource('*'), - ability: LitAbility.PKPSigning, - }, - { - resource: new LitActionResource('*'), - ability: LitAbility.LitActionExecution, - }, - ], - }, - }, - }); - - await pkpEthersWallet.init(); - - try { - const signature = await pkpEthersWallet.signMessage(alice.loveLetter); - console.log('βœ… signature:', signature); - } catch (e) { - throw new Error('❌ Error: ' + e.message); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSign.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSign.ts deleted file mode 100644 index 28439833ab..0000000000 --- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSign.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSign - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSign - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSign - */ -export const testPkpEthersWithLitActionSessionSigsToEthSign = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice); - - console.log('devEnv.network:', devEnv.network); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: litActionSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- test eth_sign - try { - // Message to sign - const message = 'Hello world'; - const hexMsg = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(message)); - - // DATA, 20 Bytes - address - // DATA, N Bytes - message to sign - // Reference: https://ethereum.github.io/execution-apis/api-documentation/#eth_sign - const signature = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_sign', - params: [alice.pkp.ethAddress, hexMsg], - }, - }); - const recoveredAddr = ethers.utils.verifyMessage(message, signature); - - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr !== alice.pkp.ethAddress) { - throw new Error( - `❌ test eth_sign recoveredAddr should be ${alice.pkp.ethAddress} but got ${recoveredAddr}` - ); - } - - console.log('βœ… recoveredAddr:', recoveredAddr); - } catch (e) { - throw new Error('❌ Error: ' + e.message); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTransaction.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTransaction.ts deleted file mode 100644 index 8542bcc55c..0000000000 --- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTransaction.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTransaction - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTransaction - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTransaction - */ -export const testPkpEthersWithLitActionSessionSigsToEthSignTransaction = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: litActionSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- eth_sendTransaction parameters - try { - // Transaction to sign and send - const from = alice.pkp.ethAddress; - const to = alice.pkp.ethAddress; - const gasLimit = ethers.BigNumber.from('21000'); - const value = ethers.BigNumber.from('0'); - const data = '0x'; - - // pkp-ethers signer will automatically add missing fields (nonce, chainId, gasPrice, gasLimit) - const tx = { - from: from, - to: to, - gasLimit, - value, - data, - }; - - // eth_sendTransaction parameters - // Transaction - Object - // Reference: https://ethereum.github.io/execution-apis/api-documentation/#eth_sendTransaction - // A serialized form of the whole transaction - const rawSignedTx = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_signTransaction', - params: [tx], - }, - }); - - const parsedTransaction = ethers.utils.parseTransaction(rawSignedTx); - - const signature = ethers.utils.joinSignature({ - r: parsedTransaction.r, - s: parsedTransaction.s, - v: parsedTransaction.v, - }); - - const rawTx = { - nonce: parsedTransaction.nonce, - gasPrice: parsedTransaction.gasPrice, - gasLimit: parsedTransaction.gasLimit, - to: parsedTransaction.to, - value: parsedTransaction.value, - data: parsedTransaction.data, - chainId: parsedTransaction.chainId, // Include chainId if the transaction is EIP-155 - }; - - const txHash = ethers.utils.keccak256( - ethers.utils.serializeTransaction(rawTx) - ); - - const { v, r, s } = parsedTransaction; - - const recoveredAddress = ethers.utils.recoverAddress(txHash, { r, s, v }); - - // ==================== Post-Validation ==================== - if (!parsedTransaction) { - throw new Error('❌ parsedTransaction should not be null'); - } - - if (signature.length !== 132) { - throw new Error( - `❌ signature should be 132 characters long, got ${signature.length}` - ); - } - - if (recoveredAddress.toLowerCase() !== alice.pkp.ethAddress.toLowerCase()) { - throw new Error( - `❌ recoveredAddres should be ${alice.pkp.ethAddress}, got ${recoveredAddress}` - ); - } - } catch (e) { - if (e.message.includes('insufficient FPE funds')) { - console.log( - `πŸ§ͺ PKPEthersWallet should be able to send tx (insufficient FPE funds ❗️)` - ); - } else { - throw new Error(`❌ Error: ${e.toString()}`); - } - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedData.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedData.ts deleted file mode 100644 index 2ddf80f082..0000000000 --- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedData.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedData - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedData - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedData - */ -export const testPkpEthersWithLitActionSessionSigsToEthSignTypedData = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: litActionSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- eth_signTypedData parameters - try { - // Example from https://github.com/MetaMask/test-dapp/blob/main/src/index.js#L1033 - const msgParams = { - types: { - EIP712Domain: [ - { name: 'name', type: 'string' }, - { name: 'version', type: 'string' }, - { name: 'chainId', type: 'uint256' }, - { name: 'verifyingContract', type: 'address' }, - ], - Person: [ - { name: 'name', type: 'string' }, - { name: 'wallet', type: 'address' }, - ], - Mail: [ - { name: 'from', type: 'Person' }, - { name: 'to', type: 'Person' }, - { name: 'contents', type: 'string' }, - ], - }, - primaryType: 'Mail', - domain: { - name: 'Ether Mail', - version: '1', - chainId: 80001, - verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', - }, - message: { - from: { - name: 'Cow', - wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', - }, - to: { - name: 'Bob', - wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - }, - contents: 'Hello, Bob!', - }, - }; - - const signature = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_signTypedData', - params: [alice.pkp.ethAddress, JSON.stringify(msgParams)], - }, - }); - - // https://docs.ethers.io/v5/api/utils/signing-key/#utils-verifyTypedData - const recoveredAddr = ethers.utils.verifyTypedData( - msgParams.domain, - { Person: msgParams.types.Person, Mail: msgParams.types.Mail }, - msgParams.message, - signature - ); - - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr.toLowerCase() !== alice.pkp.ethAddress.toLowerCase()) { - throw new Error( - `❌ recoveredAddr ${recoveredAddr} should be ${alice.pkp.ethAddress}` - ); - } - } catch (e) { - throw new Error(`❌ ${e.toString()}`); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil.ts deleted file mode 100644 index f6102c40ae..0000000000 --- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { PKPEthersWallet, signTypedData } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil - */ -export const testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil = - async (devEnv: TinnyEnvironment) => { - const alice = await devEnv.createRandomPerson(); - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: litActionSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- eth_signTypedData parameters - try { - // Example from https://github.com/MetaMask/test-dapp/blob/main/src/index.js#L1033 - const msgParams = { - types: { - EIP712Domain: [ - { name: 'name', type: 'string' }, - { name: 'version', type: 'string' }, - { name: 'chainId', type: 'uint256' }, - { name: 'verifyingContract', type: 'address' }, - ], - Person: [ - { name: 'name', type: 'string' }, - { name: 'wallet', type: 'address' }, - ], - Mail: [ - { name: 'from', type: 'Person' }, - { name: 'to', type: 'Person' }, - { name: 'contents', type: 'string' }, - ], - }, - primaryType: 'Mail', - domain: { - name: 'Ether Mail', - version: '1', - chainId: 80001, - verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', - }, - message: { - from: { - name: 'Cow', - wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', - }, - to: { - name: 'Bob', - wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - }, - contents: 'Hello, Bob!', - }, - }; - const signature = await signTypedData(pkpEthersWallet, msgParams); - - // https://docs.ethers.io/v5/api/utils/signing-key/#utils-verifyTypedData - const recoveredAddr = ethers.utils.verifyTypedData( - msgParams.domain, - { Person: msgParams.types.Person, Mail: msgParams.types.Mail }, - msgParams.message, - signature - ); - - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr.toLowerCase() !== alice.pkp.ethAddress.toLowerCase()) { - throw new Error( - `❌ recoveredAddr ${recoveredAddr} should be ${alice.pkp.ethAddress}` - ); - } - } catch (e) { - throw new Error(`❌ ${e.toString()}`); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } - }; diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1.ts deleted file mode 100644 index 0c96a2689c..0000000000 --- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { - SignTypedDataVersion, - recoverTypedSignature, -} from '@metamask/eth-sig-util'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1 - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1 - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1 - */ -export const testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1 = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: litActionSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- eth_signTypedData_v1 parameters - try { - const msgParams = [ - { - type: 'string', - name: 'Message', - value: 'Hi, Alice!', - }, - { - type: 'uint32', - name: 'A number', - value: '1337', - }, - ]; - - const signature = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_signTypedData_v1', - params: [msgParams, alice.pkp.ethAddress], - }, - }); - - const signatureBytes = ethers.utils.arrayify(signature); - - const recoveredAddr = recoverTypedSignature({ - data: msgParams, - signature: signatureBytes as any, - version: SignTypedDataVersion.V1, - }); - - // ==================== Post-Validation ==================== - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr.toLowerCase() !== alice.pkp.ethAddress.toLowerCase()) { - throw new Error( - `❌ recoveredAddr ${recoveredAddr} should be ${alice.pkp.ethAddress}` - ); - } - - console.log('signature: ', signature); - console.log('recoveredAddr: ', recoveredAddr); - } catch (e) { - throw new Error(`❌ ${e.toString()}`); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3.ts deleted file mode 100644 index a12d0efc05..0000000000 --- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { - SignTypedDataVersion, - recoverTypedSignature, -} from '@metamask/eth-sig-util'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3 - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3 - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3 - */ -export const testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3 = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: litActionSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- eth_signTypedData_v3 parameters - try { - const msgParams = { - types: { - EIP712Domain: [ - { name: 'name', type: 'string' }, - { name: 'version', type: 'string' }, - { name: 'chainId', type: 'uint256' }, - { name: 'verifyingContract', type: 'address' }, - ], - Person: [ - { name: 'name', type: 'string' }, - { name: 'wallet', type: 'address' }, - ], - Mail: [ - { name: 'from', type: 'Person' }, - { name: 'to', type: 'Person' }, - { name: 'contents', type: 'string' }, - ], - }, - primaryType: 'Mail', - domain: { - name: 'Ether Mail', - version: '1', - chainId: 80001, - verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', - }, - message: { - from: { - name: 'Cow', - wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', - }, - to: { - name: 'Bob', - wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - }, - contents: 'Hello, Bob!', - }, - }; - - const signature = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_signTypedData_v3', - params: [alice.pkp.ethAddress, JSON.stringify(msgParams)], - }, - }); - - const recoveredAddr = recoverTypedSignature({ - data: { - // @ts-ignore - types: msgParams.types, - // @ts-ignore - domain: msgParams.domain, - // @ts-ignore - primaryType: msgParams.primaryType, - // @ts-ignore - message: msgParams.message, - }, - signature: signature, - version: SignTypedDataVersion.V3, - }); - - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr.toLowerCase() !== alice.pkp.ethAddress.toLowerCase()) { - throw new Error( - `❌ recoveredAddr ${recoveredAddr} should be ${alice.pkp.ethAddress}` - ); - } - } catch (e) { - throw new Error(`❌ ${e.toString()}`); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4.ts deleted file mode 100644 index 5159129a8e..0000000000 --- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { - SignTypedDataVersion, - recoverTypedSignature, -} from '@metamask/eth-sig-util'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4 - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4 - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4 - */ -export const testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4 = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: litActionSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- eth_signTypedData_v3 parameters - try { - const msgParams = { - domain: { - chainId: 80001, - name: 'Ether Mail', - verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', - version: '1', - }, - message: { - contents: 'Hello, Bob!', - from: { - name: 'Cow', - wallets: [ - '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', - '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF', - ], - }, - to: [ - { - name: 'Bob', - wallets: [ - '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - '0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57', - '0xB0B0b0b0b0b0B000000000000000000000000000', - ], - }, - ], - }, - primaryType: 'Mail', - types: { - EIP712Domain: [ - { name: 'name', type: 'string' }, - { name: 'version', type: 'string' }, - { name: 'chainId', type: 'uint256' }, - { name: 'verifyingContract', type: 'address' }, - ], - Mail: [ - { name: 'from', type: 'Person' }, - { name: 'to', type: 'Person[]' }, - { name: 'contents', type: 'string' }, - ], - Person: [ - { name: 'name', type: 'string' }, - { name: 'wallets', type: 'address[]' }, - ], - }, - }; - - const signature = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_signTypedData_v4', - params: [alice.pkp.ethAddress, JSON.stringify(msgParams)], - }, - }); - - const recoveredAddr = recoverTypedSignature({ - data: msgParams as any, - signature: signature, - version: SignTypedDataVersion.V4, - }); - - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr.toLowerCase() !== alice.pkp.ethAddress.toLowerCase()) { - throw new Error( - `❌ recoveredAddr ${recoveredAddr} should be ${alice.pkp.ethAddress}` - ); - } - } catch (e) { - throw new Error(`❌ ${e.toString()}`); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToPersonalSign.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToPersonalSign.ts deleted file mode 100644 index b303cf69f3..0000000000 --- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToPersonalSign.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToPersonalSign - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToPersonalSign - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToPersonalSign - */ -export const testPkpEthersWithLitActionSessionSigsToPersonalSign = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: litActionSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- personal_sign parameters - try { - // Message to sign - const message = 'Free the web'; - const hexMsg = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(message)); - - // personal_sign parameters - // DATA, N Bytes - message to sign. - // DATA, 20 Bytes - address - // Reference: https://metamask.github.io/api-playground/api-documentation/#personal_sign - const signature = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'personal_sign', - params: [hexMsg, alice.pkp.ethAddress], - }, - }); - - const recoveredAddr = ethers.utils.verifyMessage(message, signature); - - // ==================== Post-Validation ==================== - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr !== alice.pkp.ethAddress) { - throw new Error( - `❌ recoveredAddr should be ${alice.pkp.ethAddress} but got ${recoveredAddr}` - ); - } - - console.log('βœ… personal_sign recoveredAddr:', recoveredAddr); - } catch (e) { - throw new Error('❌ Error: ' + e.message); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToSendTx.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToSendTx.ts deleted file mode 100644 index 92dfc6f3c8..0000000000 --- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToSendTx.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToSendTx - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToSendTx - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToSendTx - */ -export const testPkpEthersWithLitActionSessionSigsToSendTx = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: litActionSessionSigs, - }); - - await devEnv.getFunds(alice.pkp.ethAddress); - - await pkpEthersWallet.init(); - - // -- eth_sendTransaction parameters - try { - // Transaction to sign and send - const from = alice.pkp.ethAddress; - const to = alice.pkp.ethAddress; - const gasLimit = ethers.BigNumber.from('21000'); - const value = ethers.BigNumber.from('0'); - const data = '0x'; - - // pkp-ethers signer will automatically add missing fields (nonce, chainId, gasPrice, gasLimit) - const tx = { - from: from, - to: to, - gasLimit, - value, - data, - }; - - const txRes = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_sendTransaction', - params: [tx], - }, - }); - - console.log('βœ… txRes:', txRes); - } catch (e) { - if (e.message.includes('insufficient FPE funds')) { - console.log( - `πŸ§ͺ PKPEthersWallet should be able to send tx (insufficient FPE funds ❗️)` - ); - } else { - throw new Error(`❌ Error: ${e.toString()}`); - } - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToSignMessage.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToSignMessage.ts deleted file mode 100644 index cb7a2f35ac..0000000000 --- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToSignMessage.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { PKPEthersWallet } from '@lit-protocol/pkp-ethers'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToSignMessage - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToSignMessage - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToSignMessage - */ -export const testPkpEthersWithLitActionSessionSigsToSignMessage = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: litActionSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- test signMessage - try { - const signature = await pkpEthersWallet.signMessage(alice.loveLetter); - console.log('βœ… signature:', signature); - } catch (e) { - throw new Error('❌ Error: ' + e.message); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSign.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSign.ts deleted file mode 100644 index 3a63f307ae..0000000000 --- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSign.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSign - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSign - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSign - */ -export const testPkpEthersWithPkpSessionSigsToEthSign = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - console.log('devEnv.network:', devEnv.network); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: pkpSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- test eth_sign - try { - // Message to sign - const message = 'Hello world'; - const hexMsg = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(message)); - - // DATA, 20 Bytes - address - // DATA, N Bytes - message to sign - // Reference: https://ethereum.github.io/execution-apis/api-documentation/#eth_sign - const signature = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_sign', - params: [alice.pkp.ethAddress, hexMsg], - }, - }); - const recoveredAddr = ethers.utils.verifyMessage(message, signature); - - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr !== alice.pkp.ethAddress) { - throw new Error( - `❌ test eth_sign recoveredAddr should be ${alice.pkp.ethAddress} but got ${recoveredAddr}` - ); - } - - console.log('βœ… recoveredAddr:', recoveredAddr); - } catch (e) { - throw new Error('❌ Error: ' + e.message); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTransaction.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTransaction.ts deleted file mode 100644 index 794989c722..0000000000 --- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTransaction.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTransaction - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTransaction - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTransaction - */ -export const testPkpEthersWithPkpSessionSigsToEthSignTransaction = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: pkpSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- eth_sendTransaction parameters - try { - // Transaction to sign and send - const from = alice.pkp.ethAddress; - const to = alice.pkp.ethAddress; - const gasLimit = ethers.BigNumber.from('21000'); - const value = ethers.BigNumber.from('0'); - const data = '0x'; - - // pkp-ethers signer will automatically add missing fields (nonce, chainId, gasPrice, gasLimit) - const tx = { - from: from, - to: to, - gasLimit, - value, - data, - }; - - // eth_sendTransaction parameters - // Transaction - Object - // Reference: https://ethereum.github.io/execution-apis/api-documentation/#eth_sendTransaction - // A serialized form of the whole transaction - const rawSignedTx = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_signTransaction', - params: [tx], - }, - }); - - const parsedTransaction = ethers.utils.parseTransaction(rawSignedTx); - - const signature = ethers.utils.joinSignature({ - r: parsedTransaction.r, - s: parsedTransaction.s, - v: parsedTransaction.v, - }); - - const rawTx = { - nonce: parsedTransaction.nonce, - gasPrice: parsedTransaction.gasPrice, - gasLimit: parsedTransaction.gasLimit, - to: parsedTransaction.to, - value: parsedTransaction.value, - data: parsedTransaction.data, - chainId: parsedTransaction.chainId, // Include chainId if the transaction is EIP-155 - }; - - const txHash = ethers.utils.keccak256( - ethers.utils.serializeTransaction(rawTx) - ); - - const { v, r, s } = parsedTransaction; - - const recoveredAddress = ethers.utils.recoverAddress(txHash, { r, s, v }); - - // ==================== Post-Validation ==================== - if (!parsedTransaction) { - throw new Error('❌ parsedTransaction should not be null'); - } - - if (signature.length !== 132) { - throw new Error( - `❌ signature should be 132 characters long, got ${signature.length}` - ); - } - - if (recoveredAddress.toLowerCase() !== alice.pkp.ethAddress.toLowerCase()) { - throw new Error( - `❌ recoveredAddres should be ${alice.pkp.ethAddress}, got ${recoveredAddress}` - ); - } - } catch (e) { - if (e.message.includes('insufficient FPE funds')) { - console.log( - `πŸ§ͺ PKPEthersWallet should be able to send tx (insufficient FPE funds ❗️)` - ); - } else { - throw new Error(`❌ Error: ${e.toString()}`); - } - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedData.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedData.ts deleted file mode 100644 index 31d20c98be..0000000000 --- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedData.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedData - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedData - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedData - */ -export const testPkpEthersWithPkpSessionSigsToEthSignTypedData = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: pkpSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- eth_signTypedData parameters - try { - // Example from https://github.com/MetaMask/test-dapp/blob/main/src/index.js#L1033 - const msgParams = { - types: { - EIP712Domain: [ - { name: 'name', type: 'string' }, - { name: 'version', type: 'string' }, - { name: 'chainId', type: 'uint256' }, - { name: 'verifyingContract', type: 'address' }, - ], - Person: [ - { name: 'name', type: 'string' }, - { name: 'wallet', type: 'address' }, - ], - Mail: [ - { name: 'from', type: 'Person' }, - { name: 'to', type: 'Person' }, - { name: 'contents', type: 'string' }, - ], - }, - primaryType: 'Mail', - domain: { - name: 'Ether Mail', - version: '1', - chainId: 80001, - verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', - }, - message: { - from: { - name: 'Cow', - wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', - }, - to: { - name: 'Bob', - wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - }, - contents: 'Hello, Bob!', - }, - }; - - const signature = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_signTypedData', - params: [alice.pkp.ethAddress, JSON.stringify(msgParams)], - }, - }); - - // https://docs.ethers.io/v5/api/utils/signing-key/#utils-verifyTypedData - const recoveredAddr = ethers.utils.verifyTypedData( - msgParams.domain, - { Person: msgParams.types.Person, Mail: msgParams.types.Mail }, - msgParams.message, - signature - ); - - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr.toLowerCase() !== alice.pkp.ethAddress.toLowerCase()) { - throw new Error( - `❌ recoveredAddr ${recoveredAddr} should be ${alice.pkp.ethAddress}` - ); - } - } catch (e) { - throw new Error(`❌ ${e.toString()}`); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil.ts deleted file mode 100644 index 1ec0ba2010..0000000000 --- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { PKPEthersWallet, signTypedData } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil - */ -export const testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: pkpSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- eth_signTypedData parameters - try { - // Example from https://github.com/MetaMask/test-dapp/blob/main/src/index.js#L1033 - const msgParams = { - types: { - EIP712Domain: [ - { name: 'name', type: 'string' }, - { name: 'version', type: 'string' }, - { name: 'chainId', type: 'uint256' }, - { name: 'verifyingContract', type: 'address' }, - ], - Person: [ - { name: 'name', type: 'string' }, - { name: 'wallet', type: 'address' }, - ], - Mail: [ - { name: 'from', type: 'Person' }, - { name: 'to', type: 'Person' }, - { name: 'contents', type: 'string' }, - ], - }, - primaryType: 'Mail', - domain: { - name: 'Ether Mail', - version: '1', - chainId: 80001, - verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', - }, - message: { - from: { - name: 'Cow', - wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', - }, - to: { - name: 'Bob', - wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - }, - contents: 'Hello, Bob!', - }, - }; - const signature = await signTypedData(pkpEthersWallet, msgParams); - - // https://docs.ethers.io/v5/api/utils/signing-key/#utils-verifyTypedData - const recoveredAddr = ethers.utils.verifyTypedData( - msgParams.domain, - { Person: msgParams.types.Person, Mail: msgParams.types.Mail }, - msgParams.message, - signature - ); - - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr.toLowerCase() !== alice.pkp.ethAddress.toLowerCase()) { - throw new Error( - `❌ recoveredAddr ${recoveredAddr} should be ${alice.pkp.ethAddress}` - ); - } - } catch (e) { - throw new Error(`❌ ${e.toString()}`); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1.ts deleted file mode 100644 index ccaeb7cb48..0000000000 --- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { - SignTypedDataVersion, - recoverTypedSignature, -} from '@metamask/eth-sig-util'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1 - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1 - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1 - */ -export const testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1 = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: pkpSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- eth_signTypedData_v1 parameters - try { - const msgParams = [ - { - type: 'string', - name: 'Message', - value: 'Hi, Alice!', - }, - { - type: 'uint32', - name: 'A number', - value: '1337', - }, - ]; - - const signature = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_signTypedData_v1', - params: [msgParams, alice.pkp.ethAddress], - }, - }); - - const signatureBytes = ethers.utils.arrayify(signature); - - const recoveredAddr = recoverTypedSignature({ - data: msgParams, - signature: signatureBytes as any, - version: SignTypedDataVersion.V1, - }); - - // ==================== Post-Validation ==================== - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr.toLowerCase() !== alice.pkp.ethAddress.toLowerCase()) { - throw new Error( - `❌ recoveredAddr ${recoveredAddr} should be ${alice.pkp.ethAddress}` - ); - } - - console.log('signature: ', signature); - console.log('recoveredAddr: ', recoveredAddr); - } catch (e) { - throw new Error(`❌ ${e.toString()}`); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3.ts deleted file mode 100644 index bfae5a64ab..0000000000 --- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { - SignTypedDataVersion, - recoverTypedSignature, -} from '@metamask/eth-sig-util'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3 - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3 - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3 - */ -export const testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3 = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: pkpSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- eth_signTypedData_v3 parameters - try { - const msgParams = { - types: { - EIP712Domain: [ - { name: 'name', type: 'string' }, - { name: 'version', type: 'string' }, - { name: 'chainId', type: 'uint256' }, - { name: 'verifyingContract', type: 'address' }, - ], - Person: [ - { name: 'name', type: 'string' }, - { name: 'wallet', type: 'address' }, - ], - Mail: [ - { name: 'from', type: 'Person' }, - { name: 'to', type: 'Person' }, - { name: 'contents', type: 'string' }, - ], - }, - primaryType: 'Mail', - domain: { - name: 'Ether Mail', - version: '1', - chainId: 80001, - verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', - }, - message: { - from: { - name: 'Cow', - wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', - }, - to: { - name: 'Bob', - wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - }, - contents: 'Hello, Bob!', - }, - }; - - const signature = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_signTypedData_v3', - params: [alice.pkp.ethAddress, JSON.stringify(msgParams)], - }, - }); - - const recoveredAddr = recoverTypedSignature({ - data: { - // @ts-ignore - types: msgParams.types, - // @ts-ignore - domain: msgParams.domain, - // @ts-ignore - primaryType: msgParams.primaryType, - // @ts-ignore - message: msgParams.message, - }, - signature: signature, - version: SignTypedDataVersion.V3, - }); - - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr.toLowerCase() !== alice.pkp.ethAddress.toLowerCase()) { - throw new Error( - `❌ recoveredAddr ${recoveredAddr} should be ${alice.pkp.ethAddress}` - ); - } - } catch (e) { - throw new Error(`❌ ${e.toString()}`); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4.ts deleted file mode 100644 index a4712ed587..0000000000 --- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { - SignTypedDataVersion, - recoverTypedSignature, -} from '@metamask/eth-sig-util'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4 - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4 - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4 - */ -export const testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4 = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: pkpSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- eth_signTypedData_v3 parameters - try { - const msgParams = { - domain: { - chainId: 80001, - name: 'Ether Mail', - verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', - version: '1', - }, - message: { - contents: 'Hello, Bob!', - from: { - name: 'Cow', - wallets: [ - '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', - '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF', - ], - }, - to: [ - { - name: 'Bob', - wallets: [ - '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - '0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57', - '0xB0B0b0b0b0b0B000000000000000000000000000', - ], - }, - ], - }, - primaryType: 'Mail', - types: { - EIP712Domain: [ - { name: 'name', type: 'string' }, - { name: 'version', type: 'string' }, - { name: 'chainId', type: 'uint256' }, - { name: 'verifyingContract', type: 'address' }, - ], - Mail: [ - { name: 'from', type: 'Person' }, - { name: 'to', type: 'Person[]' }, - { name: 'contents', type: 'string' }, - ], - Person: [ - { name: 'name', type: 'string' }, - { name: 'wallets', type: 'address[]' }, - ], - }, - }; - - const signature = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_signTypedData_v4', - params: [alice.pkp.ethAddress, JSON.stringify(msgParams)], - }, - }); - - const recoveredAddr = recoverTypedSignature({ - data: msgParams as any, - signature: signature, - version: SignTypedDataVersion.V4, - }); - - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr.toLowerCase() !== alice.pkp.ethAddress.toLowerCase()) { - throw new Error( - `❌ recoveredAddr ${recoveredAddr} should be ${alice.pkp.ethAddress}` - ); - } - } catch (e) { - throw new Error(`❌ ${e.toString()}`); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToPersonalSign.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToPersonalSign.ts deleted file mode 100644 index 49a14f561a..0000000000 --- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToPersonalSign.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToPersonalSign - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToPersonalSign - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToPersonalSign - */ -export const testPkpEthersWithPkpSessionSigsToPersonalSign = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: pkpSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- personal_sign parameters - try { - // Message to sign - const message = 'Free the web'; - const hexMsg = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(message)); - - // personal_sign parameters - // DATA, N Bytes - message to sign. - // DATA, 20 Bytes - address - // Reference: https://metamask.github.io/api-playground/api-documentation/#personal_sign - const signature = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'personal_sign', - params: [hexMsg, alice.pkp.ethAddress], - }, - }); - - const recoveredAddr = ethers.utils.verifyMessage(message, signature); - - // ==================== Post-Validation ==================== - if (signature.length !== 132) { - throw new Error('❌ signature should be 132 characters long'); - } - - if (recoveredAddr !== alice.pkp.ethAddress) { - throw new Error( - `❌ recoveredAddr should be ${alice.pkp.ethAddress} but got ${recoveredAddr}` - ); - } - - console.log('βœ… personal_sign recoveredAddr:', recoveredAddr); - } catch (e) { - throw new Error('❌ Error: ' + e.message); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToSendTx.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToSendTx.ts deleted file mode 100644 index 73a0105fe7..0000000000 --- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToSendTx.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; -import { ethers } from 'ethers'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToSendTx - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToSendTx - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToSendTx - */ -export const testPkpEthersWithPkpSessionSigsToSendTx = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: pkpSessionSigs, - }); - - await devEnv.getFunds(alice.pkp.ethAddress); - - await pkpEthersWallet.init(); - - // -- eth_sendTransaction parameters - try { - // Transaction to sign and send - const from = alice.pkp.ethAddress; - const to = alice.pkp.ethAddress; - const gasLimit = ethers.BigNumber.from('21000'); - const value = ethers.BigNumber.from('0'); - const data = '0x'; - - // pkp-ethers signer will automatically add missing fields (nonce, chainId, gasPrice, gasLimit) - const tx = { - from: from, - to: to, - gasLimit, - value, - data, - }; - - const txRes = await ethRequestHandler({ - signer: pkpEthersWallet, - payload: { - method: 'eth_sendTransaction', - params: [tx], - }, - }); - - console.log('βœ… txRes:', txRes); - } catch (e) { - if (e.message.includes('insufficient FPE funds')) { - console.log( - `πŸ§ͺ PKPEthersWallet should be able to send tx (insufficient FPE funds ❗️)` - ); - } else { - throw new Error(`❌ Error: ${e.toString()}`); - } - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToSignMessage.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToSignMessage.ts deleted file mode 100644 index 3ad2a2a3d4..0000000000 --- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToSignMessage.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { PKPEthersWallet } from '@lit-protocol/pkp-ethers'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToSignMessage - * βœ… NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToSignMessage - * βœ… NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToSignMessage - */ -export const testPkpEthersWithPkpSessionSigsToSignMessage = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - const pkpEthersWallet = new PKPEthersWallet({ - litNodeClient: devEnv.litNodeClient, - pkpPubKey: alice.pkp.publicKey, - controllerSessionSigs: pkpSessionSigs, - }); - - await pkpEthersWallet.init(); - - // -- test signMessage - try { - const signature = await pkpEthersWallet.signMessage(alice.loveLetter); - console.log('βœ… signature:', signature); - } catch (e) { - throw new Error('❌ Error: ' + e.message); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testRelayer.ts b/local-tests/tests/testRelayer.ts deleted file mode 100644 index 9cdabd0962..0000000000 --- a/local-tests/tests/testRelayer.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { log } from '@lit-protocol/misc'; -import { - ClaimRequest, - ClaimResult, - ClientClaimProcessor, -} from '@lit-protocol/types'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { - EthWalletProvider, - LitAuthClient, -} from '@lit-protocol/lit-auth-client'; -import { ProviderType } from '@lit-protocol/constants'; -import { withTimeout } from 'local-tests/setup/tinny-utils'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testRelayer - * βœ… NETWORK=manzano yarn test:local --filter=testRelayer - * βœ… NETWORK=localchain yarn test:local --filter=testRelayer - * βœ… NETWORK=datil-dev yarn test:local --filter=testRelayer - */ -export const testRelayer = async (devEnv: TinnyEnvironment) => { - const alice = await devEnv.createRandomPerson(); - - const litAuthClient = new LitAuthClient({ - litRelayConfig: { - relayApiKey: 'test-api-key', - }, - litNodeClient: devEnv.litNodeClient, - }); - - // -- test fetch pkps - const ethWalletProvider = litAuthClient.initProvider( - ProviderType.EthWallet - ); - - const pkps = await ethWalletProvider.fetchPKPsThroughRelayer( - alice.authMethod - ); - - if (pkps.length <= 0) { - throw new Error('No PKPs found'); - } else { - console.log('βœ… 1. [testRelayer] /fetch-pkps-by-auth-method works'); - } - - // -- test claims - const claimRequest: ClaimRequest = { - authMethod: alice.authMethod, - signer: alice.wallet, - }; - - const claimRes = await devEnv.litNodeClient.claimKeyId(claimRequest); - - // Expected output: - // { - // signatures: [ - // { - // r: "0xf73ec73f2dd7858d9b463598420169cf153f8cd409c82af606b3832ff82f8774", - // s: "0x0de6ab4437749fdf1e6239a8d13af516ac9a0744fc0725f9897a880151799fde", - // v: 28, - // }, { - // r: "0x65ec2ac206c4d18aaf12d6d1f17826543c1f329657214cea66c509fcdec8d633", - // s: "0x710e2efb2c61f9ae504721d7bea0b8d1d3c519167e48e4d67c77bf61dfeca735", - // v: 28, - // }, { - // r: "0xe51bd0670463cb5b5e9994870362b3eaa747cb5732e5c666ccf25495fe9aaa54", - // s: "0x1b49aed6d46833c9b9ee0fa13a4009c533309dafdfd51dd30165f2556b6cdcf1", - // v: 27, - // }, { - // r: "0x4278d3f7f2eb38801da5940858be54527e42ee11b25d7b239cb491139c00765d", - // s: "0x13dac60eaa90a548a4c99f1e09ac24e07cb1ef7447e55d3c82cf2ea6d69ec190", - // v: 27, - // }, { - // r: "0xb18158eccd4b099d0cfae4c2f987843cbaf039ce50164410fe4f529e6dc2bb6a", - // s: "0x284d9d5326deeb3d10e2c1d81ed1a7d6fca584c46ad9606a4dad9f12d81874ab", - // v: 27, - // }, { - // r: "0x28ad76574d39d646948642d05f599a982a1dd0776e2e36138315f5fb2c03666e", - // s: "0x2a125a028df39b9230f5d866383fcda0107cc7ee2f42fa1f323d41b34f67273a", - // v: 27, - // }, { - // r: "0xb7ab5120aeffeaee6e8d6ab1456d6823a15fae7e5a70b88d2556dc85450486cf", - // s: "0x6e1e9ac479066d95d62a6cd86f0cb3db92e07367acf43873fb5a7b8ad558a09d", - // v: 28, - // } - // ], - // claimedKeyId: "4825e3caf11a273792ad0405524820410cd15d6323ae4621537f0a89c1322a74", - // pubkey: "049528b98ac4829b5eaf8f8e6addaa9c12e94e83c4d17baf8f86554c111f2ac6d774f483fca03ad06b268059f7c8bcf64c7fb93689e153dc2fed79dada7b289195", - // mintTx: "0x0000000000000000000000000000000000000000000000000000000000000000", - // } - - // assertions - if (!claimRes.claimedKeyId) { - throw new Error(`Expected "claimedKeyId" in claimRes`); - } - if (!claimRes.pubkey) { - throw new Error(`Expected "pubkey" in claimRes`); - } - if (!claimRes.mintTx) { - throw new Error(`Expected "mintTx" in claimRes`); - } - - claimRes.signatures.forEach((sig: any) => { - if (!sig.r) { - throw new Error(`Expected "r" in sig`); - } - if (!sig.s) { - throw new Error(`Expected "s" in sig`); - } - if (!sig.v) { - throw new Error(`Expected "v" in sig`); - } - }); - - log('βœ… 2. [testRelayer] Claim works'); -}; diff --git a/local-tests/tests/testSolAuthSigToEncryptDecryptString.ts b/local-tests/tests/testSolAuthSigToEncryptDecryptString.ts deleted file mode 100644 index 9e110e177c..0000000000 --- a/local-tests/tests/testSolAuthSigToEncryptDecryptString.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs'; -import { ILitNodeClient, LitAbility, SolanaAuthSig } from '@lit-protocol/types'; -import { AccessControlConditions } from 'local-tests/setup/accs/accs'; -import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { log } from '@lit-protocol/misc'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testSolAuthSigToEncryptDecryptString - * βœ… NETWORK=manzano yarn test:local --filter=testSolAuthSigToEncryptDecryptString - * βœ… NETWORK=localchain yarn test:local --filter=testSolAuthSigToEncryptDecryptString - */ -export const testSolAuthSigToEncryptDecryptString = async ( - devEnv: TinnyEnvironment -) => { - const accs = AccessControlConditions.getSolBasicAccessControlConditions({ - userAddress: devEnv.bareSolAuthSig.address, - }); - - const encryptRes = await LitJsSdk.encryptString( - { - solRpcConditions: accs, - dataToEncrypt: 'Hello world', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - console.log('encryptRes:', encryptRes); - - // -- Expected output:Β΄ - // { - // ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D", - // dataToEncryptHash: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c", - // } - - // -- assertions - if (!encryptRes.ciphertext) { - throw new Error(`Expected "ciphertext" in encryptRes`); - } - - if (!encryptRes.dataToEncryptHash) { - throw new Error(`Expected "dataToEncryptHash" to in encryptRes`); - } - - // -- Decrypt the encrypted string - const decryptRes = await LitJsSdk.decryptToString( - { - solRpcConditions: accs, - ciphertext: encryptRes.ciphertext, - dataToEncryptHash: encryptRes.dataToEncryptHash, - authSig: devEnv.bareSolAuthSig, - chain: 'solana', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - if (decryptRes !== 'Hello world') { - throw new Error( - `Expected decryptRes to be 'Hello world' but got ${decryptRes}` - ); - } - - console.log('βœ… decryptRes:', decryptRes); -}; diff --git a/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs.ts b/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs.ts deleted file mode 100644 index c6cf228505..0000000000 --- a/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getEoaSessionSigsWithCapacityDelegations } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * ## Scenario: - * Testing unrestricted access to execute js code using a capacity delegation authSig without specific delegatee restrictions - * - Given: A capacity delegation authSig is created by the dApp owner - * - When: The authSig does not specifically restrict delegatees - * - And: Any user attempts to execute js code using the capacity from the capacity credits NFT - * - Then: The user should be able to sign with his/her PKP using the capacity without restrictions due to the absence of delegatee limits - * - * - * ## Test Commands: - * - ❌ Not supported in Cayenne, but session sigs would still work - * - βœ… NETWORK=manzano yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs - * - βœ… NETWORK=localchain yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs - */ -export const testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs = - async (devEnv: TinnyEnvironment) => { - const alice = await devEnv.createRandomPerson(); - const bob = await devEnv.createRandomPerson(); - - const appOwnersCapacityDelegationAuthSig = ( - await devEnv.litNodeClient.createCapacityDelegationAuthSig({ - dAppOwnerWallet: alice.wallet, - }) - ).capacityDelegationAuthSig; - - // 3. Bob gets the capacity delegation authSig from somewhere and uses it to get session sigs - const bobsSessionSigs = await getEoaSessionSigsWithCapacityDelegations( - devEnv, - bob.wallet, - appOwnersCapacityDelegationAuthSig - ); - - // -- printing out the recaps from the session sigs - const bobsSingleSessionSig = - bobsSessionSigs[devEnv.litNodeClient.config.bootstrapUrls[0]]; - - console.log('bobsSingleSessionSig:', bobsSingleSessionSig); - - const regex = /urn:recap:[\w+\/=]+/g; - - const recaps = bobsSingleSessionSig.signedMessage.match(regex) || []; - - recaps.forEach((r) => { - const encodedRecap = r.split(':')[2]; - const decodedRecap = Buffer.from(encodedRecap, 'base64').toString(); - console.log(decodedRecap); - }); - - // 4. Bob can now execute JS code using the capacity credits NFT - // 5. Bob can now execute JS code using the capacity credits NFT - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: bobsSessionSigs, - code: `(async () => { - const sigShare = await LitActions.signEcdsa({ - toSign: dataToSign, - publicKey, - sigName: "sig", - }); - })();`, - jsParams: { - dataToSign: alice.loveLetter, - publicKey: bob.pkp.publicKey, - }, - }); - - devEnv.releasePrivateKeyFromUser(alice); - devEnv.releasePrivateKeyFromUser(bob); - - // Expected output: - // { - // claims: {}, - // signatures: { - // sig: { - // r: "0f4b8b20369a8a021aae7c2083076715820e32d2b18826ea7ccea525a9adadc2", - // s: "43aa338fa2c90e13c88d9b432d7ee6c8e3df006b8ef94ad5b4ab32d64b507f17", - // recid: 1, - // signature: "0x0f4b8b20369a8a021aae7c2083076715820e32d2b18826ea7ccea525a9adadc243aa338fa2c90e13c88d9b432d7ee6c8e3df006b8ef94ad5b4ab32d64b507f171c", - // publicKey: "0406A76D2A6E3E729A537640C8C41592BBC2675799CCBBF310CD410691C028C529C5A8DE8016933CEC0B06EC7AA0FFAFBA2791158A11D382C558376DF392F436AD", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // }, - // }, - // decryptions: [], - // response: undefined, - // logs: "", - // } - - // -- assertions - if (!res.signatures.sig.r) { - throw new Error(`Expected "r" in res.signatures.sig`); - } - if (!res.signatures.sig.s) { - throw new Error(`Expected "s" in res.signatures.sig`); - } - - if (!res.signatures.sig.dataSigned) { - throw new Error(`Expected "dataSigned" in res.signatures.sig`); - } - - if (!res.signatures.sig.publicKey) { - throw new Error(`Expected "publicKey" in res.signatures.sig`); - } - - // -- signatures.sig.signature must start with 0x - if (!res.signatures.sig.signature.startsWith('0x')) { - throw new Error(`Expected "signature" to start with 0x`); - } - - // -- signatures.sig.recid must be parseable as a number - if (isNaN(res.signatures.sig.recid)) { - throw new Error(`Expected "recid" to be parseable as a number`); - } - - console.log( - 'βœ… testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs' - ); - }; diff --git a/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToPkpSign.ts b/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToPkpSign.ts deleted file mode 100644 index 342c4419f3..0000000000 --- a/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToPkpSign.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getEoaSessionSigsWithCapacityDelegations } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * ## Scenario: - * Testing unrestricted access to pkp sign using a capacity delegation authSig without specific delegatee restrictions - * - Given: A capacity delegation authSig is created by the dApp owner - * - When: The authSig does not specifically restrict delegatees - * - And: Any user attempts to pkp sign using the capacity from the capacity credits NFT - * - Then: The user should be able to sign with his/her PKP using the capacity without restrictions due to the absence of delegatee limits - * - * - * ## Test Commands: - * - ❌ Not supported in Cayenne, but session sigs would still work - * - βœ… NETWORK=manzano yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToPkpSign - * - βœ… NETWORK=localchain yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToPkpSign - */ -export const testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToPkpSign = - async (devEnv: TinnyEnvironment) => { - const alice = await devEnv.createRandomPerson(); - const bob = await devEnv.createRandomPerson(); - - const appOwnersCapacityDelegationAuthSig = ( - await devEnv.litNodeClient.createCapacityDelegationAuthSig({ - dAppOwnerWallet: alice.wallet, - }) - ).capacityDelegationAuthSig; - - // 3. Bob gets the capacity delegation authSig from somewhere and uses it to get session sigs - const bobsSessionSigs = await getEoaSessionSigsWithCapacityDelegations( - devEnv, - bob.wallet, - appOwnersCapacityDelegationAuthSig - ); - - // -- printing out the recaps from the session sigs - const bobsSingleSessionSig = - bobsSessionSigs[devEnv.litNodeClient.config.bootstrapUrls[0]]; - - console.log('bobsSingleSessionSig:', bobsSingleSessionSig); - - const regex = /urn:recap:[\w+\/=]+/g; - - const recaps = bobsSingleSessionSig.signedMessage.match(regex) || []; - - recaps.forEach((r) => { - const encodedRecap = r.split(':')[2]; - const decodedRecap = Buffer.from(encodedRecap, 'base64').toString(); - console.log(decodedRecap); - }); - - // 4. Bob can now execute JS code using the capacity credits NFT - const res = await devEnv.litNodeClient.pkpSign({ - sessionSigs: bobsSessionSigs, - toSign: alice.loveLetter, - pubKey: bob.pkp.publicKey, - }); - - devEnv.releasePrivateKeyFromUser(alice); - devEnv.releasePrivateKeyFromUser(bob); - - // -- Expected output: - // { - // r: "25e04b2abdf220b1374b19228bc292bab71a3224a635726a46d4cbe3a62bb636", - // s: "1e5d96ffa6ec7cca961ec7bfa90e524a08b1c4fc9a833b69d8727eff1453064c", - // recid: 0, - // signature: "0x25e04b2abdf220b1374b19228bc292bab71a3224a635726a46d4cbe3a62bb6361e5d96ffa6ec7cca961ec7bfa90e524a08b1c4fc9a833b69d8727eff1453064c1b", - // publicKey: "041FF0DC7B69D2B3C3E452AF9E0D30C7FDA6729A1B394059BDC8C4530D7F584FFCAEEEC19B1F22EFB054A22E5EF13AA0B5804994469570929066F5474D490B8A1F", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // } - - // -- assertions - if (!res.r) { - throw new Error(`Expected "r" in res`); - } - if (!res.s) { - throw new Error(`Expected "s" in res`); - } - - if (!res.dataSigned) { - throw new Error(`Expected "dataSigned" in res`); - } - - if (!res.publicKey) { - throw new Error(`Expected "publicKey" in res`); - } - - // -- signature must start with 0x - if (!res.signature.startsWith('0x')) { - throw new Error(`Expected "signature" to start with 0x`); - } - - // -- recid must be parseable as a number - if (isNaN(res.recid)) { - throw new Error(`Expected "recid" to be parseable as a number`); - } - - console.log('βœ… res:', res); - }; diff --git a/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToExecuteJs.ts b/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToExecuteJs.ts deleted file mode 100644 index 0ffb15dacc..0000000000 --- a/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToExecuteJs.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getEoaSessionSigsWithCapacityDelegations } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * ## Scenario: - * Testing unrestricted access to execute JS code using a capacity delegation authSig without specific delegatee restrictions - * - Given: A capacity delegation authSig is created by the dApp owner - * - When: The authSig does not specifically restrict delegatees - * - And: Any user attempts to execute JS code using the capacity from the capacity credits NFT - * - Then: The user should be able to execute the JS code using the capacity without restrictions due to the absence of delegatee limits - * - * - * ## Test Commands: - * - ❌ Not supported in Cayenne, but session sigs would still work - * - βœ… NETWORK=manzano yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToExecuteJs - * - βœ… NETWORK=localchain yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToExecuteJs - */ - -export const testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToExecuteJs = - async (devEnv: TinnyEnvironment) => { - const alice = await devEnv.createRandomPerson(); - const bob = await devEnv.createRandomPerson(); - - // No delegatee addresses provided. It means that the capability will not restrict access based on delegatee list, but it may still enforce other restrictions such as usage limits and specific NFT IDs. - const appOwnersCapacityDelegationAuthSig = - await alice.createCapacityDelegationAuthSig(); - - // 4. Bob gets the capacity delegation authSig from somewhere and uses it to get session sigs - const bobsSessionSigs = await getEoaSessionSigsWithCapacityDelegations( - devEnv, - bob.wallet, - appOwnersCapacityDelegationAuthSig - ); - - // -- printing out the recaps from the session sigs - const bobsSingleSessionSig = - bobsSessionSigs[devEnv.litNodeClient.config.bootstrapUrls[0]]; - - console.log('bobsSingleSessionSig:', bobsSingleSessionSig); - - const regex = /urn:recap:[\w+\/=]+/g; - - const recaps = bobsSingleSessionSig.signedMessage.match(regex) || []; - - recaps.forEach((r) => { - const encodedRecap = r.split(':')[2]; - const decodedRecap = Buffer.from(encodedRecap, 'base64').toString(); - console.log(decodedRecap); - }); - - // 5. Bob can now execute JS code using the capacity credits NFT - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: bobsSessionSigs, - code: `(async () => { - const sigShare = await LitActions.signEcdsa({ - toSign: dataToSign, - publicKey, - sigName: "sig", - }); - })();`, - jsParams: { - dataToSign: alice.loveLetter, - publicKey: bob.pkp.publicKey, - }, - }); - - devEnv.releasePrivateKeyFromUser(alice); - devEnv.releasePrivateKeyFromUser(bob); - - // Expected output: - // { - // claims: {}, - // signatures: { - // sig: { - // r: "0f4b8b20369a8a021aae7c2083076715820e32d2b18826ea7ccea525a9adadc2", - // s: "43aa338fa2c90e13c88d9b432d7ee6c8e3df006b8ef94ad5b4ab32d64b507f17", - // recid: 1, - // signature: "0x0f4b8b20369a8a021aae7c2083076715820e32d2b18826ea7ccea525a9adadc243aa338fa2c90e13c88d9b432d7ee6c8e3df006b8ef94ad5b4ab32d64b507f171c", - // publicKey: "0406A76D2A6E3E729A537640C8C41592BBC2675799CCBBF310CD410691C028C529C5A8DE8016933CEC0B06EC7AA0FFAFBA2791158A11D382C558376DF392F436AD", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // }, - // }, - // decryptions: [], - // response: undefined, - // logs: "", - // } - - // -- assertions - if (!res.signatures.sig.r) { - throw new Error(`Expected "r" in res.signatures.sig`); - } - if (!res.signatures.sig.s) { - throw new Error(`Expected "s" in res.signatures.sig`); - } - - if (!res.signatures.sig.dataSigned) { - throw new Error(`Expected "dataSigned" in res.signatures.sig`); - } - - if (!res.signatures.sig.publicKey) { - throw new Error(`Expected "publicKey" in res.signatures.sig`); - } - - // -- signatures.sig.signature must start with 0x - if (!res.signatures.sig.signature.startsWith('0x')) { - throw new Error(`Expected "signature" to start with 0x`); - } - - // -- signatures.sig.recid must be parseable as a number - if (isNaN(res.signatures.sig.recid)) { - throw new Error(`Expected "recid" to be parseable as a number`); - } - - console.log( - 'βœ… testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs' - ); - }; diff --git a/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToPkpSign.ts b/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToPkpSign.ts deleted file mode 100644 index 6cdd9d2779..0000000000 --- a/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToPkpSign.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getEoaSessionSigsWithCapacityDelegations } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * ## Scenario: - * Testing unrestricted access to pkp sign code using a capacity delegation authSig without specific delegatee restrictions - * - Given: A capacity delegation authSig is created by the dApp owner - * - When: The authSig does not specifically restrict delegatees - * - And: Any user attempts to pkp sign code using the capacity from the capacity credits NFT - * - Then: The user should be able to execute the JS code using the capacity without restrictions due to the absence of delegatee limits - * - * - * ## Test Commands: - * - ❌ Not supported in Cayenne, but session sigs would still work - * - βœ… NETWORK=manzano yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToPkpSign - * - βœ… NETWORK=localchain yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToPkpSign - */ - -export const testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToPkpSign = - async (devEnv: TinnyEnvironment) => { - const alice = await devEnv.createRandomPerson(); - const bob = await devEnv.createRandomPerson(); - - const appOwnersCapacityDelegationAuthSig = - await alice.createCapacityDelegationAuthSig(); - - // 4. Bob gets the capacity delegation authSig from somewhere and uses it to get session sigs - const bobsSessionSigs = await getEoaSessionSigsWithCapacityDelegations( - devEnv, - bob.wallet, - appOwnersCapacityDelegationAuthSig - ); - - // -- printing out the recaps from the session sigs - const bobsSingleSessionSig = - bobsSessionSigs[devEnv.litNodeClient.config.bootstrapUrls[0]]; - - console.log('bobsSingleSessionSig:', bobsSingleSessionSig); - - const regex = /urn:recap:[\w+\/=]+/g; - - const recaps = bobsSingleSessionSig.signedMessage.match(regex) || []; - - recaps.forEach((r) => { - const encodedRecap = r.split(':')[2]; - const decodedRecap = Buffer.from(encodedRecap, 'base64').toString(); - console.log(decodedRecap); - }); - - // 5. Bob can now pkp sign using the capacity credits NFT - const runWithSessionSigs = await devEnv.litNodeClient.pkpSign({ - toSign: alice.loveLetter, - pubKey: bob.pkp.publicKey, - sessionSigs: bobsSessionSigs, - }); - - devEnv.releasePrivateKeyFromUser(alice); - devEnv.releasePrivateKeyFromUser(bob); - - // -- Expected output: - // { - // r: "36bd0039b4e4d1dae488a63437318790df86b8023ac4ffa842c8983245b7f629", - // s: "29135af930c40ee0901a9ea3ca5621d06a6b932aee2f2256cf2a99a65cb36d05", - // recid: 1, - // signature: "0x36bd0039b4e4d1dae488a63437318790df86b8023ac4ffa842c8983245b7f62929135af930c40ee0901a9ea3ca5621d06a6b932aee2f2256cf2a99a65cb36d051c", - // publicKey: "04837486BD4DCF221D463D976E6A392E12BC2DFEFB124E189AB0A8EA406DFB1C73F4DCD268CC2B8F854C202256BD08E22D688121061EA9CFB1317142DBD2EAB4C4", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // } - - // -- assertions - // r, s, dataSigned, and public key should be present - if (!runWithSessionSigs.r) { - throw new Error(`Expected "r" in runWithSessionSigs`); - } - if (!runWithSessionSigs.s) { - throw new Error(`Expected "s" in runWithSessionSigs`); - } - if (!runWithSessionSigs.dataSigned) { - throw new Error(`Expected "dataSigned" in runWithSessionSigs`); - } - if (!runWithSessionSigs.publicKey) { - throw new Error(`Expected "publicKey" in runWithSessionSigs`); - } - - // signature must start with 0x - if (!runWithSessionSigs.signature.startsWith('0x')) { - throw new Error(`Expected "signature" to start with 0x`); - } - - // recid must be parseable as a number - if (isNaN(runWithSessionSigs.recid)) { - throw new Error(`Expected "recid" to be parseable as a number`); - } - }; diff --git a/local-tests/tests/testUseCustomAuthSessionSigsToPkpSignExecuteJs.ts b/local-tests/tests/testUseCustomAuthSessionSigsToPkpSignExecuteJs.ts deleted file mode 100644 index aed18b9456..0000000000 --- a/local-tests/tests/testUseCustomAuthSessionSigsToPkpSignExecuteJs.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { - LitAbility, - LitActionResource, - LitPKPResource, -} from '@lit-protocol/auth-helpers'; -import { - AuthMethodScope, - CENTRALISATION_BY_NETWORK, -} from '@lit-protocol/constants'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { stringToIpfsHash } from 'local-tests/setup/tinny-utils'; - -/** - * Test Commands: - * NETWORK=cayenne yarn test:local --filter=testUseCustomAuthSessionSigsToPkpSignExecuteJs - * NOT AVAILABLE IN HABANERO - * NETWORK=localchain yarn test:local --filter=testUseCustomAuthSessionSigsToPkpSignExecuteJs - */ -export const testUseCustomAuthSessionSigsToPkpSignExecuteJs = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - /** - * This is a custom auth method. It can be anything you want. Even the shape of the object can be anything, - * because you will be handling the logic in the Lit action code yourself. - */ - const customAuthMethod = { - authMethodType: 89989, - authMethodId: 'app-id-xxx:user-id-yyy', - accessToken: 'xxx', - }; - - /** - * Alice assigns the custom auth method to her PKP. - */ - const addPermittedAuthMethodReceipt = - await alice.contractsClient.addPermittedAuthMethod({ - pkpTokenId: alice.pkp.tokenId, - authMethodType: customAuthMethod.authMethodType, - authMethodId: customAuthMethod.authMethodId, - authMethodScopes: [AuthMethodScope.SignAnything], - }); - - console.log( - 'βœ… addPermittedAuthMethodReceipt:', - addPermittedAuthMethodReceipt - ); - - /** - * Please note that the code below is first converted to a CID and stored in the smart contract. - * Therefore, the Lit action code executed in the `getPkpSessionSigs` function must match the CID stored in the smart contract. - * - * You can use https://explorer.litprotocol.com/create-action to create a Lit action and get the CID. - */ - const litActionCodeString = `(async () => { - const a = 1; - const b = 2; - - if (a + b === 3 && customAuthMethod.authMethodType === 89989) { - LitActions.setResponse({response:"true"}); - } else { - LitActions.setResponse({response:"false"}); - } - - console.log("Lit.Auth:", Lit.Auth); - })()`; - - const IPFSID = await stringToIpfsHash(litActionCodeString); - - console.log('βœ… IPFSID:', IPFSID.toString()); - - // Grant an action permission to use a PKP - const addPermittedActionReceipt = - await alice.contractsClient.addPermittedAction({ - ipfsId: IPFSID, - pkpTokenId: alice.pkp.tokenId, - authMethodScopes: [AuthMethodScope.SignAnything], - }); - - console.log('βœ… addPermittedActionReceipt:', addPermittedActionReceipt); - - const centralisation = - CENTRALISATION_BY_NETWORK[devEnv.litNodeClient.config.litNetwork]; - - const litActionSessionSigs = - await devEnv.litNodeClient.getLitActionSessionSigs({ - pkpPublicKey: alice.pkp.publicKey, - resourceAbilityRequests: [ - { - resource: new LitPKPResource('*'), - ability: LitAbility.PKPSigning, - }, - { - resource: new LitActionResource('*'), - ability: LitAbility.LitActionExecution, - }, - ], - // litActionIpfsId: IPFSID, - litActionCode: Buffer.from(litActionCodeString).toString('base64'), - jsParams: { - publicKey: `0x${alice.pkp.publicKey}`, - customAuthMethod: customAuthMethod, - sigName: 'custom-auth-sig', - }, - - ...(centralisation === 'decentralised' && { - capabilityAuthSigs: [devEnv.superCapacityDelegationAuthSig], - }), - }); - - // -- pkp sign test - try { - const res = await devEnv.litNodeClient.pkpSign({ - toSign: alice.loveLetter, - pubKey: alice.pkp.publicKey, - sessionSigs: litActionSessionSigs, - }); - - console.log('βœ… pkpSign res:', res); - } catch (e) { - throw new Error(e); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } - // -- execute js - try { - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: litActionSessionSigs, - code: `(async () => { - const sigShare = await LitActions.signEcdsa({ - toSign: dataToSign, - publicKey, - sigName: "sig", - }); - })();`, - jsParams: { - dataToSign: alice.loveLetter, - publicKey: alice.pkp.publicKey, - }, - }); - console.log('βœ… executeJs res:', res); - } catch (e) { - throw new Error(e); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptFile.ts b/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptFile.ts deleted file mode 100644 index 302b2a0a38..0000000000 --- a/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptFile.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs'; -import { ILitNodeClient, LitAbility } from '@lit-protocol/types'; -import { AccessControlConditions } from 'local-tests/setup/accs/accs'; -import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { log } from '@lit-protocol/misc'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptFile - * βœ… NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptFile - * βœ… NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptFile - */ -export const testUseEoaSessionSigsToEncryptDecryptFile = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const message = 'Hello world'; - const blob = new Blob([message], { type: 'text/plain' }); - const blobArray = new Uint8Array(await blob.arrayBuffer()); - - // set access control conditions for encrypting and decrypting - const accs = AccessControlConditions.getEmvBasicAccessControlConditions({ - userAddress: alice.wallet.address, - }); - - const encryptRes = await LitJsSdk.encryptString( - { - accessControlConditions: accs, - dataToEncrypt: 'Hello world', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - log('encryptRes:', encryptRes); - - // await 5 seconds for the encryption to be mined - - // -- Expected output: - // { - // ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D", - // dataToEncryptHash: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c", - // } - - // -- assertions - if (!encryptRes.ciphertext) { - throw new Error(`Expected "ciphertext" in encryptRes`); - } - - if (!encryptRes.dataToEncryptHash) { - throw new Error(`Expected "dataToEncryptHash" to in encryptRes`); - } - - const accsResourceString = - await LitAccessControlConditionResource.generateResourceString( - accs, - encryptRes.dataToEncryptHash - ); - - const eoaSessionSigs2 = await getEoaSessionSigs(devEnv, alice, [ - { - resource: new LitAccessControlConditionResource(accsResourceString), - ability: LitAbility.AccessControlConditionDecryption, - }, - ]); - - // -- Decrypt the encrypted string - const decriptedFile = await LitJsSdk.decryptToFile( - { - accessControlConditions: accs, - ciphertext: encryptRes.ciphertext, - dataToEncryptHash: encryptRes.dataToEncryptHash, - sessionSigs: eoaSessionSigs2, - chain: 'ethereum', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - devEnv.releasePrivateKeyFromUser(alice); - - if (blobArray.length !== decriptedFile.length) { - throw new Error( - `decrypted file should match the original file but received ${decriptedFile}` - ); - } - for (let i = 0; i < blobArray.length; i++) { - if (blobArray[i] !== decriptedFile[i]) { - throw new Error(`decrypted file should match the original file`); - } - } - - console.log('decriptedFile:', decriptedFile); -}; diff --git a/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptString.ts b/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptString.ts deleted file mode 100644 index 6a951cfc88..0000000000 --- a/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptString.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs'; -import { ILitNodeClient, LitAbility } from '@lit-protocol/types'; -import { AccessControlConditions } from 'local-tests/setup/accs/accs'; -import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { log } from '@lit-protocol/misc'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptString - * βœ… NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptString - * βœ… NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptString - */ -export const testUseEoaSessionSigsToEncryptDecryptString = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - // set access control conditions for encrypting and decrypting - const accs = AccessControlConditions.getEmvBasicAccessControlConditions({ - userAddress: alice.wallet.address, - }); - - const encryptRes = await LitJsSdk.encryptString( - { - accessControlConditions: accs, - dataToEncrypt: 'Hello world', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - log('encryptRes:', encryptRes); - - // await 5 seconds for the encryption to be mined - - // -- Expected output: - // { - // ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D", - // dataToEncryptHash: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c", - // } - - // -- assertions - if (!encryptRes.ciphertext) { - throw new Error(`Expected "ciphertext" in encryptRes`); - } - - if (!encryptRes.dataToEncryptHash) { - throw new Error(`Expected "dataToEncryptHash" to in encryptRes`); - } - - const accsResourceString = - await LitAccessControlConditionResource.generateResourceString( - accs, - encryptRes.dataToEncryptHash - ); - - const eoaSessionSigs2 = await getEoaSessionSigs(devEnv, alice, [ - { - resource: new LitAccessControlConditionResource(accsResourceString), - ability: LitAbility.AccessControlConditionDecryption, - }, - ]); - - // -- Decrypt the encrypted string - const decryptRes = await LitJsSdk.decryptToString( - { - accessControlConditions: accs, - ciphertext: encryptRes.ciphertext, - dataToEncryptHash: encryptRes.dataToEncryptHash, - sessionSigs: eoaSessionSigs2, - chain: 'ethereum', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - devEnv.releasePrivateKeyFromUser(alice); - - if (decryptRes !== 'Hello world') { - throw new Error( - `Expected decryptRes to be 'Hello world' but got ${decryptRes}` - ); - } -}; diff --git a/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptZip.ts b/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptZip.ts deleted file mode 100644 index f64eab4a5c..0000000000 --- a/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptZip.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs'; -import { ILitNodeClient, LitAbility } from '@lit-protocol/types'; -import { AccessControlConditions } from 'local-tests/setup/accs/accs'; -import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { log } from '@lit-protocol/misc'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptZip - * βœ… NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptZip - * βœ… NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptZip - */ -export const testUseEoaSessionSigsToEncryptDecryptZip = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - const message = 'Hello world'; - - // set access control conditions for encrypting and decrypting - const accs = AccessControlConditions.getEmvBasicAccessControlConditions({ - userAddress: alice.wallet.address, - }); - - const encryptRes = await LitJsSdk.zipAndEncryptString( - { - accessControlConditions: accs, - dataToEncrypt: message, - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - log('encryptRes:', encryptRes); - - // -- Expected output: - // { - // ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D", - // dataToEncryptHash: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c", - // } - - // -- assertions - if (!encryptRes.ciphertext) { - throw new Error(`Expected "ciphertext" in encryptRes`); - } - - if (!encryptRes.dataToEncryptHash) { - throw new Error(`Expected "dataToEncryptHash" to in encryptRes`); - } - - const accsResourceString = - await LitAccessControlConditionResource.generateResourceString( - accs, - encryptRes.dataToEncryptHash - ); - - const eoaSessionSigs2 = await getEoaSessionSigs(devEnv, alice, [ - { - resource: new LitAccessControlConditionResource(accsResourceString), - ability: LitAbility.AccessControlConditionDecryption, - }, - ]); - - // -- Decrypt the encrypted string - const decryptedZip = await LitJsSdk.decryptToZip( - { - accessControlConditions: accs, - ciphertext: encryptRes.ciphertext, - dataToEncryptHash: encryptRes.dataToEncryptHash, - sessionSigs: eoaSessionSigs2, - chain: 'ethereum', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - devEnv.releasePrivateKeyFromUser(alice); - - const decryptedMessage = await decryptedZip['string.txt'].async('string'); - - if (message !== decryptedMessage) { - throw new Error( - `decryptedMessage should be ${message} but received ${decryptedMessage}` - ); - } - - console.log('decryptedMessage:', decryptedMessage); -}; diff --git a/local-tests/tests/testUseEoaSessionSigsToExecuteJsClaimKeys.ts b/local-tests/tests/testUseEoaSessionSigsToExecuteJsClaimKeys.ts deleted file mode 100644 index 038b232e32..0000000000 --- a/local-tests/tests/testUseEoaSessionSigsToExecuteJsClaimKeys.ts +++ /dev/null @@ -1,182 +0,0 @@ -// import { LitContracts } from '@lit-protocol/contracts-sdk'; -// import { log } from '@lit-protocol/misc'; -// import { -// ClaimRequest, -// ClaimResult, -// ClientClaimProcessor, -// } from '@lit-protocol/types'; -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { log } from '@lit-protocol/misc'; - -/** - * ## Scenario: - * Testing the capability to claim keys using EOA (Externally Owned Account) session sigs. This test ensures that keys can be claimed correctly. - * - * - Given: EOA sessionSigs are properly generated for the environment. - * - When: These sessionSigs are used to execute JS code within Lit Action. - * - And: The Lit Action JS code attempts to claim a key using the provided sessionSigs. - * - Then: The claim operation should successfully return signatures, derived key IDs, and validate the existence and structure of claimed results. - * - * - Note: The key claiming process involves multiple nodes within the Lit network verifying the sessionSigs and collaboratively signing the claim, which results in the generation of a new key pair if successful. - * - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToExecuteJsClaimKeys - * βœ… NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToExecuteJsClaimKeys - * βœ… NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToExecuteJsClaimKeys - */ -export const testUseEoaSessionSigsToExecuteJsClaimKeys = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: eoaSessionSigs, - code: `(async () => { - Lit.Actions.claimKey({keyId: "foo"}); - })();`, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - console.log('res:', res); - - // Expected output: - // { - // claims: { - // foo: { - // signatures: [ - // { - // r: "0x31e5dcf6eed3619aa6ff68d0c8f7a4bcf082acc2f12c3d5bcae9b8bbaf883c07", - // s: "0x405f671d1c659022105775b18afe805e01eaa1d0799c6b92887baef77dc023f5", - // v: 27, - // }, { - // r: "0xf2e9fe653d9155bd93feb7fe122c07a81769076fe44567c3ea93bb828f87146e", - // s: "0x01adf2b2780511f70b0b037360ff4b0c2b8d04657a689af780180bed9e6ea3c5", - // v: 27, - // }, { - // r: "0xfe1dcacd79f53b42b24dae75521f01315f34bbc492233e26083995c82218a3ff", - // s: "0x0b708b11704d986b50bce9f648bb5d40e8b9ad87f3a337a213999c7751dc1c0c", - // v: 27, - // } - // ], - // derivedKeyId: "22c14f271322473459c456056ffc6e1c0dc1efcb2d15e5be538ad081b224b3d0", - // }, - // }, - // signatures: {}, - // decryptions: [], - // response: undefined, - // logs: "", - // } - - // assertions - if (!res.claims.foo) { - throw new Error(`Expected "foo" in res.claims`); - } - if (!res.claims.foo.derivedKeyId) { - throw new Error(`Expected "derivedKeyId" in res.claims.foo`); - } - - if (!res.claims.foo.signatures) { - throw new Error(`Expected "signatures" in res.claims.foo`); - } - - res.claims.foo.signatures.forEach((sig: any) => { - if (!sig.r) { - throw new Error(`Expected "r" in sig`); - } - if (!sig.s) { - throw new Error(`Expected "s" in sig`); - } - if (!sig.v) { - throw new Error(`Expected "v" in sig`); - } - }); - - // const claimRequest: ClaimRequest = { - // authMethod: devEnv.bobsWalletAuthMethod, - // signer: devEnv.hotWallet, - // mintCallback: async (claimRes: ClaimResult) => { - // console.log('claimRes:', claimRes); - - // const litContracts = await devEnv.getContractsClient(claimRes.signer); - // const pkpInfo = await litContracts.pkpNftContractUtils.write.claimAndMint( - // `0x${claimRes.derivedKeyId}`, - // claimRes.signatures - // ); - - // return pkpInfo.tokenId; - // }, - // }; - - // const claimRes = await devEnv.litNodeClient.claimKeyId(claimRequest); - - // console.log('claimRes:', claimRes); - - // Expected output: - // { - // signatures: [ - // { - // r: "0xf73ec73f2dd7858d9b463598420169cf153f8cd409c82af606b3832ff82f8774", - // s: "0x0de6ab4437749fdf1e6239a8d13af516ac9a0744fc0725f9897a880151799fde", - // v: 28, - // }, { - // r: "0x65ec2ac206c4d18aaf12d6d1f17826543c1f329657214cea66c509fcdec8d633", - // s: "0x710e2efb2c61f9ae504721d7bea0b8d1d3c519167e48e4d67c77bf61dfeca735", - // v: 28, - // }, { - // r: "0xe51bd0670463cb5b5e9994870362b3eaa747cb5732e5c666ccf25495fe9aaa54", - // s: "0x1b49aed6d46833c9b9ee0fa13a4009c533309dafdfd51dd30165f2556b6cdcf1", - // v: 27, - // }, { - // r: "0x4278d3f7f2eb38801da5940858be54527e42ee11b25d7b239cb491139c00765d", - // s: "0x13dac60eaa90a548a4c99f1e09ac24e07cb1ef7447e55d3c82cf2ea6d69ec190", - // v: 27, - // }, { - // r: "0xb18158eccd4b099d0cfae4c2f987843cbaf039ce50164410fe4f529e6dc2bb6a", - // s: "0x284d9d5326deeb3d10e2c1d81ed1a7d6fca584c46ad9606a4dad9f12d81874ab", - // v: 27, - // }, { - // r: "0x28ad76574d39d646948642d05f599a982a1dd0776e2e36138315f5fb2c03666e", - // s: "0x2a125a028df39b9230f5d866383fcda0107cc7ee2f42fa1f323d41b34f67273a", - // v: 27, - // }, { - // r: "0xb7ab5120aeffeaee6e8d6ab1456d6823a15fae7e5a70b88d2556dc85450486cf", - // s: "0x6e1e9ac479066d95d62a6cd86f0cb3db92e07367acf43873fb5a7b8ad558a09d", - // v: 28, - // } - // ], - // claimedKeyId: "4825e3caf11a273792ad0405524820410cd15d6323ae4621537f0a89c1322a74", - // pubkey: "049528b98ac4829b5eaf8f8e6addaa9c12e94e83c4d17baf8f86554c111f2ac6d774f483fca03ad06b268059f7c8bcf64c7fb93689e153dc2fed79dada7b289195", - // mintTx: "0x0000000000000000000000000000000000000000000000000000000000000000", - // } - - // assertions - // if (!claimRes.claimedKeyId) { - // throw new Error(`Expected "claimedKeyId" in claimRes`); - // } - // if (!claimRes.pubkey) { - // throw new Error(`Expected "pubkey" in claimRes`); - // } - // if (!claimRes.mintTx) { - // throw new Error(`Expected "mintTx" in claimRes`); - // } - - // claimRes.signatures.forEach((sig: any) => { - // if (!sig.r) { - // throw new Error(`Expected "r" in sig`); - // } - // if (!sig.s) { - // throw new Error(`Expected "s" in sig`); - // } - // if (!sig.v) { - // throw new Error(`Expected "v" in sig`); - // } - // }); - - log('βœ… testUseEoaSessionSigsToExecuteJsClaimKeys'); -}; diff --git a/local-tests/tests/testUseEoaSessionSigsToExecuteJsClaimMultipleKeys.ts b/local-tests/tests/testUseEoaSessionSigsToExecuteJsClaimMultipleKeys.ts deleted file mode 100644 index c18f740365..0000000000 --- a/local-tests/tests/testUseEoaSessionSigsToExecuteJsClaimMultipleKeys.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * ## Scenario: - * Testing the capability to claim keys using EOA (Externally Owned Account) session sigs. This test ensures that multiple keys can be claimed correctly. - * - * - Given: EOA sessionSigs are properly generated for the environment. - * - When: These sessionSigs are used to execute JS code within Lit Action. - * - And: The Lit Action JS code attempts to claim a key using the provided sessionSigs. - * - Then: The claim operation should successfully return signatures, derived key IDs, and validate the existence and structure of claimed results. - * * - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToExecuteJsClaimMultipleKeys - * βœ… NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToExecuteJsClaimMultipleKeys - * βœ… NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToExecuteJsClaimMultipleKeys - */ -export const testUseEoaSessionSigsToExecuteJsClaimMultipleKeys = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: eoaSessionSigs, - code: `(async () => { - Lit.Actions.claimKey({keyId: "foo"}); - Lit.Actions.claimKey({keyId: "bar"}); - })();`, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - // Expected output: - // { - // claims: { - // bar: { - // signatures: [ - // { - // r: "0x7ee7b329462acb08d1dd1d3fba17f8ac76263454e2582bc0d5f36c74f4aaac68", - // s: "0x1b20cd8ac8ab1efdcf500d7ff100229deee42ce44b6420619c609a694af33aad", - // v: 28, - // }, { - // r: "0x2bd6db983d5f5dd239b4fe27b087acf0547e49a69e6c62b8e1435d3890a5d4c5", - // s: "0x15a8a80b2a5bf16e9c155bfe9d5da1109847334b8a0a74a9ce277cdfc6b05fdd", - // v: 28, - // }, { - // r: "0x9294c656bdb6764fca46e431dc4b15c653e6347a41eb657d23145d93a1fa19d0", - // s: "0x7afe0be470e9393dda32c356a9a262f7794a59f8e75e551bdb7634beb3a0a114", - // v: 28, - // } - // ], - // derivedKeyId: "0961c21c8a46c4992003a7b7af9449c15f772a269633ae3242f6ed146708a819", - // }, - // foo: { - // signatures: [ - // { - // r: "0xc39c073d69c8878bf06c813af9d090b41e15319abc9677e20f07085c96451e98", - // s: "0x6ef6a3d4b365119f4a9613a89fd57af01c4a350a20222935581be306b4c8aba4", - // v: 27, - // }, { - // r: "0xa2473911de4b252349cadde340de121ce3195929cd1ebb4c717f3d9d65c67988", - // s: "0x597a45d27a3100fa0bb144644f6bdec62c8a827f35427814cea64f8d3d9a9fa8", - // v: 27, - // }, { - // r: "0x97c393fb1f733b946bfaafdbb13c46192f4cf5ad2b2a9fcf9ff0355a7a2dc5fa", - // s: "0x152737c1b0aba904182bb5ac70e3a99ba4301b631df55bd21b91d705eb5ef4d2", - // v: 27, - // } - // ], - // derivedKeyId: "7698c828a5e4ae6dd6f98ae72fcb5a96bc83f53fa6a09c614e28ceab8198d5ca", - // }, - // }, - // signatures: {}, - // decryptions: [], - // response: undefined, - // logs: "", - // } - - // assertions - if (!res.claims.foo) { - throw new Error(`Expected "foo" in res.claims`); - } - if (!res.claims.foo.derivedKeyId) { - throw new Error(`Expected "derivedKeyId" in res.claims.foo`); - } - - if (!res.claims.foo.signatures) { - throw new Error(`Expected "signatures" in res.claims.foo`); - } - - res.claims.foo.signatures.forEach((sig: any) => { - if (!sig.r) { - throw new Error(`Expected "r" in sig`); - } - if (!sig.s) { - throw new Error(`Expected "s" in sig`); - } - if (!sig.v) { - throw new Error(`Expected "v" in sig`); - } - }); -}; diff --git a/local-tests/tests/testUseEoaSessionSigsToExecuteJsConsoleLog.ts b/local-tests/tests/testUseEoaSessionSigsToExecuteJsConsoleLog.ts deleted file mode 100644 index f6b90ae481..0000000000 --- a/local-tests/tests/testUseEoaSessionSigsToExecuteJsConsoleLog.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToExecuteJsConsoleLog - * βœ… NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToExecuteJsConsoleLog - * βœ… NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToExecuteJsConsoleLog - */ -export const testUseEoaSessionSigsToExecuteJsConsoleLog = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: eoaSessionSigs, - code: `(async () => { - console.log('hello world') - })();`, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - console.log('res:', res); - - // Expected output: - // { - // success: true, - // signedData: {}, - // decryptedData: {}, - // claimData: {}, - // response: "", - // logs: "hello world\n", - // } - - // -- assertions - if (res.response) { - throw new Error(`Expected "response" to be falsy`); - } - - if (!res.logs) { - throw new Error(`Expected "logs" in res`); - } - - if (!res.logs.includes('hello world')) { - throw new Error(`Expected "logs" to include 'hello world'`); - } - - if (!res.success) { - throw new Error(`Expected "success" in res`); - } -}; diff --git a/local-tests/tests/testUseEoaSessionSigsToExecuteJsJsonResponse.ts b/local-tests/tests/testUseEoaSessionSigsToExecuteJsJsonResponse.ts deleted file mode 100644 index 4e219a264f..0000000000 --- a/local-tests/tests/testUseEoaSessionSigsToExecuteJsJsonResponse.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToExecuteJsJsonResponse - * βœ… NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToExecuteJsJsonResponse - * βœ… NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToExecuteJsJsonResponse - */ -export const testUseEoaSessionSigsToExecuteJsJsonResponse = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: eoaSessionSigs, - code: `(async () => { - console.log('hello world') - - LitActions.setResponse({ - response: JSON.stringify({hello: 'world'}) - }); - - })();`, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - // Expected output: - // { - // success: true, - // signedData: {}, - // decryptedData: {}, - // claimData: {}, - // response: "{\"hello\":\"world\"}", - // logs: "hello world\n", - // } - - // -- assertions - if (!res.response) { - throw new Error(`Expected "response" in res`); - } - - if (!res.response.startsWith('{')) { - throw new Error(`Expected "response" to start with {`); - } - - if (!res.response.endsWith('}')) { - throw new Error(`Expected "response" to end with }`); - } - - if (!res.logs) { - throw new Error(`Expected "logs" in res`); - } - - if (!res.logs.includes('hello world')) { - throw new Error(`Expected "logs" to include 'hello world'`); - } - - if (!res.success) { - throw new Error(`Expected "success" in res`); - } - - if (res.success !== true) { - throw new Error(`Expected "success" to be true`); - } -}; diff --git a/local-tests/tests/testUseEoaSessionSigsToExecuteJsSigning.ts b/local-tests/tests/testUseEoaSessionSigsToExecuteJsSigning.ts deleted file mode 100644 index c381ded7a8..0000000000 --- a/local-tests/tests/testUseEoaSessionSigsToExecuteJsSigning.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { log } from '@lit-protocol/misc'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigning - * βœ… NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigning - * βœ… NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigning - */ -export const testUseEoaSessionSigsToExecuteJsSigning = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: eoaSessionSigs, - code: `(async () => { - const sigShare = await LitActions.signEcdsa({ - toSign: dataToSign, - publicKey, - sigName: "sig", - }); - })();`, - jsParams: { - dataToSign: alice.loveLetter, - publicKey: alice.pkp.publicKey, - }, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - // -- Expected output: - // { - // claims: {}, - // signatures: { - // sig: { - // r: "63311a761842b41686875862a3fb09975c838afff6ae11c5c3940da458dffe79", - // s: "1c25f352b4a8bf15510cecbee4e798270cdf68c45a26cf93dc32d6e03dfc720a", - // recid: 0, - // signature: "0x63311a761842b41686875862a3fb09975c838afff6ae11c5c3940da458dffe791c25f352b4a8bf15510cecbee4e798270cdf68c45a26cf93dc32d6e03dfc720a1b", - // publicKey: "0423F38A7663289FC58841B5F8E068FA43106BC7DDEE38D1F2542C03ABEC45B6733BE2D85A703C7B238865E45DF2175DD2A1736C56F2BAD0A965837F64BB21FB03", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // }, - // } - - // -- assertions - if (!res.signatures.sig.r) { - throw new Error(`Expected "r" in res.signatures.sig`); - } - if (!res.signatures.sig.s) { - throw new Error(`Expected "s" in res.signatures.sig`); - } - - if (!res.signatures.sig.dataSigned) { - throw new Error(`Expected "dataSigned" in res.signatures.sig`); - } - - if (!res.signatures.sig.publicKey) { - throw new Error(`Expected "publicKey" in res.signatures.sig`); - } - - log('βœ… testUseEoaSessionSigsToExecuteJsSigning'); -}; diff --git a/local-tests/tests/testUseEoaSessionSigsToExecuteJsSigningInParallel.ts b/local-tests/tests/testUseEoaSessionSigsToExecuteJsSigningInParallel.ts deleted file mode 100644 index 0b20018d88..0000000000 --- a/local-tests/tests/testUseEoaSessionSigsToExecuteJsSigningInParallel.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { log } from '@lit-protocol/misc'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigningInParallel - * βœ… NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigningInParallel - * βœ… NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigningInParallel - */ -export const testUseEoaSessionSigsToExecuteJsSigningInParallel = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - const fn = async (index: number) => { - log(`Index: ${index}`); - - return await devEnv.litNodeClient.executeJs({ - sessionSigs: eoaSessionSigs, - code: `(async () => { - const sigShare = await LitActions.signEcdsa({ - toSign: dataToSign, - publicKey, - sigName: "sig", - }); - })();`, - jsParams: { - dataToSign: alice.loveLetter, - publicKey: alice.pkp.publicKey, - }, - }); - }; - - const res = await Promise.all([fn(1), fn(2), fn(3)]); - devEnv.releasePrivateKeyFromUser(alice); - log('res:', res); - - // -- Expected output: - // [ - // { - // claims: {}, - // signatures: { - // sig: { - // r: "d5bc8b53b9f69604c2dfb2d1d3e6c8b7e01a225346055ee798f5f67fe542a05a", - // s: "0153071ac4c7f9b08330361575b109dec07d1c335edeecd85db47398795a00d0", - // recid: 0, - // signature: "0xd5bc8b53b9f69604c2dfb2d1d3e6c8b7e01a225346055ee798f5f67fe542a05a0153071ac4c7f9b08330361575b109dec07d1c335edeecd85db47398795a00d01b", - // publicKey: "0489782A60B39C758DD8405965DC83DE5F1DB9572861EBAB6064090223C3B7F60DD71C6E673D81550E127BE18497BEA8C349E3B91C8170AD572AD0572009797EA5", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // }, - // }, - // decryptions: [], - // response: undefined, - // logs: "", - // }, { - // claims: {}, - // signatures: { - // sig: { - // r: "d2ad9086e810a5fd9b49dc4c2a0e7e2cf417dd79f8e75cc5f7b7b21d1b7ae9bc", - // s: "5e28b3321e73bab4177f6a69fec924f9daec294cf89a9a4d9c1a8fad18810bbd", - // recid: 1, - // signature: "0xd2ad9086e810a5fd9b49dc4c2a0e7e2cf417dd79f8e75cc5f7b7b21d1b7ae9bc5e28b3321e73bab4177f6a69fec924f9daec294cf89a9a4d9c1a8fad18810bbd1c", - // publicKey: "0489782A60B39C758DD8405965DC83DE5F1DB9572861EBAB6064090223C3B7F60DD71C6E673D81550E127BE18497BEA8C349E3B91C8170AD572AD0572009797EA5", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // }, - // }, - // decryptions: [], - // response: undefined, - // logs: "", - // }, { - // claims: {}, - // signatures: { - // sig: { - // r: "50f87167ba2c8a92e78c95f34e2683a23c372fcc6d104ef9f4d9050d5e1621f3", - // s: "443f5895668e8df6b5d6097a3e9f363923dc2cb83a4734b79359c8213f220fa9", - // recid: 0, - // signature: "0x50f87167ba2c8a92e78c95f34e2683a23c372fcc6d104ef9f4d9050d5e1621f3443f5895668e8df6b5d6097a3e9f363923dc2cb83a4734b79359c8213f220fa91b", - // publicKey: "0489782A60B39C758DD8405965DC83DE5F1DB9572861EBAB6064090223C3B7F60DD71C6E673D81550E127BE18497BEA8C349E3B91C8170AD572AD0572009797EA5", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // }, - // }, - // decryptions: [], - // response: undefined, - // logs: "", - // } - // ] - - // -- assertions - res.forEach((r) => { - if (!r.signatures.sig.r) { - throw new Error(`Expected "r" in res.signatures.sig`); - } - if (!r.signatures.sig.s) { - throw new Error(`Expected "s" in res.signatures.sig`); - } - - if (!r.signatures.sig.dataSigned) { - throw new Error(`Expected "dataSigned" in res.signatures.sig`); - } - - if (!r.signatures.sig.publicKey) { - throw new Error(`Expected "publicKey" in res.signatures.sig`); - } - - // -- signatures.sig.signature must start with 0x - if (!r.signatures.sig.signature.startsWith('0x')) { - throw new Error(`Expected "signature" to start with 0x`); - } - - // -- signatures.sig.recid must be parseable as a number - if (isNaN(r.signatures.sig.recid)) { - throw new Error(`Expected "recid" to be parseable as a number`); - } - }); - - log('βœ… testUseEoaSessionSigsToExecuteJsSigningInParallel'); -}; diff --git a/local-tests/tests/testUseEoaSessionSigsToPkpSign.ts b/local-tests/tests/testUseEoaSessionSigsToPkpSign.ts deleted file mode 100644 index d50d5b5513..0000000000 --- a/local-tests/tests/testUseEoaSessionSigsToPkpSign.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { log } from '@lit-protocol/misc'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToPkpSign - * βœ… NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToPkpSign - * βœ… NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToPkpSign - */ -export const testUseEoaSessionSigsToPkpSign = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - const runWithSessionSigs = await devEnv.litNodeClient.pkpSign({ - toSign: alice.loveLetter, - pubKey: alice.pkp.publicKey, - sessionSigs: eoaSessionSigs, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - // Expected output: - // { - // r: "25fc0d2fecde8ed801e9fee5ad26f2cf61d82e6f45c8ad1ad1e4798d3b747fd9", - // s: "549fe745b4a09536e6e7108d814cf7e44b93f1d73c41931b8d57d1b101833214", - // recid: 1, - // signature: "0x25fc0d2fecde8ed801e9fee5ad26f2cf61d82e6f45c8ad1ad1e4798d3b747fd9549fe745b4a09536e6e7108d814cf7e44b93f1d73c41931b8d57d1b1018332141c", - // publicKey: "04A3CD53CCF63597D3FFCD1DF1E8236F642C7DF8196F532C8104625635DC55A1EE59ABD2959077432FF635DF2CED36CC153050902B71291C4D4867E7DAAF964049", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // } - - // -- assertions - // r, s, dataSigned, and public key should be present - if (!runWithSessionSigs.r) { - throw new Error(`Expected "r" in runWithSessionSigs`); - } - if (!runWithSessionSigs.s) { - throw new Error(`Expected "s" in runWithSessionSigs`); - } - if (!runWithSessionSigs.dataSigned) { - throw new Error(`Expected "dataSigned" in runWithSessionSigs`); - } - if (!runWithSessionSigs.publicKey) { - throw new Error(`Expected "publicKey" in runWithSessionSigs`); - } - - // signature must start with 0x - if (!runWithSessionSigs.signature.startsWith('0x')) { - throw new Error(`Expected "signature" to start with 0x`); - } - - // recid must be parseable as a number - if (isNaN(runWithSessionSigs.recid)) { - throw new Error(`Expected "recid" to be parseable as a number`); - } - - log('βœ… testUseEoaSessionSigsToPkpSign'); -}; diff --git a/local-tests/tests/testUseInvalidLitActionCodeToGenerateSessionSigs.ts b/local-tests/tests/testUseInvalidLitActionCodeToGenerateSessionSigs.ts deleted file mode 100644 index 69d6cd36ad..0000000000 --- a/local-tests/tests/testUseInvalidLitActionCodeToGenerateSessionSigs.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getInvalidLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseInvalidLitActionCodeToGenerateSessionSigs - * ❌ NOT AVAILABLE IN MANZANO - * βœ… NETWORK=localchain yarn test:local --filter=testUseInvalidLitActionCodeToGenerateSessionSigs - * βœ… NETWORK=datil-dev yarn test:local --filter=testUseInvalidLitActionCodeToGenerateSessionSigs - */ -export const testUseInvalidLitActionCodeToGenerateSessionSigs = async ( - devEnv: TinnyEnvironment -) => { - devEnv.setUnavailable(LIT_TESTNET.MANZANO); - - const alice = await devEnv.createRandomPerson(); - - try { - await getInvalidLitActionSessionSigs(devEnv, alice); - } catch (e: any) { - console.log('❌ This error is expected', e); - if ( - e.message === - 'There was an error getting the signing shares from the nodes' - ) { - console.log('βœ… testUseInvalidLitActionCodeToGenerateSessionSigs passed'); - } else { - throw e; - } - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testUseInvalidLitActionIpfsCodeToGenerateSessionSigs.ts b/local-tests/tests/testUseInvalidLitActionIpfsCodeToGenerateSessionSigs.ts deleted file mode 100644 index 871009d8e5..0000000000 --- a/local-tests/tests/testUseInvalidLitActionIpfsCodeToGenerateSessionSigs.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getInvalidLitActionIpfsSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseInvalidLitActionIpfsCodeToGenerateSessionSigs - * ❌ NOT AVAILABLE IN MANZANO - * βœ… NETWORK=localchain yarn test:local --filter=testUseInvalidLitActionIpfsCodeToGenerateSessionSigs - */ -export const testUseInvalidLitActionIpfsCodeToGenerateSessionSigs = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - try { - await getInvalidLitActionIpfsSessionSigs(devEnv, alice); - } catch (e: any) { - console.log('❌ THIS IS EXPECTED: ', e); - - if (e.message === 'An error related to validation has occured.') { - console.log( - 'βœ… testUseInvalidLitActionIpfsCodeToGenerateSessionSigs is expected to have an error' - ); - } else { - throw e; - } - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptFile.ts b/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptFile.ts deleted file mode 100644 index 4b4026eb28..0000000000 --- a/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptFile.ts +++ /dev/null @@ -1,95 +0,0 @@ -import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs'; -import { ILitNodeClient, LitAbility } from '@lit-protocol/types'; -import { AccessControlConditions } from 'local-tests/setup/accs/accs'; -import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { log } from '@lit-protocol/misc'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptFile - * βœ… NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptFile - * βœ… NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptFile - */ -export const testUsePkpSessionSigsToEncryptDecryptFile = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - const message = 'Hello world'; - const blob = new Blob([message], { type: 'text/plain' }); - const blobArray = new Uint8Array(await blob.arrayBuffer()); - - // set access control conditions for encrypting and decrypting - const accs = AccessControlConditions.getEmvBasicAccessControlConditions({ - userAddress: alice.authMethodOwnedPkp.ethAddress, - }); - - const encryptRes = await LitJsSdk.encryptString( - { - accessControlConditions: accs, - dataToEncrypt: 'Hello world', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - log('encryptRes:', encryptRes); - - // await 5 seconds for the encryption to be mined - - // -- Expected output: - // { - // ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D", - // dataToEncryptHash: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c", - // } - - // -- assertions - if (!encryptRes.ciphertext) { - throw new Error(`Expected "ciphertext" in encryptRes`); - } - - if (!encryptRes.dataToEncryptHash) { - throw new Error(`Expected "dataToEncryptHash" to in encryptRes`); - } - - const accsResourceString = - await LitAccessControlConditionResource.generateResourceString( - accs, - encryptRes.dataToEncryptHash - ); - - const pkpSessionSigs2 = await getPkpSessionSigs(devEnv, alice, [ - { - resource: new LitAccessControlConditionResource(accsResourceString), - ability: LitAbility.AccessControlConditionDecryption, - }, - ]); - - // -- Decrypt the encrypted string - const decriptedFile = await LitJsSdk.decryptToFile( - { - accessControlConditions: accs, - ciphertext: encryptRes.ciphertext, - dataToEncryptHash: encryptRes.dataToEncryptHash, - sessionSigs: pkpSessionSigs2, - chain: 'ethereum', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - devEnv.releasePrivateKeyFromUser(alice); - - if (blobArray.length !== decriptedFile.length) { - throw new Error( - `decrypted file should match the original file but received ${decriptedFile}` - ); - } - for (let i = 0; i < blobArray.length; i++) { - if (blobArray[i] !== decriptedFile[i]) { - throw new Error(`decrypted file should match the original file`); - } - } - - console.log('decriptedFile:', decriptedFile); -}; diff --git a/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptString.ts b/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptString.ts deleted file mode 100644 index f5918b1e73..0000000000 --- a/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptString.ts +++ /dev/null @@ -1,81 +0,0 @@ -import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs'; -import { ILitNodeClient, LitAbility } from '@lit-protocol/types'; -import { AccessControlConditions } from 'local-tests/setup/accs/accs'; -import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { log } from '@lit-protocol/misc'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptString - * βœ… NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptString - * βœ… NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptString - */ -export const testUsePkpSessionSigsToEncryptDecryptString = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - // set access control conditions for encrypting and decrypting - const accs = AccessControlConditions.getEmvBasicAccessControlConditions({ - userAddress: alice.authMethodOwnedPkp.ethAddress, - }); - - const encryptRes = await LitJsSdk.encryptString( - { - accessControlConditions: accs, - dataToEncrypt: 'Hello world', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - log('encryptRes:', encryptRes); - - // -- Expected output: - // { - // ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D", - // dataToEncryptHash: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c", - // } - - // -- assertions - if (!encryptRes.ciphertext) { - throw new Error(`Expected "ciphertext" in encryptRes`); - } - - if (!encryptRes.dataToEncryptHash) { - throw new Error(`Expected "dataToEncryptHash" to in encryptRes`); - } - - const accsResourceString = - await LitAccessControlConditionResource.generateResourceString( - accs, - encryptRes.dataToEncryptHash - ); - - const pkpSessionSigs2 = await getPkpSessionSigs(devEnv, alice, [ - { - resource: new LitAccessControlConditionResource(accsResourceString), - ability: LitAbility.AccessControlConditionDecryption, - }, - ]); - - // -- Decrypt the encrypted string - const decryptRes = await LitJsSdk.decryptToString( - { - accessControlConditions: accs, - ciphertext: encryptRes.ciphertext, - dataToEncryptHash: encryptRes.dataToEncryptHash, - sessionSigs: pkpSessionSigs2, - chain: 'ethereum', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - devEnv.releasePrivateKeyFromUser(alice); - - if (decryptRes !== 'Hello world') { - throw new Error( - `Expected decryptRes to be 'Hello world' but got ${decryptRes}` - ); - } -}; diff --git a/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptZip.ts b/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptZip.ts deleted file mode 100644 index abdc59ef4e..0000000000 --- a/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptZip.ts +++ /dev/null @@ -1,90 +0,0 @@ -import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs'; -import { ILitNodeClient, LitAbility } from '@lit-protocol/types'; -import { AccessControlConditions } from 'local-tests/setup/accs/accs'; -import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { log } from '@lit-protocol/misc'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptZip - * βœ… NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptZip - * βœ… NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptZip - */ -export const testUsePkpSessionSigsToEncryptDecryptZip = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - const message = 'Hello world'; - - // set access control conditions for encrypting and decrypting - const accs = AccessControlConditions.getEmvBasicAccessControlConditions({ - userAddress: alice.authMethodOwnedPkp.ethAddress, - }); - - const encryptRes = await LitJsSdk.zipAndEncryptString( - { - accessControlConditions: accs, - dataToEncrypt: message, - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - log('encryptRes:', encryptRes); - - // await 5 seconds for the encryption to be mined - - // -- Expected output: - // { - // ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D", - // dataToEncryptHash: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c", - // } - - // -- assertions - if (!encryptRes.ciphertext) { - throw new Error(`Expected "ciphertext" in encryptRes`); - } - - if (!encryptRes.dataToEncryptHash) { - throw new Error(`Expected "dataToEncryptHash" to in encryptRes`); - } - - const accsResourceString = - await LitAccessControlConditionResource.generateResourceString( - accs, - encryptRes.dataToEncryptHash - ); - - const pkpSessionSigs2 = await getPkpSessionSigs(devEnv, alice, [ - { - resource: new LitAccessControlConditionResource(accsResourceString), - ability: LitAbility.AccessControlConditionDecryption, - }, - ]); - - // -- Decrypt the encrypted string - const decryptedZip = await LitJsSdk.decryptToZip( - { - accessControlConditions: accs, - ciphertext: encryptRes.ciphertext, - dataToEncryptHash: encryptRes.dataToEncryptHash, - sessionSigs: pkpSessionSigs2, - chain: 'ethereum', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - devEnv.releasePrivateKeyFromUser(alice); - - const decryptedMessage = await decryptedZip['string.txt'].async('string'); - - if (message !== decryptedMessage) { - throw new Error( - `decryptedMessage should be ${message} but received ${decryptedMessage}` - ); - } - - console.log('decryptedMessage:', decryptedMessage); -}; diff --git a/local-tests/tests/testUsePkpSessionSigsToExecuteJsClaimKeys.ts b/local-tests/tests/testUsePkpSessionSigsToExecuteJsClaimKeys.ts deleted file mode 100644 index 3dee2d97d3..0000000000 --- a/local-tests/tests/testUsePkpSessionSigsToExecuteJsClaimKeys.ts +++ /dev/null @@ -1,172 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * ## Scenario: - * Testing the capability to claim keys using PKP session sigs. This test ensures that keys can be claimed correctly. - * - * - Given: PKP sessionSigs are properly generated for the environment. - * - When: These sessionSigs are used to execute JS code within Lit Action. - * - And: The Lit Action JS code attempts to claim a key using the provided sessionSigs. - * - Then: The claim operation should successfully return signatures, derived key IDs, and validate the existence and structure of claimed results. - * - * - Note: The key claiming process involves multiple nodes within the Lit network verifying the sessionSigs and collaboratively signing the claim, which results in the generation of a new key pair if successful. - * - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToExecuteJsClaimKeys - * βœ… NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToExecuteJsClaimKeys - * βœ… NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToExecuteJsClaimKeys - */ -export const testUsePkpSessionSigsToExecuteJsClaimKeys = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: pkpSessionSigs, - code: `(async () => { - Lit.Actions.claimKey({keyId: "foo"}); - })();`, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - console.log('res:', res); - - // Expected output: - // { - // claims: { - // foo: { - // signatures: [ - // { - // r: "0x31e5dcf6eed3619aa6ff68d0c8f7a4bcf082acc2f12c3d5bcae9b8bbaf883c07", - // s: "0x405f671d1c659022105775b18afe805e01eaa1d0799c6b92887baef77dc023f5", - // v: 27, - // }, { - // r: "0xf2e9fe653d9155bd93feb7fe122c07a81769076fe44567c3ea93bb828f87146e", - // s: "0x01adf2b2780511f70b0b037360ff4b0c2b8d04657a689af780180bed9e6ea3c5", - // v: 27, - // }, { - // r: "0xfe1dcacd79f53b42b24dae75521f01315f34bbc492233e26083995c82218a3ff", - // s: "0x0b708b11704d986b50bce9f648bb5d40e8b9ad87f3a337a213999c7751dc1c0c", - // v: 27, - // } - // ], - // derivedKeyId: "22c14f271322473459c456056ffc6e1c0dc1efcb2d15e5be538ad081b224b3d0", - // }, - // }, - // signatures: {}, - // decryptions: [], - // response: undefined, - // logs: "", - // } - - // assertions - if (!res.claims.foo) { - throw new Error(`Expected "foo" in res.claims`); - } - if (!res.claims.foo.derivedKeyId) { - throw new Error(`Expected "derivedKeyId" in res.claims.foo`); - } - - if (!res.claims.foo.signatures) { - throw new Error(`Expected "signatures" in res.claims.foo`); - } - - res.claims.foo.signatures.forEach((sig: any) => { - if (!sig.r) { - throw new Error(`Expected "r" in sig`); - } - if (!sig.s) { - throw new Error(`Expected "s" in sig`); - } - if (!sig.v) { - throw new Error(`Expected "v" in sig`); - } - }); - - // const claimRequest: ClaimRequest = { - // authMethod: devEnv.bobsWalletAuthMethod, - // signer: devEnv.hotWallet, - // mintCallback: async (claimRes: ClaimResult) => { - // console.log('claimRes:', claimRes); - - // const litContracts = await devEnv.getContractsClient(claimRes.signer); - // const pkpInfo = await litContracts.pkpNftContractUtils.write.claimAndMint( - // `0x${claimRes.derivedKeyId}`, - // claimRes.signatures - // ); - - // return pkpInfo.tokenId; - // }, - // }; - - // const claimRes = await devEnv.litNodeClient.claimKeyId(claimRequest); - - // console.log('claimRes:', claimRes); - - // Expected output: - // { - // signatures: [ - // { - // r: "0xf73ec73f2dd7858d9b463598420169cf153f8cd409c82af606b3832ff82f8774", - // s: "0x0de6ab4437749fdf1e6239a8d13af516ac9a0744fc0725f9897a880151799fde", - // v: 28, - // }, { - // r: "0x65ec2ac206c4d18aaf12d6d1f17826543c1f329657214cea66c509fcdec8d633", - // s: "0x710e2efb2c61f9ae504721d7bea0b8d1d3c519167e48e4d67c77bf61dfeca735", - // v: 28, - // }, { - // r: "0xe51bd0670463cb5b5e9994870362b3eaa747cb5732e5c666ccf25495fe9aaa54", - // s: "0x1b49aed6d46833c9b9ee0fa13a4009c533309dafdfd51dd30165f2556b6cdcf1", - // v: 27, - // }, { - // r: "0x4278d3f7f2eb38801da5940858be54527e42ee11b25d7b239cb491139c00765d", - // s: "0x13dac60eaa90a548a4c99f1e09ac24e07cb1ef7447e55d3c82cf2ea6d69ec190", - // v: 27, - // }, { - // r: "0xb18158eccd4b099d0cfae4c2f987843cbaf039ce50164410fe4f529e6dc2bb6a", - // s: "0x284d9d5326deeb3d10e2c1d81ed1a7d6fca584c46ad9606a4dad9f12d81874ab", - // v: 27, - // }, { - // r: "0x28ad76574d39d646948642d05f599a982a1dd0776e2e36138315f5fb2c03666e", - // s: "0x2a125a028df39b9230f5d866383fcda0107cc7ee2f42fa1f323d41b34f67273a", - // v: 27, - // }, { - // r: "0xb7ab5120aeffeaee6e8d6ab1456d6823a15fae7e5a70b88d2556dc85450486cf", - // s: "0x6e1e9ac479066d95d62a6cd86f0cb3db92e07367acf43873fb5a7b8ad558a09d", - // v: 28, - // } - // ], - // claimedKeyId: "4825e3caf11a273792ad0405524820410cd15d6323ae4621537f0a89c1322a74", - // pubkey: "049528b98ac4829b5eaf8f8e6addaa9c12e94e83c4d17baf8f86554c111f2ac6d774f483fca03ad06b268059f7c8bcf64c7fb93689e153dc2fed79dada7b289195", - // mintTx: "0x0000000000000000000000000000000000000000000000000000000000000000", - // } - - // assertions - // if (!claimRes.claimedKeyId) { - // throw new Error(`Expected "claimedKeyId" in claimRes`); - // } - // if (!claimRes.pubkey) { - // throw new Error(`Expected "pubkey" in claimRes`); - // } - // if (!claimRes.mintTx) { - // throw new Error(`Expected "mintTx" in claimRes`); - // } - - // claimRes.signatures.forEach((sig: any) => { - // if (!sig.r) { - // throw new Error(`Expected "r" in sig`); - // } - // if (!sig.s) { - // throw new Error(`Expected "s" in sig`); - // } - // if (!sig.v) { - // throw new Error(`Expected "v" in sig`); - // } - // }); -}; diff --git a/local-tests/tests/testUsePkpSessionSigsToExecuteJsClaimMultipleKeys.ts b/local-tests/tests/testUsePkpSessionSigsToExecuteJsClaimMultipleKeys.ts deleted file mode 100644 index 6b960c9958..0000000000 --- a/local-tests/tests/testUsePkpSessionSigsToExecuteJsClaimMultipleKeys.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * ## Scenario: - * Testing the capability to claim keys using PKP session sigs. This test ensures that multiple keys can be claimed correctly. - * - * - Given: PKP sessionSigs are properly generated for the environment. - * - When: These sessionSigs are used to execute JS code within Lit Action. - * - And: The Lit Action JS code attempts to claim a key using the provided sessionSigs. - * - Then: The claim operation should successfully return signatures, derived key IDs, and validate the existence and structure of claimed results. - * * - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToExecuteJsClaimMultipleKeys - * βœ… NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToExecuteJsClaimMultipleKeys - * βœ… NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToExecuteJsClaimMultipleKeys - */ -export const testUsePkpSessionSigsToExecuteJsClaimMultipleKeys = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: pkpSessionSigs, - code: `(async () => { - Lit.Actions.claimKey({keyId: "foo"}); - Lit.Actions.claimKey({keyId: "bar"}); - })();`, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - // Expected output: - // { - // claims: { - // bar: { - // signatures: [ - // { - // r: "0x7ee7b329462acb08d1dd1d3fba17f8ac76263454e2582bc0d5f36c74f4aaac68", - // s: "0x1b20cd8ac8ab1efdcf500d7ff100229deee42ce44b6420619c609a694af33aad", - // v: 28, - // }, { - // r: "0x2bd6db983d5f5dd239b4fe27b087acf0547e49a69e6c62b8e1435d3890a5d4c5", - // s: "0x15a8a80b2a5bf16e9c155bfe9d5da1109847334b8a0a74a9ce277cdfc6b05fdd", - // v: 28, - // }, { - // r: "0x9294c656bdb6764fca46e431dc4b15c653e6347a41eb657d23145d93a1fa19d0", - // s: "0x7afe0be470e9393dda32c356a9a262f7794a59f8e75e551bdb7634beb3a0a114", - // v: 28, - // } - // ], - // derivedKeyId: "0961c21c8a46c4992003a7b7af9449c15f772a269633ae3242f6ed146708a819", - // }, - // foo: { - // signatures: [ - // { - // r: "0xc39c073d69c8878bf06c813af9d090b41e15319abc9677e20f07085c96451e98", - // s: "0x6ef6a3d4b365119f4a9613a89fd57af01c4a350a20222935581be306b4c8aba4", - // v: 27, - // }, { - // r: "0xa2473911de4b252349cadde340de121ce3195929cd1ebb4c717f3d9d65c67988", - // s: "0x597a45d27a3100fa0bb144644f6bdec62c8a827f35427814cea64f8d3d9a9fa8", - // v: 27, - // }, { - // r: "0x97c393fb1f733b946bfaafdbb13c46192f4cf5ad2b2a9fcf9ff0355a7a2dc5fa", - // s: "0x152737c1b0aba904182bb5ac70e3a99ba4301b631df55bd21b91d705eb5ef4d2", - // v: 27, - // } - // ], - // derivedKeyId: "7698c828a5e4ae6dd6f98ae72fcb5a96bc83f53fa6a09c614e28ceab8198d5ca", - // }, - // }, - // signatures: {}, - // decryptions: [], - // response: undefined, - // logs: "", - // } - - // assertions - if (!res.claims.foo) { - throw new Error(`Expected "foo" in res.claims`); - } - if (!res.claims.foo.derivedKeyId) { - throw new Error(`Expected "derivedKeyId" in res.claims.foo`); - } - - if (!res.claims.foo.signatures) { - throw new Error(`Expected "signatures" in res.claims.foo`); - } - - res.claims.foo.signatures.forEach((sig: any) => { - if (!sig.r) { - throw new Error(`Expected "r" in sig`); - } - if (!sig.s) { - throw new Error(`Expected "s" in sig`); - } - if (!sig.v) { - throw new Error(`Expected "v" in sig`); - } - }); -}; diff --git a/local-tests/tests/testUsePkpSessionSigsToExecuteJsConsoleLog.ts b/local-tests/tests/testUsePkpSessionSigsToExecuteJsConsoleLog.ts deleted file mode 100644 index dab300578d..0000000000 --- a/local-tests/tests/testUsePkpSessionSigsToExecuteJsConsoleLog.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToExecuteJsConsoleLog - * βœ… NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToExecuteJsConsoleLog - * βœ… NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToExecuteJsConsoleLog - */ -export const testUsePkpSessionSigsToExecuteJsConsoleLog = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: pkpSessionSigs, - code: `(async () => { - console.log('hello world') - })();`, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - // Expected output: - // { - // success: true, - // signedData: {}, - // decryptedData: {}, - // claimData: {}, - // response: "", - // logs: "hello world\n", - // } - - // -- assertions - if (res.response) { - throw new Error(`Expected "response" to be falsy`); - } - - if (!res.logs) { - throw new Error(`Expected "logs" in res`); - } - - if (!res.logs.includes('hello world')) { - throw new Error(`Expected "logs" to include 'hello world'`); - } - - if (!res.success) { - throw new Error(`Expected "success" in res`); - } -}; diff --git a/local-tests/tests/testUsePkpSessionSigsToExecuteJsJsonResponse.ts b/local-tests/tests/testUsePkpSessionSigsToExecuteJsJsonResponse.ts deleted file mode 100644 index cc4e016d69..0000000000 --- a/local-tests/tests/testUsePkpSessionSigsToExecuteJsJsonResponse.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToExecuteJsJsonResponse - * βœ… NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToExecuteJsJsonResponse - * βœ… NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToExecuteJsJsonResponse - */ -export const testUsePkpSessionSigsToExecuteJsJsonResponse = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: pkpSessionSigs, - code: `(async () => { - console.log('hello world') - - LitActions.setResponse({ - response: JSON.stringify({hello: 'world'}) - }); - - })();`, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - // Expected output: - // { - // success: true, - // signedData: {}, - // decryptedData: {}, - // claimData: {}, - // response: "{\"hello\":\"world\"}", - // logs: "hello world\n", - // } - - // -- assertions - if (!res.response) { - throw new Error(`Expected "response" in res`); - } - - if (!res.response.startsWith('{')) { - throw new Error(`Expected "response" to start with {`); - } - - if (!res.response.endsWith('}')) { - throw new Error(`Expected "response" to end with }`); - } - - if (!res.logs) { - throw new Error(`Expected "logs" in res`); - } - - if (!res.logs.includes('hello world')) { - throw new Error(`Expected "logs" to include 'hello world'`); - } - - if (!res.success) { - throw new Error(`Expected "success" in res`); - } - - if (res.success !== true) { - throw new Error(`Expected "success" to be true`); - } -}; diff --git a/local-tests/tests/testUsePkpSessionSigsToExecuteJsSigning.ts b/local-tests/tests/testUsePkpSessionSigsToExecuteJsSigning.ts deleted file mode 100644 index 0864680c36..0000000000 --- a/local-tests/tests/testUsePkpSessionSigsToExecuteJsSigning.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { log } from '@lit-protocol/misc'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToExecuteJsSigning - * βœ… NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToExecuteJsSigning - * βœ… NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToExecuteJsSigning - */ -export const testUsePkpSessionSigsToExecuteJsSigning = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: pkpSessionSigs, - code: `(async () => { - const sigShare = await LitActions.signEcdsa({ - toSign: dataToSign, - publicKey, - sigName: "sig", - }); - })();`, - jsParams: { - dataToSign: alice.loveLetter, - publicKey: alice.authMethodOwnedPkp.publicKey, - }, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - // -- Expected output: - // { - // claims: {}, - // signatures: { - // sig: { - // r: "8d2a3b3fa49e67b6bf9de15adfc0b5fbe04b6d730cbef60f4c211c4803bd9c3f", - // s: "1f819cc7a74a72e6f1b16a9a665f19cdd7294132d8a1c70871a752a6d70615e4", - // recid: 1, - // signature: "0x8d2a3b3fa49e67b6bf9de15adfc0b5fbe04b6d730cbef60f4c211c4803bd9c3f1f819cc7a74a72e6f1b16a9a665f19cdd7294132d8a1c70871a752a6d70615e41c", - // publicKey: "044395E44BA89AC0D0E76DEECD937C7BC0AE96B47766AB01CEC5449A8F869754560ACAEAC82CD48FAD3553AD47D7FAA99131F6E7E1B19DEBA058BB6D6B97F2BDB1", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // }, - // }, - // decryptions: [], - // response: undefined, - // logs: "", - // } - - // -- assertions - if (!res.signatures.sig.r) { - throw new Error(`Expected "r" in res.signatures.sig`); - } - if (!res.signatures.sig.s) { - throw new Error(`Expected "s" in res.signatures.sig`); - } - - if (!res.signatures.sig.dataSigned) { - throw new Error(`Expected "dataSigned" in res.signatures.sig`); - } - - if (!res.signatures.sig.publicKey) { - throw new Error(`Expected "publicKey" in res.signatures.sig`); - } - - // -- signatures.sig.signature must start with 0x - if (!res.signatures.sig.signature.startsWith('0x')) { - throw new Error(`Expected "signature" to start with 0x`); - } - - // -- signatures.sig.recid must be parseable as a number - if (isNaN(res.signatures.sig.recid)) { - throw new Error(`Expected "recid" to be parseable as a number`); - } - - log('βœ… res:', res); -}; diff --git a/local-tests/tests/testUsePkpSessionSigsToExecuteJsSigningInParallel.ts b/local-tests/tests/testUsePkpSessionSigsToExecuteJsSigningInParallel.ts deleted file mode 100644 index 7469896024..0000000000 --- a/local-tests/tests/testUsePkpSessionSigsToExecuteJsSigningInParallel.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { log } from '@lit-protocol/misc'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToExecuteJsSigningInParallel - * βœ… NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToExecuteJsSigningInParallel - * βœ… NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToExecuteJsSigningInParallel - */ -export const testUsePkpSessionSigsToExecuteJsSigningInParallel = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - const fn = async (index: number) => { - log(`Index: ${index}`); - - return await devEnv.litNodeClient.executeJs({ - sessionSigs: pkpSessionSigs, - code: `(async () => { - const sigShare = await LitActions.signEcdsa({ - toSign: dataToSign, - publicKey, - sigName: "sig", - }); - })();`, - jsParams: { - dataToSign: alice.loveLetter, - publicKey: alice.authMethodOwnedPkp.publicKey, - }, - }); - }; - - devEnv.releasePrivateKeyFromUser(alice); - - const res = await Promise.all([fn(1), fn(2), fn(3)]); - log('res:', res); - - // -- Expected output: - // [ - // { - // claims: {}, - // signatures: { - // sig: { - // r: "d5bc8b53b9f69604c2dfb2d1d3e6c8b7e01a225346055ee798f5f67fe542a05a", - // s: "0153071ac4c7f9b08330361575b109dec07d1c335edeecd85db47398795a00d0", - // recid: 0, - // signature: "0xd5bc8b53b9f69604c2dfb2d1d3e6c8b7e01a225346055ee798f5f67fe542a05a0153071ac4c7f9b08330361575b109dec07d1c335edeecd85db47398795a00d01b", - // publicKey: "0489782A60B39C758DD8405965DC83DE5F1DB9572861EBAB6064090223C3B7F60DD71C6E673D81550E127BE18497BEA8C349E3B91C8170AD572AD0572009797EA5", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // }, - // }, - // decryptions: [], - // response: undefined, - // logs: "", - // }, { - // claims: {}, - // signatures: { - // sig: { - // r: "d2ad9086e810a5fd9b49dc4c2a0e7e2cf417dd79f8e75cc5f7b7b21d1b7ae9bc", - // s: "5e28b3321e73bab4177f6a69fec924f9daec294cf89a9a4d9c1a8fad18810bbd", - // recid: 1, - // signature: "0xd2ad9086e810a5fd9b49dc4c2a0e7e2cf417dd79f8e75cc5f7b7b21d1b7ae9bc5e28b3321e73bab4177f6a69fec924f9daec294cf89a9a4d9c1a8fad18810bbd1c", - // publicKey: "0489782A60B39C758DD8405965DC83DE5F1DB9572861EBAB6064090223C3B7F60DD71C6E673D81550E127BE18497BEA8C349E3B91C8170AD572AD0572009797EA5", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // }, - // }, - // decryptions: [], - // response: undefined, - // logs: "", - // }, { - // claims: {}, - // signatures: { - // sig: { - // r: "50f87167ba2c8a92e78c95f34e2683a23c372fcc6d104ef9f4d9050d5e1621f3", - // s: "443f5895668e8df6b5d6097a3e9f363923dc2cb83a4734b79359c8213f220fa9", - // recid: 0, - // signature: "0x50f87167ba2c8a92e78c95f34e2683a23c372fcc6d104ef9f4d9050d5e1621f3443f5895668e8df6b5d6097a3e9f363923dc2cb83a4734b79359c8213f220fa91b", - // publicKey: "0489782A60B39C758DD8405965DC83DE5F1DB9572861EBAB6064090223C3B7F60DD71C6E673D81550E127BE18497BEA8C349E3B91C8170AD572AD0572009797EA5", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // }, - // }, - // decryptions: [], - // response: undefined, - // logs: "", - // } - // ] - - // -- assertions - res.forEach((r) => { - if (!r.signatures.sig.r) { - throw new Error(`Expected "r" in res.signatures.sig`); - } - if (!r.signatures.sig.s) { - throw new Error(`Expected "s" in res.signatures.sig`); - } - - if (!r.signatures.sig.dataSigned) { - throw new Error(`Expected "dataSigned" in res.signatures.sig`); - } - - if (!r.signatures.sig.publicKey) { - throw new Error(`Expected "publicKey" in res.signatures.sig`); - } - - // -- signatures.sig.signature must start with 0x - if (!r.signatures.sig.signature.startsWith('0x')) { - throw new Error(`Expected "signature" to start with 0x`); - } - - // -- signatures.sig.recid must be parseable as a number - if (isNaN(r.signatures.sig.recid)) { - throw new Error(`Expected "recid" to be parseable as a number`); - } - }); - - log('βœ… testUsePkpSessionSigsToExecuteJsSigningInParallel'); -}; diff --git a/local-tests/tests/testUsePkpSessionSigsToPkpSign.ts b/local-tests/tests/testUsePkpSessionSigsToPkpSign.ts deleted file mode 100644 index 658b676a73..0000000000 --- a/local-tests/tests/testUsePkpSessionSigsToPkpSign.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { log } from '@lit-protocol/misc'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToPkpSign - * βœ… NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToPkpSign - * βœ… NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToPkpSign - */ -export const testUsePkpSessionSigsToPkpSign = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - const res = await devEnv.litNodeClient.pkpSign({ - toSign: alice.loveLetter, - pubKey: alice.authMethodOwnedPkp.publicKey, - sessionSigs: pkpSessionSigs, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - // -- Expected output: - // { - // r: "f67785b9c516a1fdbd224e9591554171d594bb1fb9799c851bac56212956838a", - // s: "799edb2732f2ebeaf90ea84cbf4c2a2e2ba509487a19d5c6b88210afe362ce42", - // recid: 1, - // signature: "0xf67785b9c516a1fdbd224e9591554171d594bb1fb9799c851bac56212956838a799edb2732f2ebeaf90ea84cbf4c2a2e2ba509487a19d5c6b88210afe362ce421c", - // publicKey: "0486C6E6E854337411A3884E0DEFF15D6D69663594826313BB73E18C465A079B4C2850719F45E9BE2FAC18AA78FFF2C7AEC912FA9D646B2F088C6CAAA8F7A0144A", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // } - - // -- assertions - // r, s, dataSigned, and public key should be present - if (!res.r) { - throw new Error(`Expected "r" in res`); - } - if (!res.s) { - throw new Error(`Expected "s" in res`); - } - if (!res.dataSigned) { - throw new Error(`Expected "dataSigned" in res`); - } - if (!res.publicKey) { - throw new Error(`Expected "publicKey" in res`); - } - - // signature must start with 0x - if (!res.signature.startsWith('0x')) { - throw new Error(`Expected "signature" to start with 0x`); - } - - // recid must be parseable as a number - if (isNaN(res.recid)) { - throw new Error(`Expected "recid" to be parseable as a number`); - } - - log('βœ… res:', res); -}; diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile.ts deleted file mode 100644 index 9481fa4a65..0000000000 --- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs'; -import { ILitNodeClient, LitAbility } from '@lit-protocol/types'; -import { AccessControlConditions } from 'local-tests/setup/accs/accs'; -import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { log } from '@lit-protocol/misc'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile - * βœ… NETWORK=manzano yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile - * βœ… NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile - * βœ… NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile - */ -export const testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile = - async (devEnv: TinnyEnvironment) => { - devEnv.setUnavailable(LIT_TESTNET.MANZANO); - const alice = await devEnv.createRandomPerson(); - - const message = 'Hello world'; - const blob = new Blob([message], { type: 'text/plain' }); - const blobArray = new Uint8Array(await blob.arrayBuffer()); - - // set access control conditions for encrypting and decrypting - const accs = AccessControlConditions.getEmvBasicAccessControlConditions({ - userAddress: alice.authMethodOwnedPkp.ethAddress, - }); - - const encryptRes = await LitJsSdk.encryptString( - { - accessControlConditions: accs, - dataToEncrypt: 'Hello world', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - log('encryptRes:', encryptRes); - - // await 5 seconds for the encryption to be mined - - // -- Expected output: - // { - // ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D", - // dataToEncryptHash: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c", - // } - - // -- assertions - if (!encryptRes.ciphertext) { - throw new Error(`Expected "ciphertext" in encryptRes`); - } - - if (!encryptRes.dataToEncryptHash) { - throw new Error(`Expected "dataToEncryptHash" to in encryptRes`); - } - - const accsResourceString = - await LitAccessControlConditionResource.generateResourceString( - accs, - encryptRes.dataToEncryptHash - ); - - const pkpSessionSigs2 = await getPkpSessionSigs(devEnv, alice, [ - { - resource: new LitAccessControlConditionResource(accsResourceString), - ability: LitAbility.AccessControlConditionDecryption, - }, - ]); - - // -- Decrypt the encrypted string - const decriptedFile = await LitJsSdk.decryptToFile( - { - accessControlConditions: accs, - ciphertext: encryptRes.ciphertext, - dataToEncryptHash: encryptRes.dataToEncryptHash, - sessionSigs: pkpSessionSigs2, - chain: 'ethereum', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - devEnv.releasePrivateKeyFromUser(alice); - - if (blobArray.length !== decriptedFile.length) { - throw new Error( - `decrypted file should match the original file but received ${decriptedFile}` - ); - } - for (let i = 0; i < blobArray.length; i++) { - if (blobArray[i] !== decriptedFile[i]) { - throw new Error(`decrypted file should match the original file`); - } - } - - console.log('decriptedFile:', decriptedFile); - }; diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString.ts deleted file mode 100644 index c62bb9f4e9..0000000000 --- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs'; -import { ILitNodeClient, LitAbility } from '@lit-protocol/types'; -import { AccessControlConditions } from 'local-tests/setup/accs/accs'; -import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { log } from '@lit-protocol/misc'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString - * ❌ NOT AVAILABLE IN MANZANO - * βœ… NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString - * βœ… NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString - * - */ -export const testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString = - async (devEnv: TinnyEnvironment) => { - devEnv.setUnavailable(LIT_TESTNET.MANZANO); - - const alice = await devEnv.createRandomPerson(); - // set access control conditions for encrypting and decrypting - const accs = AccessControlConditions.getEmvBasicAccessControlConditions({ - userAddress: alice.authMethodOwnedPkp.ethAddress, - }); - - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice); - - const encryptRes = await LitJsSdk.encryptString( - { - accessControlConditions: accs, - dataToEncrypt: 'Hello world', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - log('encryptRes:', encryptRes); - - // -- Expected output: - // { - // ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D", - // dataToEncryptHash: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c", - // } - - // -- assertions - if (!encryptRes.ciphertext) { - throw new Error(`Expected "ciphertext" in encryptRes`); - } - - if (!encryptRes.dataToEncryptHash) { - throw new Error(`Expected "dataToEncryptHash" to in encryptRes`); - } - - const accsResourceString = - await LitAccessControlConditionResource.generateResourceString( - accs, - encryptRes.dataToEncryptHash - ); - - const litActionSessionSigs2 = await getLitActionSessionSigs(devEnv, alice, [ - { - resource: new LitAccessControlConditionResource(accsResourceString), - ability: LitAbility.AccessControlConditionDecryption, - }, - ]); - - // -- Decrypt the encrypted string - const decryptRes = await LitJsSdk.decryptToString( - { - accessControlConditions: accs, - ciphertext: encryptRes.ciphertext, - dataToEncryptHash: encryptRes.dataToEncryptHash, - sessionSigs: litActionSessionSigs2, - chain: 'ethereum', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - devEnv.releasePrivateKeyFromUser(alice); - - if (decryptRes !== 'Hello world') { - throw new Error( - `Expected decryptRes to be 'Hello world' but got ${decryptRes}` - ); - } - }; diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip.ts deleted file mode 100644 index 1ef9ff9e5e..0000000000 --- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs'; -import { ILitNodeClient, LitAbility } from '@lit-protocol/types'; -import { AccessControlConditions } from 'local-tests/setup/accs/accs'; -import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { log } from '@lit-protocol/misc'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip - * ❌ Not supported in Manzano - * βœ… NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip - * βœ… NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip - */ -export const testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip = - async (devEnv: TinnyEnvironment) => { - devEnv.setUnavailable(LIT_TESTNET.MANZANO); - const alice = await devEnv.createRandomPerson(); - - const message = 'Hello world'; - - // set access control conditions for encrypting and decrypting - const accs = AccessControlConditions.getEmvBasicAccessControlConditions({ - userAddress: alice.authMethodOwnedPkp.ethAddress, - }); - - const encryptRes = await LitJsSdk.zipAndEncryptString( - { - accessControlConditions: accs, - dataToEncrypt: message, - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - log('encryptRes:', encryptRes); - - // await 5 seconds for the encryption to be mined - - // -- Expected output: - // { - // ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D", - // dataToEncryptHash: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c", - // } - - // -- assertions - if (!encryptRes.ciphertext) { - throw new Error(`Expected "ciphertext" in encryptRes`); - } - - if (!encryptRes.dataToEncryptHash) { - throw new Error(`Expected "dataToEncryptHash" to in encryptRes`); - } - - const accsResourceString = - await LitAccessControlConditionResource.generateResourceString( - accs, - encryptRes.dataToEncryptHash - ); - - const litActionSessionSigs2 = await getLitActionSessionSigs(devEnv, alice, [ - { - resource: new LitAccessControlConditionResource(accsResourceString), - ability: LitAbility.AccessControlConditionDecryption, - }, - ]); - - // -- Decrypt the encrypted string - const decryptedZip = await LitJsSdk.decryptToZip( - { - accessControlConditions: accs, - ciphertext: encryptRes.ciphertext, - dataToEncryptHash: encryptRes.dataToEncryptHash, - sessionSigs: litActionSessionSigs2, - chain: 'ethereum', - }, - devEnv.litNodeClient as unknown as ILitNodeClient - ); - - devEnv.releasePrivateKeyFromUser(alice); - - const decryptedMessage = await decryptedZip['string.txt'].async('string'); - - if (message !== decryptedMessage) { - throw new Error( - `decryptedMessage should be ${message} but received ${decryptedMessage}` - ); - } - - console.log('decryptedMessage:', decryptedMessage); - }; diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys.ts deleted file mode 100644 index 9d6fd6e946..0000000000 --- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { LitActionResource, LitPKPResource } from '@lit-protocol/auth-helpers'; -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LitAbility } from '@lit-protocol/types'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * ## Scenario: - * Testing the capability to claim keys using Lit ACtion PKP session sigs. This test ensures that multiple keys can be claimed correctly. - * - * - Given: Lit ACtion PKP sessionSigs are properly generated for the environment. - * - When: These sessionSigs are used to execute JS code within Lit Action. - * - And: The Lit Action JS code attempts to claim a key using the provided sessionSigs. - * - Then: The claim operation should successfully return signatures, derived key IDs, and validate the existence and structure of claimed results. - * * - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys - * ❌ Not supported in Manzano - * βœ… NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys - * βœ… NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys - */ -export const testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys = - async (devEnv: TinnyEnvironment) => { - devEnv.setUnavailable(LIT_TESTNET.MANZANO); - - const alice = await devEnv.createRandomPerson(); - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice, [ - { - resource: new LitPKPResource('*'), - ability: LitAbility.PKPSigning, - }, - { - resource: new LitActionResource('*'), - ability: LitAbility.LitActionExecution, - }, - ]); - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: litActionSessionSigs, - code: `(async () => { - Lit.Actions.claimKey({keyId: "foo"}); - Lit.Actions.claimKey({keyId: "bar"}); - })();`, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - // Expected output: - // { - // claims: { - // bar: { - // signatures: [ - // { - // r: "0x7ee7b329462acb08d1dd1d3fba17f8ac76263454e2582bc0d5f36c74f4aaac68", - // s: "0x1b20cd8ac8ab1efdcf500d7ff100229deee42ce44b6420619c609a694af33aad", - // v: 28, - // }, { - // r: "0x2bd6db983d5f5dd239b4fe27b087acf0547e49a69e6c62b8e1435d3890a5d4c5", - // s: "0x15a8a80b2a5bf16e9c155bfe9d5da1109847334b8a0a74a9ce277cdfc6b05fdd", - // v: 28, - // }, { - // r: "0x9294c656bdb6764fca46e431dc4b15c653e6347a41eb657d23145d93a1fa19d0", - // s: "0x7afe0be470e9393dda32c356a9a262f7794a59f8e75e551bdb7634beb3a0a114", - // v: 28, - // } - // ], - // derivedKeyId: "0961c21c8a46c4992003a7b7af9449c15f772a269633ae3242f6ed146708a819", - // }, - // foo: { - // signatures: [ - // { - // r: "0xc39c073d69c8878bf06c813af9d090b41e15319abc9677e20f07085c96451e98", - // s: "0x6ef6a3d4b365119f4a9613a89fd57af01c4a350a20222935581be306b4c8aba4", - // v: 27, - // }, { - // r: "0xa2473911de4b252349cadde340de121ce3195929cd1ebb4c717f3d9d65c67988", - // s: "0x597a45d27a3100fa0bb144644f6bdec62c8a827f35427814cea64f8d3d9a9fa8", - // v: 27, - // }, { - // r: "0x97c393fb1f733b946bfaafdbb13c46192f4cf5ad2b2a9fcf9ff0355a7a2dc5fa", - // s: "0x152737c1b0aba904182bb5ac70e3a99ba4301b631df55bd21b91d705eb5ef4d2", - // v: 27, - // } - // ], - // derivedKeyId: "7698c828a5e4ae6dd6f98ae72fcb5a96bc83f53fa6a09c614e28ceab8198d5ca", - // }, - // }, - // signatures: {}, - // decryptions: [], - // response: undefined, - // logs: "", - // } - - // assertions - if (!res.claims.foo) { - throw new Error(`Expected "foo" in res.claims`); - } - if (!res.claims.foo.derivedKeyId) { - throw new Error(`Expected "derivedKeyId" in res.claims.foo`); - } - - if (!res.claims.foo.signatures) { - throw new Error(`Expected "signatures" in res.claims.foo`); - } - - res.claims.foo.signatures.forEach((sig: any) => { - if (!sig.r) { - throw new Error(`Expected "r" in sig`); - } - if (!sig.s) { - throw new Error(`Expected "s" in sig`); - } - if (!sig.v) { - throw new Error(`Expected "v" in sig`); - } - }); - }; diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys.ts deleted file mode 100644 index 2cd2919b8d..0000000000 --- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * ## Scenario: - * Testing the capability to claim keys using Lit Action PKP session sigs. This test ensures that multiple keys can be claimed correctly. - * - * - Given: Lit Action PKP sessionSigs are properly generated for the environment. - * - When: These sessionSigs are used to execute JS code within Lit Action. - * - And: The Lit Action JS code attempts to claim a key using the provided sessionSigs. - * - Then: The claim operation should successfully return signatures, derived key IDs, and validate the existence and structure of claimed results. - * * - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys - * ❌ Not supported in Manzano - * βœ… NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys - * βœ… NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys - */ -export const testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys = - async (devEnv: TinnyEnvironment) => { - devEnv.setUnavailable(LIT_TESTNET.MANZANO); - - const alice = await devEnv.createRandomPerson(); - - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice); - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: litActionSessionSigs, - code: `(async () => { - Lit.Actions.claimKey({keyId: "foo"}); - Lit.Actions.claimKey({keyId: "bar"}); - })();`, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - // Expected output: - // { - // claims: { - // bar: { - // signatures: [ - // { - // r: "0x7ee7b329462acb08d1dd1d3fba17f8ac76263454e2582bc0d5f36c74f4aaac68", - // s: "0x1b20cd8ac8ab1efdcf500d7ff100229deee42ce44b6420619c609a694af33aad", - // v: 28, - // }, { - // r: "0x2bd6db983d5f5dd239b4fe27b087acf0547e49a69e6c62b8e1435d3890a5d4c5", - // s: "0x15a8a80b2a5bf16e9c155bfe9d5da1109847334b8a0a74a9ce277cdfc6b05fdd", - // v: 28, - // }, { - // r: "0x9294c656bdb6764fca46e431dc4b15c653e6347a41eb657d23145d93a1fa19d0", - // s: "0x7afe0be470e9393dda32c356a9a262f7794a59f8e75e551bdb7634beb3a0a114", - // v: 28, - // } - // ], - // derivedKeyId: "0961c21c8a46c4992003a7b7af9449c15f772a269633ae3242f6ed146708a819", - // }, - // foo: { - // signatures: [ - // { - // r: "0xc39c073d69c8878bf06c813af9d090b41e15319abc9677e20f07085c96451e98", - // s: "0x6ef6a3d4b365119f4a9613a89fd57af01c4a350a20222935581be306b4c8aba4", - // v: 27, - // }, { - // r: "0xa2473911de4b252349cadde340de121ce3195929cd1ebb4c717f3d9d65c67988", - // s: "0x597a45d27a3100fa0bb144644f6bdec62c8a827f35427814cea64f8d3d9a9fa8", - // v: 27, - // }, { - // r: "0x97c393fb1f733b946bfaafdbb13c46192f4cf5ad2b2a9fcf9ff0355a7a2dc5fa", - // s: "0x152737c1b0aba904182bb5ac70e3a99ba4301b631df55bd21b91d705eb5ef4d2", - // v: 27, - // } - // ], - // derivedKeyId: "7698c828a5e4ae6dd6f98ae72fcb5a96bc83f53fa6a09c614e28ceab8198d5ca", - // }, - // }, - // signatures: {}, - // decryptions: [], - // response: undefined, - // logs: "", - // } - - // assertions - if (!res.claims.foo) { - throw new Error(`Expected "foo" in res.claims`); - } - if (!res.claims.foo.derivedKeyId) { - throw new Error(`Expected "derivedKeyId" in res.claims.foo`); - } - - if (!res.claims.foo.signatures) { - throw new Error(`Expected "signatures" in res.claims.foo`); - } - - res.claims.foo.signatures.forEach((sig: any) => { - if (!sig.r) { - throw new Error(`Expected "r" in sig`); - } - if (!sig.s) { - throw new Error(`Expected "s" in sig`); - } - if (!sig.v) { - throw new Error(`Expected "v" in sig`); - } - }); - }; diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog.ts deleted file mode 100644 index 53ffe99766..0000000000 --- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { LitActionResource, LitPKPResource } from '@lit-protocol/auth-helpers'; -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LitAbility } from '@lit-protocol/types'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog - * ❌ Not supported on manzano - * βœ… NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog - * βœ… NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog - */ -export const testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog = - async (devEnv: TinnyEnvironment) => { - devEnv.setUnavailable(LIT_TESTNET.MANZANO); - - const alice = await devEnv.createRandomPerson(); - - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice, [ - { - resource: new LitPKPResource('*'), - ability: LitAbility.PKPSigning, - }, - { - resource: new LitActionResource('*'), - ability: LitAbility.LitActionExecution, - }, - ]); - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: litActionSessionSigs, - code: `(async () => { - console.log('hello world') - })();`, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - console.log('res:', res); - - // Expected output: - // { - // success: true, - // signedData: {}, - // decryptedData: {}, - // claimData: {}, - // response: "", - // logs: "hello world\n", - // } - - // -- assertions - if (res.response) { - throw new Error(`Expected "response" to be falsy`); - } - - if (!res.logs) { - throw new Error(`Expected "logs" in res`); - } - - if (!res.logs.includes('hello world')) { - throw new Error(`Expected "logs" to include 'hello world'`); - } - - if (!res.success) { - throw new Error(`Expected "success" in res`); - } - }; diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse.ts deleted file mode 100644 index 007c9e448c..0000000000 --- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse - * ❌ Not supported on manzano - * βœ… NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse - * βœ… NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse - */ -export const testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse = - async (devEnv: TinnyEnvironment) => { - devEnv.setUnavailable(LIT_TESTNET.MANZANO); - - const alice = await devEnv.createRandomPerson(); - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice); - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: litActionSessionSigs, - code: `(async () => { - console.log('hello world') - - LitActions.setResponse({ - response: JSON.stringify({hello: 'world'}) - }); - - })();`, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - // Expected output: - // { - // success: true, - // signedData: {}, - // decryptedData: {}, - // claimData: {}, - // response: "{\"hello\":\"world\"}", - // logs: "hello world\n", - // } - - // -- assertions - if (!res.response) { - throw new Error(`Expected "response" in res`); - } - - if (!res.response.startsWith('{')) { - throw new Error(`Expected "response" to start with {`); - } - - if (!res.response.endsWith('}')) { - throw new Error(`Expected "response" to end with }`); - } - - if (!res.logs) { - throw new Error(`Expected "logs" in res`); - } - - if (!res.logs.includes('hello world')) { - throw new Error(`Expected "logs" to include 'hello world'`); - } - - if (!res.success) { - throw new Error(`Expected "success" in res`); - } - - if (res.success !== true) { - throw new Error(`Expected "success" to be true`); - } - }; diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning.ts deleted file mode 100644 index 92b90b2556..0000000000 --- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { LitActionResource, LitPKPResource } from '@lit-protocol/auth-helpers'; -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { log } from '@lit-protocol/misc'; -import { LitAbility } from '@lit-protocol/types'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning - * ❌ NOT AVAILABLE IN HABANERO - * βœ… NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning - * βœ… NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning - */ -export const testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning = - async (devEnv: TinnyEnvironment) => { - // - // devEnv.setUnavailable(LIT_TESTNET.MANZANO); - - const alice = await devEnv.createRandomPerson(); - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice, [ - { - resource: new LitPKPResource('*'), - ability: LitAbility.PKPSigning, - }, - { - resource: new LitActionResource('*'), - ability: LitAbility.LitActionExecution, - }, - ]); - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: litActionSessionSigs, - code: `(async () => { - const sigShare = await LitActions.signEcdsa({ - toSign: dataToSign, - publicKey, - sigName: "sig", - }); - })();`, - jsParams: { - dataToSign: alice.loveLetter, - publicKey: alice.authMethodOwnedPkp.publicKey, - }, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - // -- Expected output: - // { - // claims: {}, - // signatures: { - // sig: { - // r: "6d5ce6f948ff763939c204fc0f1b750fa0267ed567ed59581082d0cbf283feef", - // s: "4957ece75c60388500c4b7aa38a5fbafb7c20427db181aff7806af54c16ee145", - // recid: 1, - // signature: "0x6d5ce6f948ff763939c204fc0f1b750fa0267ed567ed59581082d0cbf283feef4957ece75c60388500c4b7aa38a5fbafb7c20427db181aff7806af54c16ee1451c", - // publicKey: "04D10D941B04491FDC99B048E2252A69137333254C482511D6CCDD401C080AF4F51BF65D9AE2413FCE066E326D7F0CED9C139DD9BA2D1C6334FD8C14CA4DD7F3D0", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // }, - // }, - // decryptions: [], - // response: undefined, - // logs: "", - // } - - // -- assertions - if (!res.signatures.sig.r) { - throw new Error(`Expected "r" in res.signatures.sig`); - } - if (!res.signatures.sig.s) { - throw new Error(`Expected "s" in res.signatures.sig`); - } - - if (!res.signatures.sig.dataSigned) { - throw new Error(`Expected "dataSigned" in res.signatures.sig`); - } - - if (!res.signatures.sig.publicKey) { - throw new Error(`Expected "publicKey" in res.signatures.sig`); - } - - log('βœ… res:', res); - }; diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel.ts deleted file mode 100644 index e57cc6f451..0000000000 --- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { log } from '@lit-protocol/misc'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel - * ❌ Not available in Habanero - * βœ… NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel - * βœ… NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel - */ -export const testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel = - async (devEnv: TinnyEnvironment) => { - devEnv.setUnavailable(LIT_TESTNET.MANZANO); - - const alice = await devEnv.createRandomPerson(); - - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice); - - const fn = async (index: number) => { - log(`Index: ${index}`); - - return await devEnv.litNodeClient.executeJs({ - sessionSigs: litActionSessionSigs, - code: `(async () => { - const sigShare = await LitActions.signEcdsa({ - toSign: dataToSign, - publicKey, - sigName: "sig", - }); - })();`, - jsParams: { - dataToSign: alice.loveLetter, - publicKey: alice.authMethodOwnedPkp.publicKey, - }, - }); - }; - - devEnv.releasePrivateKeyFromUser(alice); - - const res = await Promise.all([fn(1), fn(2), fn(3)]); - log('res:', res); - - // -- Expected output: - // [ - // { - // claims: {}, - // signatures: { - // sig: { - // r: "d5bc8b53b9f69604c2dfb2d1d3e6c8b7e01a225346055ee798f5f67fe542a05a", - // s: "0153071ac4c7f9b08330361575b109dec07d1c335edeecd85db47398795a00d0", - // recid: 0, - // signature: "0xd5bc8b53b9f69604c2dfb2d1d3e6c8b7e01a225346055ee798f5f67fe542a05a0153071ac4c7f9b08330361575b109dec07d1c335edeecd85db47398795a00d01b", - // publicKey: "0489782A60B39C758DD8405965DC83DE5F1DB9572861EBAB6064090223C3B7F60DD71C6E673D81550E127BE18497BEA8C349E3B91C8170AD572AD0572009797EA5", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // }, - // }, - // decryptions: [], - // response: undefined, - // logs: "", - // }, { - // claims: {}, - // signatures: { - // sig: { - // r: "d2ad9086e810a5fd9b49dc4c2a0e7e2cf417dd79f8e75cc5f7b7b21d1b7ae9bc", - // s: "5e28b3321e73bab4177f6a69fec924f9daec294cf89a9a4d9c1a8fad18810bbd", - // recid: 1, - // signature: "0xd2ad9086e810a5fd9b49dc4c2a0e7e2cf417dd79f8e75cc5f7b7b21d1b7ae9bc5e28b3321e73bab4177f6a69fec924f9daec294cf89a9a4d9c1a8fad18810bbd1c", - // publicKey: "0489782A60B39C758DD8405965DC83DE5F1DB9572861EBAB6064090223C3B7F60DD71C6E673D81550E127BE18497BEA8C349E3B91C8170AD572AD0572009797EA5", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // }, - // }, - // decryptions: [], - // response: undefined, - // logs: "", - // }, { - // claims: {}, - // signatures: { - // sig: { - // r: "50f87167ba2c8a92e78c95f34e2683a23c372fcc6d104ef9f4d9050d5e1621f3", - // s: "443f5895668e8df6b5d6097a3e9f363923dc2cb83a4734b79359c8213f220fa9", - // recid: 0, - // signature: "0x50f87167ba2c8a92e78c95f34e2683a23c372fcc6d104ef9f4d9050d5e1621f3443f5895668e8df6b5d6097a3e9f363923dc2cb83a4734b79359c8213f220fa91b", - // publicKey: "0489782A60B39C758DD8405965DC83DE5F1DB9572861EBAB6064090223C3B7F60DD71C6E673D81550E127BE18497BEA8C349E3B91C8170AD572AD0572009797EA5", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // }, - // }, - // decryptions: [], - // response: undefined, - // logs: "", - // } - // ] - - // -- assertions - res.forEach((r) => { - if (!r.signatures.sig.r) { - throw new Error(`Expected "r" in res.signatures.sig`); - } - if (!r.signatures.sig.s) { - throw new Error(`Expected "s" in res.signatures.sig`); - } - - if (!r.signatures.sig.dataSigned) { - throw new Error(`Expected "dataSigned" in res.signatures.sig`); - } - - if (!r.signatures.sig.publicKey) { - throw new Error(`Expected "publicKey" in res.signatures.sig`); - } - - // -- signatures.sig.signature must start with 0x - if (!r.signatures.sig.signature.startsWith('0x')) { - throw new Error(`Expected "signature" to start with 0x`); - } - - // -- signatures.sig.recid must be parseable as a number - if (isNaN(r.signatures.sig.recid)) { - throw new Error(`Expected "recid" to be parseable as a number`); - } - }); - - log('βœ… testUsePkpSessionSigsToExecuteJsSigningInParallel'); - }; diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToPkpSign.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToPkpSign.ts deleted file mode 100644 index b72471a035..0000000000 --- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToPkpSign.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { LitPKPResource } from '@lit-protocol/auth-helpers'; -import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants'; -import { log } from '@lit-protocol/misc'; -import { LitAbility } from '@lit-protocol/types'; -import { LIT_TESTNET } from 'local-tests/setup/tinny-config'; -import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToPkpSign - * ❌ NOT AVAILABLE IN HABANERO - * βœ… NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToPkpSign - * βœ… NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToPkpSign - * - **/ -export const testUseValidLitActionCodeGeneratedSessionSigsToPkpSign = async ( - devEnv: TinnyEnvironment -) => { - devEnv.setUnavailable(LIT_TESTNET.MANZANO); - - const alice = await devEnv.createRandomPerson(); - const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice); - - const res = await devEnv.litNodeClient.pkpSign({ - toSign: alice.loveLetter, - pubKey: alice.authMethodOwnedPkp.publicKey, - sessionSigs: litActionSessionSigs, - }); - - devEnv.releasePrivateKeyFromUser(alice); - - // -- Expected output: - // { - // r: "ab2cef959db920d56f001c3b05637ee49af4c4441f2867ea067c413594a4c87b", - // s: "4bf11e17b4bb618aa6ed75cbf0406e6babfd953c5b201da697077c5fbf5b542e", - // recid: 1, - // signature: "0xab2cef959db920d56f001c3b05637ee49af4c4441f2867ea067c413594a4c87b4bf11e17b4bb618aa6ed75cbf0406e6babfd953c5b201da697077c5fbf5b542e1c", - // publicKey: "04400AD53C2F8BA11EBC69F05D1076D5BEE4EAE668CD66BABADE2E0770F756FDEEFC2C1D20F9A698EA3FEC6E9C944FF9FAFC2DC339B8E9392AFB9CC8AE75C5E5EC", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // } - - // -- assertions - // r, s, dataSigned, and public key should be present - if (!res.r) { - throw new Error(`Expected "r" in res`); - } - if (!res.s) { - throw new Error(`Expected "s" in res`); - } - if (!res.dataSigned) { - throw new Error(`Expected "dataSigned" in res`); - } - if (!res.publicKey) { - throw new Error(`Expected "publicKey" in res`); - } - - // signature must start with 0x - if (!res.signature.startsWith('0x')) { - throw new Error(`Expected "signature" to start with 0x`); - } - - // recid must be parseable as a number - if (isNaN(res.recid)) { - throw new Error(`Expected "recid" to be parseable as a number`); - } - - log('βœ… res:', res); -}; diff --git a/local-tests/tests/testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning.ts b/local-tests/tests/testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning.ts deleted file mode 100644 index 535521bd87..0000000000 --- a/local-tests/tests/testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { LitActionResource, LitPKPResource } from '@lit-protocol/auth-helpers'; -import { log } from '@lit-protocol/misc'; -import { LitAbility } from '@lit-protocol/types'; -import { getLitActionSessionSigsUsingIpfsId } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning - * ❌ NOT AVAILABLE IN HABANERO - * βœ… NETWORK=localchain yarn test:local --filter=testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning - */ -export const testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning = - async (devEnv: TinnyEnvironment) => { - const alice = await devEnv.createRandomPerson(); - const litActionSessionSigs = await getLitActionSessionSigsUsingIpfsId( - devEnv, - alice, - [ - { - resource: new LitPKPResource('*'), - ability: LitAbility.PKPSigning, - }, - { - resource: new LitActionResource('*'), - ability: LitAbility.LitActionExecution, - }, - ] - ); - - const res = await devEnv.litNodeClient.executeJs({ - sessionSigs: litActionSessionSigs, - code: `(async () => { - const sigShare = await LitActions.signEcdsa({ - toSign: dataToSign, - publicKey, - sigName: "sig", - }); - })();`, - jsParams: { - dataToSign: alice.loveLetter, - publicKey: alice.authMethodOwnedPkp.publicKey, - }, - }); - devEnv.releasePrivateKeyFromUser(alice); - console.log('βœ… res:', res); - - // -- Expected output: - // { - // claims: {}, - // signatures: { - // sig: { - // r: "6d5ce6f948ff763939c204fc0f1b750fa0267ed567ed59581082d0cbf283feef", - // s: "4957ece75c60388500c4b7aa38a5fbafb7c20427db181aff7806af54c16ee145", - // recid: 1, - // signature: "0x6d5ce6f948ff763939c204fc0f1b750fa0267ed567ed59581082d0cbf283feef4957ece75c60388500c4b7aa38a5fbafb7c20427db181aff7806af54c16ee1451c", - // publicKey: "04D10D941B04491FDC99B048E2252A69137333254C482511D6CCDD401C080AF4F51BF65D9AE2413FCE066E326D7F0CED9C139DD9BA2D1C6334FD8C14CA4DD7F3D0", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // }, - // }, - // decryptions: [], - // response: undefined, - // logs: "", - // } - - // -- assertions - if (!res.signatures.sig.r) { - throw new Error(`Expected "r" in res.signatures.sig`); - } - if (!res.signatures.sig.s) { - throw new Error(`Expected "s" in res.signatures.sig`); - } - - if (!res.signatures.sig.dataSigned) { - throw new Error(`Expected "dataSigned" in res.signatures.sig`); - } - - if (!res.signatures.sig.publicKey) { - throw new Error(`Expected "publicKey" in res.signatures.sig`); - } - - log('βœ… res:', res); - }; diff --git a/local-tests/tests/testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign.ts b/local-tests/tests/testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign.ts deleted file mode 100644 index 9d11289b7b..0000000000 --- a/local-tests/tests/testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { log } from '@lit-protocol/misc'; -import { getLitActionSessionSigsUsingIpfsId } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign - * ❌ NOT AVAILABLE IN HABANERO - * ❌ NETWORK=localchain yarn test:local --filter=testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign - * - **/ -export const testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign = - async (devEnv: TinnyEnvironment) => { - const alice = await devEnv.createRandomPerson(); - let litActionSessionSigs; - - try { - litActionSessionSigs = await getLitActionSessionSigsUsingIpfsId( - devEnv, - alice - ); - } catch (e: any) { - console.log('❌ This error is NOT expected:', e); - throw new Error(e); - } - - const res = await devEnv.litNodeClient.pkpSign({ - toSign: alice.loveLetter, - pubKey: alice.authMethodOwnedPkp.publicKey, - sessionSigs: litActionSessionSigs, - }); - devEnv.releasePrivateKeyFromUser(alice); - console.log('βœ… res:', res); - - // -- Expected output: - // { - // r: "ab2cef959db920d56f001c3b05637ee49af4c4441f2867ea067c413594a4c87b", - // s: "4bf11e17b4bb618aa6ed75cbf0406e6babfd953c5b201da697077c5fbf5b542e", - // recid: 1, - // signature: "0xab2cef959db920d56f001c3b05637ee49af4c4441f2867ea067c413594a4c87b4bf11e17b4bb618aa6ed75cbf0406e6babfd953c5b201da697077c5fbf5b542e1c", - // publicKey: "04400AD53C2F8BA11EBC69F05D1076D5BEE4EAE668CD66BABADE2E0770F756FDEEFC2C1D20F9A698EA3FEC6E9C944FF9FAFC2DC339B8E9392AFB9CC8AE75C5E5EC", - // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", - // } - - // -- assertions - // r, s, dataSigned, and public key should be present - if (!res.r) { - throw new Error(`Expected "r" in res`); - } - if (!res.s) { - throw new Error(`Expected "s" in res`); - } - if (!res.dataSigned) { - throw new Error(`Expected "dataSigned" in res`); - } - if (!res.publicKey) { - throw new Error(`Expected "publicKey" in res`); - } - - // signature must start with 0x - if (!res.signature.startsWith('0x')) { - throw new Error(`Expected "signature" to start with 0x`); - } - - // recid must be parseable as a number - if (isNaN(res.recid)) { - throw new Error(`Expected "recid" to be parseable as a number`); - } - - log('βœ… res:', res); - }; diff --git a/local-tests/tests/wrapped-keys/testEthereumBroadcastTransactionGeneratedKey.ts b/local-tests/tests/wrapped-keys/testEthereumBroadcastTransactionGeneratedKey.ts deleted file mode 100644 index 711516a3b3..0000000000 --- a/local-tests/tests/wrapped-keys/testEthereumBroadcastTransactionGeneratedKey.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { log } from '@lit-protocol/misc'; -import { ethers } from 'ethers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { api, EthereumLitTransaction } from '@lit-protocol/wrapped-keys'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { getBaseTransactionForNetwork } from './util'; - -const { signTransactionWithEncryptedKey, generatePrivateKey } = api; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testEthereumBroadcastTransactionGeneratedKey - * βœ… NETWORK=manzano yarn test:local --filter=testEthereumBroadcastTransactionGeneratedKey - * βœ… NETWORK=localchain yarn test:local --filter=testEthereumBroadcastTransactionGeneratedKey - */ -export const testEthereumBroadcastTransactionGeneratedKey = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - try { - const pkpSessionSigs = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - const { pkpAddress, generatedPublicKey, id } = await generatePrivateKey({ - pkpSessionSigs, - network: 'evm', - litNodeClient: devEnv.litNodeClient, - memo: 'Test key', - }); - - const generatedKeysWalletAddress = - ethers.utils.computeAddress(generatedPublicKey); - console.log(`Sending funds to ${generatedKeysWalletAddress}`); - await devEnv.getFunds(generatedKeysWalletAddress, '0.005'); - - const alicePkpAddress = alice.authMethodOwnedPkp.ethAddress; - if (pkpAddress !== alicePkpAddress) { - throw new Error( - `Received address: ${pkpAddress} doesn't match Alice's PKP address: ${alicePkpAddress}` - ); - } - - const pkpSessionSigsSigning = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - // console.log(pkpSessionSigsSigning); - - const unsignedTransaction = getBaseTransactionForNetwork({ - network: devEnv.litNodeClient.config.litNetwork, - toAddress: alice.wallet.address, - }); - - const signedTx = await signTransactionWithEncryptedKey({ - pkpSessionSigs: pkpSessionSigsSigning, - network: 'evm', - unsignedTransaction, - broadcast: true, - litNodeClient: devEnv.litNodeClient, - id, - }); - - // console.log('signedTx'); - // console.log(signedTx); - - if (!ethers.utils.isHexString(signedTx)) { - throw new Error(`signedTx isn't hex: ${signedTx}`); - } - - log('βœ… testEthereumBroadcastTransactionGeneratedKey'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/wrapped-keys/testEthereumBroadcastTransactionWrappedKey.ts b/local-tests/tests/wrapped-keys/testEthereumBroadcastTransactionWrappedKey.ts deleted file mode 100644 index 85aae4d90e..0000000000 --- a/local-tests/tests/wrapped-keys/testEthereumBroadcastTransactionWrappedKey.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { log } from '@lit-protocol/misc'; -import { ethers } from 'ethers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { api, EthereumLitTransaction } from '@lit-protocol/wrapped-keys'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { getBaseTransactionForNetwork } from './util'; - -const { importPrivateKey, signTransactionWithEncryptedKey } = api; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testEthereumBroadcastTransactionWrappedKey - * βœ… NETWORK=manzano yarn test:local --filter=testEthereumBroadcastTransactionWrappedKey - * βœ… NETWORK=localchain yarn test:local --filter=testEthereumBroadcastTransactionWrappedKey - */ -export const testEthereumBroadcastTransactionWrappedKey = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - try { - const pkpSessionSigs = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - const wrappedKeysWallet = ethers.Wallet.createRandom(); - const wrappedKeysWalletPrivateKey = wrappedKeysWallet.privateKey; - - const wrappedKeysWalletAddress = wrappedKeysWallet.address; - console.log(`Sending funds to ${wrappedKeysWalletAddress}`); - await devEnv.getFunds(wrappedKeysWallet.address, '0.005'); - - const { pkpAddress, id } = await importPrivateKey({ - pkpSessionSigs, - privateKey: wrappedKeysWalletPrivateKey, - litNodeClient: devEnv.litNodeClient, - publicKey: '0xdeadbeef', - keyType: 'K256', - memo: 'Test key', - }); - - const alicePkpAddress = alice.authMethodOwnedPkp.ethAddress; - if (pkpAddress !== alicePkpAddress) { - throw new Error( - `Received address: ${pkpAddress} doesn't match Alice's PKP address: ${alicePkpAddress}` - ); - } - - const pkpSessionSigsSigning = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - // console.log(pkpSessionSigsSigning); - - const unsignedTransaction = getBaseTransactionForNetwork({ - network: devEnv.litNodeClient.config.litNetwork, - toAddress: alice.wallet.address, - }); - - const signedTx = await signTransactionWithEncryptedKey({ - pkpSessionSigs: pkpSessionSigsSigning, - network: 'evm', - unsignedTransaction, - broadcast: true, - litNodeClient: devEnv.litNodeClient, - id, - }); - - // console.log('signedTx'); - // console.log(signedTx); - - // TODO: Get the raw input from the tx hash, convert it to UTF-8 and assert that it contains "Test transaction from Alice to bob" - if (!ethers.utils.isHexString(signedTx)) { - throw new Error(`signedTx isn't hex: ${signedTx}`); - } - - log('βœ… testEthereumBroadcastTransactionWrappedKey'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/wrapped-keys/testEthereumBroadcastWrappedKeyWithFetchGasParams.ts b/local-tests/tests/wrapped-keys/testEthereumBroadcastWrappedKeyWithFetchGasParams.ts deleted file mode 100644 index 4c1e7af112..0000000000 --- a/local-tests/tests/wrapped-keys/testEthereumBroadcastWrappedKeyWithFetchGasParams.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { log } from '@lit-protocol/misc'; -import { ethers } from 'ethers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { api, EthereumLitTransaction } from '@lit-protocol/wrapped-keys'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { getChainForNetwork } from './util'; - -const { importPrivateKey, signTransactionWithEncryptedKey } = api; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testEthereumBroadcastWrappedKeyWithFetchGasParams - * βœ… NETWORK=manzano yarn test:local --filter=testEthereumBroadcastWrappedKeyWithFetchGasParams - * βœ… NETWORK=localchain yarn test:local --filter=testEthereumBroadcastWrappedKeyWithFetchGasParams - */ -export const testEthereumBroadcastWrappedKeyWithFetchGasParams = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - try { - const pkpSessionSigs = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - const wrappedKeysWallet = ethers.Wallet.createRandom(); - const wrappedKeysWalletPrivateKey = wrappedKeysWallet.privateKey; - - const wrappedKeysWalletAddress = wrappedKeysWallet.address; - console.log(`Sending funds to ${wrappedKeysWalletAddress}`); - await devEnv.getFunds(wrappedKeysWallet.address, '0.005'); - - const { pkpAddress, id } = await importPrivateKey({ - pkpSessionSigs, - privateKey: wrappedKeysWalletPrivateKey, - litNodeClient: devEnv.litNodeClient, - publicKey: '0xdeadbeef', - keyType: 'K256', - memo: 'Test key', - }); - - const alicePkpAddress = alice.authMethodOwnedPkp.ethAddress; - if (pkpAddress !== alicePkpAddress) { - throw new Error( - `Received address: ${pkpAddress} doesn't match Alice's PKP address: ${alicePkpAddress}` - ); - } - - const pkpSessionSigsSigning = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - // console.log(pkpSessionSigsSigning); - - const unsignedTransaction: EthereumLitTransaction = { - toAddress: alice.wallet.address, - value: '0.0001', // in ethers (Lit tokens) - dataHex: ethers.utils.hexlify( - ethers.utils.toUtf8Bytes('Test transaction from Alice to bob') - ), - ...getChainForNetwork(devEnv.litNodeClient.config.litNetwork), - }; - - const signedTx = await signTransactionWithEncryptedKey({ - pkpSessionSigs: pkpSessionSigsSigning, - network: 'evm', - unsignedTransaction, - broadcast: true, - litNodeClient: devEnv.litNodeClient, - id, - }); - - // console.log('signedTx'); - // console.log(signedTx); - - // TODO: Get the raw input from the tx hash, convert it to UTF-8 and assert that it contains "Test transaction from Alice to bob" - if (!ethers.utils.isHexString(signedTx)) { - throw new Error(`signedTx isn't hex: ${signedTx}`); - } - - log('βœ… testEthereumBroadcastWrappedKeyWithDefaultGasParams'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/wrapped-keys/testEthereumSignMessageGeneratedKey.ts b/local-tests/tests/wrapped-keys/testEthereumSignMessageGeneratedKey.ts deleted file mode 100644 index a06531dce0..0000000000 --- a/local-tests/tests/wrapped-keys/testEthereumSignMessageGeneratedKey.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { log } from '@lit-protocol/misc'; -import { ethers } from 'ethers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { api } from '@lit-protocol/wrapped-keys'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; - -const { generatePrivateKey, signMessageWithEncryptedKey } = api; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testEthereumSignMessageGeneratedKey - * βœ… NETWORK=manzano yarn test:local --filter=testEthereumSignMessageGeneratedKey - * βœ… NETWORK=localchain yarn test:local --filter=testEthereumSignMessageGeneratedKey - */ -export const testEthereumSignMessageGeneratedKey = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - try { - const pkpSessionSigs = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - const { pkpAddress, id, generatedPublicKey } = await generatePrivateKey({ - pkpSessionSigs, - network: 'evm', - litNodeClient: devEnv.litNodeClient, - memo: 'Test key', - }); - - const alicePkpAddress = alice.authMethodOwnedPkp.ethAddress; - if (pkpAddress !== alicePkpAddress) { - throw new Error( - `Received address: ${pkpAddress} doesn't match Alice's PKP address: ${alicePkpAddress}` - ); - } - - const pkpSessionSigsSigning = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - // console.log(pkpSessionSigsSigning); - - const unsignedStringMessage = 'This is a test message'; - - const signature = await signMessageWithEncryptedKey({ - pkpSessionSigs: pkpSessionSigsSigning, - network: 'evm', - messageToSign: unsignedStringMessage, - litNodeClient: devEnv.litNodeClient, - id, - }); - - // console.log('signature'); - // console.log(signature); - - if (!ethers.utils.isHexString(signature)) { - throw new Error(`signature isn't hex: ${signature}`); - } - - const unsignedBinaryMessage = ethers.utils.arrayify( - ethers.utils.toUtf8Bytes(unsignedStringMessage) - ); - - const signatureBinary = await signMessageWithEncryptedKey({ - pkpSessionSigs: pkpSessionSigsSigning, - network: 'evm', - messageToSign: unsignedBinaryMessage, - litNodeClient: devEnv.litNodeClient, - id, - }); - - // console.log('signatureBinary'); - // console.log(signatureBinary); - - if (!ethers.utils.isHexString(signatureBinary)) { - throw new Error(`signatureBinary isn't hex: ${signatureBinary}`); - } - - if (signatureBinary !== signature) { - throw new Error( - `signature: ${signature} doesn't match it's signatureBinary form: ${signatureBinary}` - ); - } - - log('βœ… testEthereumSignMessageGeneratedKey'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/wrapped-keys/testEthereumSignMessageWrappedKey.ts b/local-tests/tests/wrapped-keys/testEthereumSignMessageWrappedKey.ts deleted file mode 100644 index 05d692ea0f..0000000000 --- a/local-tests/tests/wrapped-keys/testEthereumSignMessageWrappedKey.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { log } from '@lit-protocol/misc'; -import { ethers } from 'ethers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { api } from '@lit-protocol/wrapped-keys'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; - -const { importPrivateKey, signMessageWithEncryptedKey } = api; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testEthereumSignMessageWrappedKey - * βœ… NETWORK=manzano yarn test:local --filter=testEthereumSignMessageWrappedKey - * βœ… NETWORK=localchain yarn test:local --filter=testEthereumSignMessageWrappedKey - */ -export const testEthereumSignMessageWrappedKey = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - try { - const pkpSessionSigs = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - const privateKey = ethers.Wallet.createRandom().privateKey; - - const { pkpAddress, id } = await importPrivateKey({ - pkpSessionSigs, - privateKey, - litNodeClient: devEnv.litNodeClient, - publicKey: '0xdeadbeef', - keyType: 'K256', - memo: 'Test key', - }); - - const alicePkpAddress = alice.authMethodOwnedPkp.ethAddress; - if (pkpAddress !== alicePkpAddress) { - throw new Error( - `Received address: ${pkpAddress} doesn't match Alice's PKP address: ${alicePkpAddress}` - ); - } - - const pkpSessionSigsSigning = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - // console.log(pkpSessionSigsSigning); - - const unsignedStringMessage = 'This is a test message'; - - const signature = await signMessageWithEncryptedKey({ - pkpSessionSigs: pkpSessionSigsSigning, - network: 'evm', - messageToSign: unsignedStringMessage, - litNodeClient: devEnv.litNodeClient, - id, - }); - - // console.log('signature'); - // console.log(signature); - - if (!ethers.utils.isHexString(signature)) { - throw new Error(`signature isn't hex: ${signature}`); - } - - const unsignedBinaryMessage = ethers.utils.arrayify( - ethers.utils.toUtf8Bytes(unsignedStringMessage) - ); - - const signatureBinary = await signMessageWithEncryptedKey({ - pkpSessionSigs: pkpSessionSigsSigning, - network: 'evm', - messageToSign: unsignedBinaryMessage, - litNodeClient: devEnv.litNodeClient, - id, - }); - - // console.log('signatureBinary'); - // console.log(signatureBinary); - - if (!ethers.utils.isHexString(signatureBinary)) { - throw new Error(`signatureBinary isn't hex: ${signatureBinary}`); - } - - if (signatureBinary !== signature) { - throw new Error( - `signature: ${signature} doesn't match it's signatureBinary form: ${signatureBinary}` - ); - } - - log('βœ… testEthereumSignMessageWrappedKey'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/wrapped-keys/testEthereumSignTransactionWrappedKey.ts b/local-tests/tests/wrapped-keys/testEthereumSignTransactionWrappedKey.ts deleted file mode 100644 index a4b1ace84b..0000000000 --- a/local-tests/tests/wrapped-keys/testEthereumSignTransactionWrappedKey.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { log } from '@lit-protocol/misc'; -import { ethers } from 'ethers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { api } from '@lit-protocol/wrapped-keys'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; - -import type { EthereumLitTransaction } from '@lit-protocol/wrapped-keys'; -import { getBaseTransactionForNetwork } from './util'; - -const { importPrivateKey, signTransactionWithEncryptedKey } = api; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testEthereumSignTransactionWrappedKey - * βœ… NETWORK=manzano yarn test:local --filter=testEthereumSignTransactionWrappedKey - * βœ… NETWORK=localchain yarn test:local --filter=testEthereumSignTransactionWrappedKey - */ -export const testEthereumSignTransactionWrappedKey = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - try { - const pkpSessionSigs = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - const privateKey = ethers.Wallet.createRandom().privateKey; - - const { pkpAddress, id } = await importPrivateKey({ - pkpSessionSigs, - privateKey, - litNodeClient: devEnv.litNodeClient, - publicKey: '0xdeadbeef', - keyType: 'K256', - memo: 'Test key', - }); - - const alicePkpAddress = alice.authMethodOwnedPkp.ethAddress; - if (pkpAddress !== alicePkpAddress) { - throw new Error( - `Received address: ${pkpAddress} doesn't match Alice's PKP address: ${alicePkpAddress}` - ); - } - - const pkpSessionSigsSigning = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - // console.log(pkpSessionSigsSigning); - - const unsignedTransaction = getBaseTransactionForNetwork({ - network: devEnv.litNodeClient.config.litNetwork, - toAddress: alice.wallet.address, - }); - - const signedTx = await signTransactionWithEncryptedKey({ - pkpSessionSigs: pkpSessionSigsSigning, - network: 'evm', - unsignedTransaction, - broadcast: false, - litNodeClient: devEnv.litNodeClient, - id, - }); - - // console.log('signedTx'); - // console.log(signedTx); - - if (!ethers.utils.isHexString(signedTx)) { - throw new Error(`signedTx isn't hex: ${signedTx}`); - } - - log('βœ… testEthereumSignTransactionWrappedKey'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/wrapped-keys/testExportWrappedKey.ts b/local-tests/tests/wrapped-keys/testExportWrappedKey.ts deleted file mode 100644 index da390f1eda..0000000000 --- a/local-tests/tests/wrapped-keys/testExportWrappedKey.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { log } from '@lit-protocol/misc'; -import { TinnyEnvironment } from '../../setup/tinny-environment'; -import { api } from '@lit-protocol/wrapped-keys'; -import { getPkpSessionSigs } from '../../setup/session-sigs/get-pkp-session-sigs'; -import { randomSolanaPrivateKey } from '../../setup/tinny-utils'; - -const { exportPrivateKey, importPrivateKey } = api; -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testExportWrappedKey - * βœ… NETWORK=manzano yarn test:local --filter=testExportWrappedKey - * βœ… NETWORK=localchain yarn test:local --filter=testExportWrappedKey - */ -export const testExportWrappedKey = async (devEnv: TinnyEnvironment) => { - const alice = await devEnv.createRandomPerson(); - - try { - const pkpSessionSigsImport = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - // console.log(pkpSessionSigsImport); - - const privateKey = randomSolanaPrivateKey(); - - const { pkpAddress, id } = await importPrivateKey({ - pkpSessionSigs: pkpSessionSigsImport, - privateKey, - litNodeClient: devEnv.litNodeClient, - publicKey: '0xdeadbeef', - keyType: 'K256', - memo: 'Test key', - }); - - const alicePkpAddress = alice.authMethodOwnedPkp.ethAddress; - if (pkpAddress !== alicePkpAddress) { - throw new Error( - `Received address: ${pkpAddress} doesn't match Alice's PKP address: ${alicePkpAddress}` - ); - } - - const pkpSessionSigsExport = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - // console.log(pkpSessionSigsExport); - - const { decryptedPrivateKey } = await exportPrivateKey({ - pkpSessionSigs: pkpSessionSigsExport, - litNodeClient: devEnv.litNodeClient, - network: 'solana', - id, - }); - - if (decryptedPrivateKey !== privateKey) { - throw new Error( - `Decrypted private key: ${decryptedPrivateKey} doesn't match with the original private key: ${privateKey}` - ); - } - - log('βœ… testExportWrappedKey'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyInvalidDecryption.ts b/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyInvalidDecryption.ts deleted file mode 100644 index 0595610d54..0000000000 --- a/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyInvalidDecryption.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { log } from '@lit-protocol/misc'; -import { ethers } from 'ethers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { encryptString } from '@lit-protocol/encryption'; -import { LIT_PREFIX } from 'packages/wrapped-keys/src/lib/constants'; -import { LIT_ACTION_CID_REPOSITORY } from '../../../packages/wrapped-keys/src/lib/lit-actions-client/constants'; -import { getBaseTransactionForNetwork } from './util'; -import { GLOBAL_OVERWRITE_IPFS_CODE_BY_NETWORK } from '@lit-protocol/constants'; -import { getPkpAccessControlCondition } from '../../../packages/wrapped-keys/src/lib/api/utils'; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyInvalidDecryption - * βœ… NETWORK=manzano yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyInvalidDecryption - * βœ… NETWORK=localchain yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyInvalidDecryption - */ -export const testFailEthereumSignTransactionWrappedKeyInvalidDecryption = - async (devEnv: TinnyEnvironment) => { - const alice = await devEnv.createRandomPerson(); - const bob = await devEnv.createRandomPerson(); - - try { - const privateKey = ethers.Wallet.createRandom().privateKey; - const alicePkpAddress = alice.authMethodOwnedPkp.ethAddress; - const decryptionAccessControlCondition = - getPkpAccessControlCondition(alicePkpAddress); - const { ciphertext, dataToEncryptHash } = await encryptString( - { - accessControlConditions: [decryptionAccessControlCondition], - dataToEncrypt: LIT_PREFIX + privateKey, - }, - devEnv.litNodeClient - ); - - const pkpSessionSigsSigning = await getPkpSessionSigs( - devEnv, - bob, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - // console.log(pkpSessionSigsSigning); - - const unsignedTransaction = getBaseTransactionForNetwork({ - network: devEnv.litNodeClient.config.litNetwork, - toAddress: alice.wallet.address, - }); - - try { - const _res = await devEnv.litNodeClient.executeJs({ - sessionSigs: pkpSessionSigsSigning, - ipfsId: LIT_ACTION_CID_REPOSITORY.signTransaction.evm, - jsParams: { - ciphertext, - dataToEncryptHash, - unsignedTransaction, - accessControlConditions: [decryptionAccessControlCondition], - }, - ipfsOptions: { - overwriteCode: - GLOBAL_OVERWRITE_IPFS_CODE_BY_NETWORK[ - devEnv.litNodeClient.config.litNetwork - ], - }, - }); - } catch (e: any) { - if ( - e.message.includes( - 'There was an error getting the signing shares from the nodes' - ) - ) { - console.log('βœ… THIS IS EXPECTED: ', e); - console.log(e.message); - console.log( - 'βœ… testFailEthereumSignTransactionWrappedKeyInvalidDecryption is expected to have an error' - ); - } else { - throw e; - } - } - - log('βœ… testFailEthereumSignTransactionWrappedKeyInvalidDecryption'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - devEnv.releasePrivateKeyFromUser(bob); - } - }; diff --git a/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyWithInvalidParam.ts b/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyWithInvalidParam.ts deleted file mode 100644 index 8aaccca971..0000000000 --- a/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyWithInvalidParam.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { log } from '@lit-protocol/misc'; -import { ethers } from 'ethers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { api, EthereumLitTransaction } from '@lit-protocol/wrapped-keys'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { getBaseTransactionForNetwork } from './util'; - -const { importPrivateKey, signTransactionWithEncryptedKey } = api; -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyWithInvalidParam - * βœ… NETWORK=manzano yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyWithInvalidParam - * βœ… NETWORK=localchain yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyWithInvalidParam - */ -export const testFailEthereumSignTransactionWrappedKeyWithInvalidParam = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - try { - const pkpSessionSigs = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - const privateKey = ethers.Wallet.createRandom().privateKey; - - const { pkpAddress, id } = await importPrivateKey({ - pkpSessionSigs, - privateKey, - litNodeClient: devEnv.litNodeClient, - publicKey: '0xdeadbeef', - keyType: 'K256', - memo: 'Test key', - }); - - const alicePkpAddress = alice.authMethodOwnedPkp.ethAddress; - if (pkpAddress !== alicePkpAddress) { - throw new Error( - `Received address: ${pkpAddress} doesn't match Alice's PKP address: ${alicePkpAddress}` - ); - } - - const pkpSessionSigsSigning = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - // console.log(pkpSessionSigsSigning); - - const unsignedTransaction: EthereumLitTransaction = { - ...getBaseTransactionForNetwork({ - network: devEnv.litNodeClient.config.litNetwork, - toAddress: alice.wallet.address, - }), - dataHex: 'Test transaction from Alice to bob', - }; - - try { - const _res = await signTransactionWithEncryptedKey({ - pkpSessionSigs: pkpSessionSigsSigning, - network: 'evm', - unsignedTransaction, - broadcast: false, - litNodeClient: devEnv.litNodeClient, - id, - }); - } catch (e: any) { - if (e.message.includes('invalid hexlify value')) { - console.log('βœ… THIS IS EXPECTED: ', e); - console.log(e.message); - console.log( - 'βœ… testFailEthereumSignTransactionWrappedKeyWithInvalidParam is expected to have an error' - ); - } else { - console.log('ERROR', e.message); - throw e; - } - } - - log('βœ… testFailEthereumSignTransactionWrappedKeyWithInvalidParam'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyWithMissingParam.ts b/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyWithMissingParam.ts deleted file mode 100644 index f23c0d6910..0000000000 --- a/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyWithMissingParam.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { log } from '@lit-protocol/misc'; -import { ethers } from 'ethers'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { api } from '@lit-protocol/wrapped-keys'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { getChainForNetwork } from './util'; - -const { importPrivateKey, signTransactionWithEncryptedKey } = api; -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyWithMissingParam - * βœ… NETWORK=manzano yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyWithMissingParam - * βœ… NETWORK=localchain yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyWithMissingParam - */ -export const testFailEthereumSignTransactionWrappedKeyWithMissingParam = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - try { - const pkpSessionSigs = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - const privateKey = ethers.Wallet.createRandom().privateKey; - - const { pkpAddress, id } = await importPrivateKey({ - pkpSessionSigs, - privateKey, - litNodeClient: devEnv.litNodeClient, - publicKey: '0xdeadbeef', - keyType: 'K256', - memo: 'Test key', - }); - - const alicePkpAddress = alice.authMethodOwnedPkp.ethAddress; - if (pkpAddress !== alicePkpAddress) { - throw new Error( - `Received address: ${pkpAddress} doesn't match Alice's PKP address: ${alicePkpAddress}` - ); - } - - const pkpSessionSigsSigning = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - // console.log(pkpSessionSigsSigning); - - try { - const _res = await signTransactionWithEncryptedKey({ - pkpSessionSigs: pkpSessionSigsSigning, - network: 'evm', - unsignedTransaction: { - ...getChainForNetwork(devEnv.litNodeClient.config.litNetwork), - // @ts-expect-error This test is intentionally using the type incorrectly. - serializedTransaction: 'random-value', - }, - broadcast: false, - litNodeClient: devEnv.litNodeClient, - id, - }); - } catch (e: any) { - if (e.message.includes('Missing required field: toAddress')) { - console.log('βœ… THIS IS EXPECTED: ', e); - console.log(e.message); - console.log( - 'βœ… testFailEthereumSignTransactionWrappedKeyWithMissingParam is expected to have an error' - ); - } else { - throw e; - } - } - - log('βœ… testFailEthereumSignTransactionWrappedKeyWithMissingParam'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithEoaSessionSig.ts b/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithEoaSessionSig.ts deleted file mode 100644 index 831fc5f04b..0000000000 --- a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithEoaSessionSig.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { api } from '@lit-protocol/wrapped-keys'; -import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs'; -import { randomSolanaPrivateKey } from 'local-tests/setup/tinny-utils'; - -const { importPrivateKey } = api; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testFailImportWrappedKeysWithEoaSessionSig - * βœ… NETWORK=manzano yarn test:local --filter=testFailImportWrappedKeysWithEoaSessionSig - * βœ… NETWORK=localchain yarn test:local --filter=testFailImportWrappedKeysWithEoaSessionSig - */ -export const testFailImportWrappedKeysWithEoaSessionSig = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - try { - const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); - - // console.log(eoaSessionSigs); - - const privateKey = randomSolanaPrivateKey(); - - try { - await importPrivateKey({ - pkpSessionSigs: eoaSessionSigs, - privateKey, - litNodeClient: devEnv.litNodeClient, - publicKey: '0xdeadbeef', - keyType: 'K256', - memo: 'Test key', - }); - } catch (e: any) { - if (e.message.includes('SessionSig is not from a PKP')) { - console.log('βœ… THIS IS EXPECTED: ', e); - console.log(e.message); - console.log( - 'βœ… testFailImportWrappedKeysWithEoaSessionSig is expected to have an error' - ); - } else { - throw e; - } - } - - console.log('βœ… testFailImportWrappedKeysWithEoaSessionSig'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithExpiredSessionSig.ts b/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithExpiredSessionSig.ts deleted file mode 100644 index 67f5422ef5..0000000000 --- a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithExpiredSessionSig.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { api } from '@lit-protocol/wrapped-keys'; -import { randomSolanaPrivateKey } from 'local-tests/setup/tinny-utils'; -import { SessionSigsMap } from '@lit-protocol/types'; - -const { importPrivateKey } = api; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testFailImportWrappedKeysWithExpiredSessionSig - * βœ… NETWORK=manzano yarn test:local --filter=testFailImportWrappedKeysWithExpiredSessionSig - * βœ… NETWORK=localchain yarn test:local --filter=testFailImportWrappedKeysWithExpiredSessionSig - */ -export const testFailImportWrappedKeysWithExpiredSessionSig = async ( - devEnv: TinnyEnvironment -) => { - const pkpSessionSigs: SessionSigsMap = { - 'https://207.244.70.36:8474': { - sig: '1827d1c7b79c979ce76d0b9e130f6804dbf7c7838b6dfa41d4cadf690b9a8bec23321dde6cc573e8a592c395193074ade303d94f3c198d8f0017ca0aca91bd0f', - derivedVia: 'litSessionSignViaNacl', - signedMessage: `{"sessionKey":"4fd3d6ae41190cdd33a07bc5feb4a51b0c882474e6b51eb37cf799d6668eb44b","resourceAbilityRequests":[{"resource":{"resource":"*","resourcePrefix":"lit-pkp"},"ability":"pkp-signing"},{"resource":{"resource":"*","resourcePrefix":"lit-litaction"},"ability":"lit-action-execution"}],"capabilities":[{"sig":"{\\"ProofOfPossession\\":\\"8f060f34f55e996e8396c5036cb456dbf3b3cf79a6c9d2a9c036a27dae6be5cb286c0170c45404ce60d45ad5df384a030450f4eabe61af68d7267d2de035a1ff0697097b3b32413581d8550b198599b8ee5c29a78999c05f8806e33923705748\\"}","algo":"LIT_BLS","derivedVia":"lit.bls","signedMessage":"litprotocol.com wants you to sign in with your Ethereum account:\\n0xd1Af1AAC50aC837C873200D17b78664aFCde597C\\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:4fd3d6ae41190cdd33a07bc5feb4a51b0c882474e6b51eb37cf799d6668eb44b\\nVersion: 1\\nChain ID: 1\\nNonce: 0xa8b687976835989b8ac57e8e6cb17fa316cc9ef74ea6174a588f08b11571829c\\nIssued At: 2024-06-02T19:46:47Z\\nExpiration Time: 2024-06-03T19:47:14.907Z\\nResources:\\n- urn:recap:eyJhdHQiOnsibGl0LWxpdGFjdGlvbjovLyoiOnsiVGhyZXNob2xkL0V4ZWN1dGlvbiI6W3t9XX0sImxpdC1wa3A6Ly8qIjp7IlRocmVzaG9sZC9TaWduaW5nIjpbe31dfSwibGl0LXJlc29sdmVkYXV0aGNvbnRleHQ6Ly8qIjp7IkF1dGgvQXV0aCI6W3siYXV0aF9jb250ZXh0Ijp7ImFjdGlvbklwZnNJZHMiOltdLCJhdXRoTWV0aG9kQ29udGV4dHMiOlt7ImFwcElkIjoibGl0IiwiYXV0aE1ldGhvZFR5cGUiOjEsImV4cGlyYXRpb24iOjE3MTc0NDQwMjAsInVzZWRGb3JTaWduU2Vzc2lvbktleVJlcXVlc3QiOnRydWUsInVzZXJJZCI6IjB4MkY2ZjU4NzRhNGQyNTFlMzVDZDc4YjM1NzZDQTkwYkQyZjA1RmUwQiJ9XSwiYXV0aFNpZ0FkZHJlc3MiOm51bGwsImN1c3RvbUF1dGhSZXNvdXJjZSI6IiIsInJlc291cmNlcyI6W119fV19fSwicHJmIjpbXX0","address":"0xd1Af1AAC50aC837C873200D17b78664aFCde597C"}],"issuedAt":"2024-06-02T19:47:16.707Z","expiration":"2024-06-03T19:47:14.907Z","nodeAddress":"https://207.244.70.36:8474"}`, - address: - '4fd3d6ae41190cdd33a07bc5feb4a51b0c882474e6b51eb37cf799d6668eb44b', - algo: 'ed25519', - }, - 'https://207.244.70.36:8473': { - sig: '762b9849d2cc77d0c75aa354c3cce63abca008a9a07ec3efc69ee8a4954650c3362b8cb83cd3d63310ad98b446be5e68cb8193f9d486453b2df72188dc698d0e', - derivedVia: 'litSessionSignViaNacl', - signedMessage: `{"sessionKey":"4fd3d6ae41190cdd33a07bc5feb4a51b0c882474e6b51eb37cf799d6668eb44b","resourceAbilityRequests":[{"resource":{"resource":"*","resourcePrefix":"lit-pkp"},"ability":"pkp-signing"},{"resource":{"resource":"*","resourcePrefix":"lit-litaction"},"ability":"lit-action-execution"}],"capabilities":[{"sig":"{\\"ProofOfPossession\\":\\"8f060f34f55e996e8396c5036cb456dbf3b3cf79a6c9d2a9c036a27dae6be5cb286c0170c45404ce60d45ad5df384a030450f4eabe61af68d7267d2de035a1ff0697097b3b32413581d8550b198599b8ee5c29a78999c05f8806e33923705748\\"}","algo":"LIT_BLS","derivedVia":"lit.bls","signedMessage":"litprotocol.com wants you to sign in with your Ethereum account:\\n0xd1Af1AAC50aC837C873200D17b78664aFCde597C\\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:4fd3d6ae41190cdd33a07bc5feb4a51b0c882474e6b51eb37cf799d6668eb44b\\nVersion: 1\\nChain ID: 1\\nNonce: 0xa8b687976835989b8ac57e8e6cb17fa316cc9ef74ea6174a588f08b11571829c\\nIssued At: 2024-06-02T19:46:47Z\\nExpiration Time: 2024-06-03T19:47:14.907Z\\nResources:\\n- urn:recap:eyJhdHQiOnsibGl0LWxpdGFjdGlvbjovLyoiOnsiVGhyZXNob2xkL0V4ZWN1dGlvbiI6W3t9XX0sImxpdC1wa3A6Ly8qIjp7IlRocmVzaG9sZC9TaWduaW5nIjpbe31dfSwibGl0LXJlc29sdmVkYXV0aGNvbnRleHQ6Ly8qIjp7IkF1dGgvQXV0aCI6W3siYXV0aF9jb250ZXh0Ijp7ImFjdGlvbklwZnNJZHMiOltdLCJhdXRoTWV0aG9kQ29udGV4dHMiOlt7ImFwcElkIjoibGl0IiwiYXV0aE1ldGhvZFR5cGUiOjEsImV4cGlyYXRpb24iOjE3MTc0NDQwMjAsInVzZWRGb3JTaWduU2Vzc2lvbktleVJlcXVlc3QiOnRydWUsInVzZXJJZCI6IjB4MkY2ZjU4NzRhNGQyNTFlMzVDZDc4YjM1NzZDQTkwYkQyZjA1RmUwQiJ9XSwiYXV0aFNpZ0FkZHJlc3MiOm51bGwsImN1c3RvbUF1dGhSZXNvdXJjZSI6IiIsInJlc291cmNlcyI6W119fV19fSwicHJmIjpbXX0","address":"0xd1Af1AAC50aC837C873200D17b78664aFCde597C"}],"issuedAt":"2024-06-02T19:47:16.707Z","expiration":"2024-06-03T19:47:14.907Z","nodeAddress":"https://207.244.70.36:8473"}`, - address: - '4fd3d6ae41190cdd33a07bc5feb4a51b0c882474e6b51eb37cf799d6668eb44b', - algo: 'ed25519', - }, - 'https://207.244.70.36:8475': { - sig: '5e506dc973cc1540dcb3bd1de251afa687caf277cb5f3efe107339ecf4c25607d4bdf5d8c8910874519252e026a49cc66cea0b07bc5d38342c7cb2613decbe0a', - derivedVia: 'litSessionSignViaNacl', - signedMessage: `{"sessionKey":"4fd3d6ae41190cdd33a07bc5feb4a51b0c882474e6b51eb37cf799d6668eb44b","resourceAbilityRequests":[{"resource":{"resource":"*","resourcePrefix":"lit-pkp"},"ability":"pkp-signing"},{"resource":{"resource":"*","resourcePrefix":"lit-litaction"},"ability":"lit-action-execution"}],"capabilities":[{"sig":"{\\"ProofOfPossession\\":\\"8f060f34f55e996e8396c5036cb456dbf3b3cf79a6c9d2a9c036a27dae6be5cb286c0170c45404ce60d45ad5df384a030450f4eabe61af68d7267d2de035a1ff0697097b3b32413581d8550b198599b8ee5c29a78999c05f8806e33923705748\\"}","algo":"LIT_BLS","derivedVia":"lit.bls","signedMessage":"litprotocol.com wants you to sign in with your Ethereum account:\\n0xd1Af1AAC50aC837C873200D17b78664aFCde597C\\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:4fd3d6ae41190cdd33a07bc5feb4a51b0c882474e6b51eb37cf799d6668eb44b\\nVersion: 1\\nChain ID: 1\\nNonce: 0xa8b687976835989b8ac57e8e6cb17fa316cc9ef74ea6174a588f08b11571829c\\nIssued At: 2024-06-02T19:46:47Z\\nExpiration Time: 2024-06-03T19:47:14.907Z\\nResources:\\n- urn:recap:eyJhdHQiOnsibGl0LWxpdGFjdGlvbjovLyoiOnsiVGhyZXNob2xkL0V4ZWN1dGlvbiI6W3t9XX0sImxpdC1wa3A6Ly8qIjp7IlRocmVzaG9sZC9TaWduaW5nIjpbe31dfSwibGl0LXJlc29sdmVkYXV0aGNvbnRleHQ6Ly8qIjp7IkF1dGgvQXV0aCI6W3siYXV0aF9jb250ZXh0Ijp7ImFjdGlvbklwZnNJZHMiOltdLCJhdXRoTWV0aG9kQ29udGV4dHMiOlt7ImFwcElkIjoibGl0IiwiYXV0aE1ldGhvZFR5cGUiOjEsImV4cGlyYXRpb24iOjE3MTc0NDQwMjAsInVzZWRGb3JTaWduU2Vzc2lvbktleVJlcXVlc3QiOnRydWUsInVzZXJJZCI6IjB4MkY2ZjU4NzRhNGQyNTFlMzVDZDc4YjM1NzZDQTkwYkQyZjA1RmUwQiJ9XSwiYXV0aFNpZ0FkZHJlc3MiOm51bGwsImN1c3RvbUF1dGhSZXNvdXJjZSI6IiIsInJlc291cmNlcyI6W119fV19fSwicHJmIjpbXX0","address":"0xd1Af1AAC50aC837C873200D17b78664aFCde597C"}],"issuedAt":"2024-06-02T19:47:16.707Z","expiration":"2024-06-03T19:47:14.907Z","nodeAddress":"https://207.244.70.36:8475"}`, - address: - '4fd3d6ae41190cdd33a07bc5feb4a51b0c882474e6b51eb37cf799d6668eb44b', - algo: 'ed25519', - }, - }; - - try { - const privateKey = randomSolanaPrivateKey(); - - const res = await importPrivateKey({ - pkpSessionSigs, - privateKey, - litNodeClient: devEnv.litNodeClient, - publicKey: '0xdeadbeef', - keyType: 'K256', - memo: 'Test key', - }); - // console.log(res); - } catch (e: any) { - if (e.message.includes('Invalid sessionSig: Expired')) { - console.log('βœ… THIS IS EXPECTED: ', e); - console.log(e.message); - console.log( - 'βœ… testFailImportWrappedKeysWithExpiredSessionSig is expected to have an error' - ); - } else { - throw e; - } - } - - console.log('βœ… testFailImportWrappedKeysWithExpiredSessionSig'); -}; diff --git a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithInvalidSessionSig.ts b/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithInvalidSessionSig.ts deleted file mode 100644 index 78cc80a53b..0000000000 --- a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithInvalidSessionSig.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { api } from '@lit-protocol/wrapped-keys'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { randomSolanaPrivateKey } from 'local-tests/setup/tinny-utils'; -import { AuthSig, SessionSigsMap } from '@lit-protocol/types'; - -const { importPrivateKey } = api; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testFailImportWrappedKeysWithInvalidSessionSig - * βœ… NETWORK=manzano yarn test:local --filter=testFailImportWrappedKeysWithInvalidSessionSig - * βœ… NETWORK=localchain yarn test:local --filter=testFailImportWrappedKeysWithInvalidSessionSig - */ -export const testFailImportWrappedKeysWithInvalidSessionSig = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - try { - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - try { - const privateKey = randomSolanaPrivateKey(); - - await importPrivateKey({ - pkpSessionSigs: tamperPkpSessionSigs(pkpSessionSigs), - privateKey, - litNodeClient: devEnv.litNodeClient, - publicKey: '0xdeadbeef', - keyType: 'K256', - memo: 'Test key', - }); - } catch (e: any) { - if (e.message.includes('bad public key size')) { - console.log('βœ… THIS IS EXPECTED: ', e); - console.log(e.message); - console.log( - 'βœ… testFailImportWrappedKeysWithInvalidSessionSig is expected to have an error' - ); - } else { - throw e; - } - } - - console.log('βœ… testFailImportWrappedKeysWithInvalidSessionSig'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; - -const tamperPkpSessionSigs = ( - pkpSessionSig: SessionSigsMap -): SessionSigsMap => { - const tamperedPkpSessionSigs: SessionSigsMap = {}; - - for (const key in pkpSessionSig) { - if (pkpSessionSig.hasOwnProperty(key)) { - const authSig = pkpSessionSig[key]; - const updatedAuthSig: AuthSig = { - ...authSig, - address: authSig.address.slice(0, -1), - }; - tamperedPkpSessionSigs[key] = updatedAuthSig; - } - } - - // console.log(tamperedPkpSessionSigs); - - return tamperedPkpSessionSigs; -}; diff --git a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithMaxExpirySessionSig.ts b/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithMaxExpirySessionSig.ts deleted file mode 100644 index 55ab120c21..0000000000 --- a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithMaxExpirySessionSig.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { api } from '@lit-protocol/wrapped-keys'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { randomSolanaPrivateKey } from 'local-tests/setup/tinny-utils'; - -const { importPrivateKey } = api; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testFailImportWrappedKeysWithMaxExpirySessionSig - * βœ… NETWORK=manzano yarn test:local --filter=testFailImportWrappedKeysWithMaxExpirySessionSig - * βœ… NETWORK=localchain yarn test:local --filter=testFailImportWrappedKeysWithMaxExpirySessionSig - */ -export const testFailImportWrappedKeysWithMaxExpirySessionSig = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - try { - const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); - - try { - const privateKey = randomSolanaPrivateKey(); - - await importPrivateKey({ - pkpSessionSigs, - privateKey, - litNodeClient: devEnv.litNodeClient, - publicKey: '0xdeadbeef', - keyType: 'K256', - memo: 'Test key', - }); - } catch (e: any) { - if (e.message.includes('Expires too far in the future')) { - console.log('βœ… THIS IS EXPECTED: ', e); - console.log(e.message); - console.log( - 'βœ… testFailImportWrappedKeysWithMaxExpirySessionSig is expected to have an error' - ); - } else { - throw e; - } - } - - console.log('βœ… testFailImportWrappedKeysWithMaxExpirySessionSig'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithSamePrivateKey.ts b/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithSamePrivateKey.ts deleted file mode 100644 index 3c47591382..0000000000 --- a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithSamePrivateKey.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { api } from '@lit-protocol/wrapped-keys'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; - -const { importPrivateKey } = api; -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testFailImportWrappedKeysWithSamePrivateKey - * βœ… NETWORK=manzano yarn test:local --filter=testFailImportWrappedKeysWithSamePrivateKey - * βœ… NETWORK=localchain yarn test:local --filter=testFailImportWrappedKeysWithSamePrivateKey - */ -export const testFailImportWrappedKeysWithSamePrivateKey = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - try { - const pkpSessionSigs = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - const privateKey = - '4rXcTBAZVypFRGGER4TwSuGGxMvmRwvYA3jwuZfDY4YKX4VEbuUaPCWrZGSxujKknQCdN8UD9wMW8XYmT1BiLxmB'; // Already exists in the DB - - try { - await importPrivateKey({ - pkpSessionSigs, - privateKey, - litNodeClient: devEnv.litNodeClient, - publicKey: '0xdeadbeef', - keyType: 'K256', - memo: 'Test key', - }); - - await importPrivateKey({ - pkpSessionSigs, - privateKey, - litNodeClient: devEnv.litNodeClient, - publicKey: '0xdeadbeef', - keyType: 'K256', - memo: 'Test key', - }); - - throw new Error( - 'Expected an AlreadyExists error but the importPrivateKey succeeded!' - ); - } catch (e: any) { - if ( - e.message.includes( - 'There is already a wrapped key stored with the same dataToEncryptHash' - ) - ) { - console.log('βœ… THIS IS EXPECTED: ', e); - console.log(e.message); - console.log( - 'βœ… testFailImportWrappedKeysWithSamePrivateKey is expected to have an error' - ); - } else { - throw e; - } - } - - console.log('βœ… testFailImportWrappedKeysWithSamePrivateKey'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/wrapped-keys/testGenerateEthereumWrappedKey.ts b/local-tests/tests/wrapped-keys/testGenerateEthereumWrappedKey.ts deleted file mode 100644 index 214780fa10..0000000000 --- a/local-tests/tests/wrapped-keys/testGenerateEthereumWrappedKey.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { log } from '@lit-protocol/misc'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { api } from '@lit-protocol/wrapped-keys'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { ethers } from 'ethers'; -import { exportPrivateKey } from '../../../packages/wrapped-keys/src/lib/api'; - -const { generatePrivateKey } = api; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testGenerateEthereumWrappedKey - * βœ… NETWORK=manzano yarn test:local --filter=testGenerateEthereumWrappedKey - * βœ… NETWORK=localchain yarn test:local --filter=testGenerateEthereumWrappedKey - */ -export const testGenerateEthereumWrappedKey = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - try { - const pkpSessionSigs = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - const { pkpAddress, generatedPublicKey, id } = await generatePrivateKey({ - pkpSessionSigs, - network: 'evm', - litNodeClient: devEnv.litNodeClient, - memo: 'Test key', - }); - - const alicePkpAddress = alice.authMethodOwnedPkp.ethAddress; - if (pkpAddress !== alicePkpAddress) { - throw new Error( - `Received address: ${pkpAddress} doesn't match Alice's PKP address: ${alicePkpAddress}` - ); - } - - const pkpSessionSigsExport = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - // console.log(pkpSessionSigsExport); - - const { decryptedPrivateKey } = await exportPrivateKey({ - pkpSessionSigs: pkpSessionSigsExport, - litNodeClient: devEnv.litNodeClient, - network: 'evm', - id, - }); - - const wallet = new ethers.Wallet(decryptedPrivateKey); - const decryptedPublicKey = wallet.publicKey; - - if (decryptedPublicKey !== generatedPublicKey) { - throw new Error( - `Decrypted decryptedPublicKey: ${decryptedPublicKey} doesn't match with the original generatedPublicKey: ${generatedPublicKey}` - ); - } - - log('βœ… testGenerateEthereumWrappedKey'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/wrapped-keys/testGenerateSolanaWrappedKey.ts b/local-tests/tests/wrapped-keys/testGenerateSolanaWrappedKey.ts deleted file mode 100644 index 74bcae620d..0000000000 --- a/local-tests/tests/wrapped-keys/testGenerateSolanaWrappedKey.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { log } from '@lit-protocol/misc'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { api } from '@lit-protocol/wrapped-keys'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import nacl from 'tweetnacl'; -import bs58 from 'bs58'; -import { Keypair } from '@solana/web3.js'; - -const { generatePrivateKey, signMessageWithEncryptedKey, exportPrivateKey } = - api; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testGenerateSolanaWrappedKey - * βœ… NETWORK=manzano yarn test:local --filter=testGenerateSolanaWrappedKey - * βœ… NETWORK=localchain yarn test:local --filter=testGenerateSolanaWrappedKey - */ -export const testGenerateSolanaWrappedKey = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - try { - const pkpSessionSigs = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - const { pkpAddress, generatedPublicKey, id } = await generatePrivateKey({ - pkpSessionSigs, - network: 'solana', - litNodeClient: devEnv.litNodeClient, - memo: 'Test key', - }); - - console.log(`generatedPublicKey: ${generatedPublicKey}`); - - const alicePkpAddress = alice.authMethodOwnedPkp.ethAddress; - if (pkpAddress !== alicePkpAddress) { - throw new Error( - `Received address: ${pkpAddress} doesn't match Alice's PKP address: ${alicePkpAddress}` - ); - } - - const pkpSessionSigsSigning = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - // console.log(pkpSessionSigsSigning); - - const messageToSign = 'This is a test message'; - - const signature = await signMessageWithEncryptedKey({ - pkpSessionSigs: pkpSessionSigsSigning, - network: 'solana', - messageToSign, - litNodeClient: devEnv.litNodeClient, - id, - }); - - // console.log('signature'); - // console.log(signature); - - const signatureIsValidForPublicKey = nacl.sign.detached.verify( - Buffer.from(messageToSign), - bs58.decode(signature), - bs58.decode(generatedPublicKey) - ); - - if (!signatureIsValidForPublicKey) - throw new Error( - `signature: ${signature} doesn't validate for the Solana public key: ${generatedPublicKey}` - ); - - const pkpSessionSigsExport = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - const { decryptedPrivateKey } = await exportPrivateKey({ - pkpSessionSigs: pkpSessionSigsExport, - litNodeClient: devEnv.litNodeClient, - network: 'solana', - id, - }); - - const solanaKeyPair = Keypair.fromSecretKey( - Buffer.from(decryptedPrivateKey, 'hex') - ); - const decryptedPublicKey = solanaKeyPair.publicKey; - - if (decryptedPublicKey.toString() !== generatedPublicKey) { - throw new Error( - `Decrypted decryptedPublicKey: ${decryptedPublicKey} doesn't match with the original generatedPublicKey: ${generatedPublicKey}` - ); - } - - log('βœ… testGenerateSolanaWrappedKey'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/wrapped-keys/testImportWrappedKey.ts b/local-tests/tests/wrapped-keys/testImportWrappedKey.ts deleted file mode 100644 index 63a8054383..0000000000 --- a/local-tests/tests/wrapped-keys/testImportWrappedKey.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { log } from '@lit-protocol/misc'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { api } from '@lit-protocol/wrapped-keys'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { randomSolanaPrivateKey } from 'local-tests/setup/tinny-utils'; - -const { importPrivateKey, listEncryptedKeyMetadata } = api; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testImportWrappedKey - * βœ… NETWORK=manzano yarn test:local --filter=testImportWrappedKey - * βœ… NETWORK=localchain yarn test:local --filter=testImportWrappedKey - */ -export const testImportWrappedKey = async (devEnv: TinnyEnvironment) => { - const alice = await devEnv.createRandomPerson(); - - try { - const pkpSessionSigs = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - const privateKey = randomSolanaPrivateKey(); - // '4rXcTBAZVypFRGGER4TwSuGGxMvmRwvYA3jwuZfDY4YKX4VEbuUaPCWrZGSxujKknQCdN8UD9wMW8XYmT1BiLxmB'; - - const { pkpAddress, id } = await importPrivateKey({ - pkpSessionSigs, - privateKey, - litNodeClient: devEnv.litNodeClient, - publicKey: '0xdeadbeef', - keyType: 'K256', - memo: 'Test key', - }); - - const alicePkpAddress = alice.authMethodOwnedPkp.ethAddress; - if (pkpAddress !== alicePkpAddress) { - throw new Error( - `Received address: ${pkpAddress} doesn't match Alice's PKP address: ${alicePkpAddress}` - ); - } - - const keys = await listEncryptedKeyMetadata({ - pkpSessionSigs, - litNodeClient: devEnv.litNodeClient, - }); - - if (keys.length !== 1 || keys[0].id !== id) { - throw new Error( - 'Keys returned by `listPrivateKeyMetadata()` do not match expected result.' - ); - } - - log('βœ… testImportWrappedKey'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/wrapped-keys/testSignMessageWithSolanaEncryptedKey.ts b/local-tests/tests/wrapped-keys/testSignMessageWithSolanaEncryptedKey.ts deleted file mode 100644 index 485332c722..0000000000 --- a/local-tests/tests/wrapped-keys/testSignMessageWithSolanaEncryptedKey.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { log } from '@lit-protocol/misc'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { api } from '@lit-protocol/wrapped-keys'; -import { Keypair } from '@solana/web3.js'; -import bs58 from 'bs58'; -import nacl from 'tweetnacl'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; - -const { importPrivateKey, signMessageWithEncryptedKey } = api; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testSignMessageWithSolanaEncryptedKey - * βœ… NETWORK=manzano yarn test:local --filter=testSignMessageWithSolanaEncryptedKey - * βœ… NETWORK=localchain yarn test:local --filter=testSignMessageWithSolanaEncryptedKey - */ -export const testSignMessageWithSolanaEncryptedKey = async ( - devEnv: TinnyEnvironment -) => { - const alice = await devEnv.createRandomPerson(); - - try { - const pkpSessionSigs = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - const solanaKeypair = Keypair.generate(); - const privateKey = Buffer.from(solanaKeypair.secretKey).toString('hex'); - - const { pkpAddress, id } = await importPrivateKey({ - pkpSessionSigs, - privateKey, - litNodeClient: devEnv.litNodeClient, - publicKey: '0xdeadbeef', - keyType: 'K256', - memo: 'Test key', - }); - - const alicePkpAddress = alice.authMethodOwnedPkp.ethAddress; - if (pkpAddress !== alicePkpAddress) { - throw new Error( - `Received address: ${pkpAddress} doesn't match Alice's PKP address: ${alicePkpAddress}` - ); - } - - const pkpSessionSigsSigning = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - const messageToSign = 'This is a test message'; - - const signature = await signMessageWithEncryptedKey({ - pkpSessionSigs: pkpSessionSigsSigning, - network: 'solana', - messageToSign, - litNodeClient: devEnv.litNodeClient, - id, - }); - - console.log('signature'); - console.log(signature); - - const signatureIsValidForPublicKey = nacl.sign.detached.verify( - Buffer.from(messageToSign), - bs58.decode(signature), - solanaKeypair.publicKey.toBuffer() - ); - - if (!signatureIsValidForPublicKey) - throw new Error( - `signature: ${signature} doesn't validate for the Solana public key: ${solanaKeypair.publicKey.toString()}` - ); - - log('βœ… testSignMessageWithSolanaEncryptedKey'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/wrapped-keys/testSignTransactionWithSolanaEncryptedKey.ts b/local-tests/tests/wrapped-keys/testSignTransactionWithSolanaEncryptedKey.ts deleted file mode 100644 index 55f9bfa402..0000000000 --- a/local-tests/tests/wrapped-keys/testSignTransactionWithSolanaEncryptedKey.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { log } from '@lit-protocol/misc'; -import { TinnyEnvironment } from 'local-tests/setup/tinny-environment'; -import { SerializedTransaction, api } from '@lit-protocol/wrapped-keys'; -import { - Connection, - Keypair, - LAMPORTS_PER_SOL, - PublicKey, - SystemProgram, - Transaction, - clusterApiUrl, -} from '@solana/web3.js'; -import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs'; -import { ethers } from 'ethers'; - -const { importPrivateKey, signTransactionWithEncryptedKey } = api; - -/** - * Test Commands: - * βœ… NETWORK=cayenne yarn test:local --filter=testSignTransactionWithSolanaEncryptedKey - * βœ… NETWORK=manzano yarn test:local --filter=testSignTransactionWithSolanaEncryptedKey - * βœ… NETWORK=localchain yarn test:local --filter=testSignTransactionWithSolanaEncryptedKey - */ -export const testSignTransactionWithSolanaEncryptedKey = async ( - devEnv: TinnyEnvironment -) => { - /** - * The commented code tests the following. We're commenting it as Solana heavily rate limits its Air Dropping - * 1. Importing with the actual Solana publicKey - * 2. Requesting a Solana Airdrop on devnet - * 3. Setting broadcast as true so that the Lit Action returns the transaction signature which can be used to confirm the tx - * 4. Checking the status of the tx as well as confirming it - */ - const alice = await devEnv.createRandomPerson(); - - try { - const pkpSessionSigs = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - const solanaKeypair = Keypair.generate(); - const privateKey = Buffer.from(solanaKeypair.secretKey).toString('hex'); - // const publicKey = solanaKeypair.publicKey; - // console.log("publicKey"); - // console.log(publicKey); // https://explorer.solana.com/address/jnu7wE8XMWXDmghQuVUZUUtQ1HFRkn8mwoquVif3e8q?cluster=devnet - - const { pkpAddress, id } = await importPrivateKey({ - pkpSessionSigs, - privateKey, - litNodeClient: devEnv.litNodeClient, - publicKey: '0xdeadbeef', - // publicKey: publicKey.toBase58(), - keyType: 'K256', - memo: 'Test key', - }); - - const solanaConnection = new Connection( - clusterApiUrl('devnet'), - 'confirmed' - ); - - // Request Solana Airdrop - // const balance = await solanaConnection.getBalance(solanaKeypair.publicKey); - // console.log("balance- ", balance); // Should be 0, in fact if we get the balance right after the Air Drop it will also be 0 unless we wait. We're skipping the balance confirmation - // await solanaConnection.requestAirdrop(solanaKeypair.publicKey, 1000000000); - - const alicePkpAddress = alice.authMethodOwnedPkp.ethAddress; - if (pkpAddress !== alicePkpAddress) { - throw new Error( - `Received address: ${pkpAddress} doesn't match Alice's PKP address: ${alicePkpAddress}` - ); - } - - const pkpSessionSigsSigning = await getPkpSessionSigs( - devEnv, - alice, - null, - new Date(Date.now() + 1000 * 60 * 10).toISOString() - ); // 10 mins expiry - - const solanaTransaction = new Transaction(); - solanaTransaction.add( - SystemProgram.transfer({ - fromPubkey: solanaKeypair.publicKey, - toPubkey: new PublicKey(solanaKeypair.publicKey), - lamports: LAMPORTS_PER_SOL / 100, // Transfer 0.01 SOL - }) - ); - solanaTransaction.feePayer = solanaKeypair.publicKey; - - const { blockhash } = await solanaConnection.getLatestBlockhash(); - solanaTransaction.recentBlockhash = blockhash; - - const serializedTransaction = solanaTransaction - .serialize({ - requireAllSignatures: false, // should be false as we're not signing the message - verifySignatures: false, // should be false as we're not signing the message - }) - .toString('base64'); - - const unsignedTransaction: SerializedTransaction = { - serializedTransaction, - chain: 'devnet', - }; - - const signedTx = await signTransactionWithEncryptedKey({ - pkpSessionSigs: pkpSessionSigsSigning, - network: 'solana', - unsignedTransaction, - broadcast: false, - // broadcast: true, - litNodeClient: devEnv.litNodeClient, - id, - }); - - // The following Explorer link show that the imported Solana wallet was sent an Air Drop and then broadcasted a tx from within the Lit Action - // https://explorer.solana.com/address/jnu7wE8XMWXDmghQuVUZUUtQ1HFRkn8mwoquVif3e8q?cluster=devnet - - // Transaction Signature upon broadcast from `sendRawTransaction()`. We use this below to check the status of the tx and check whether it's confirmed. - // console.log(signedTx); // 5YEthLprbhk5Zwn47YU7qZW6qZEFFhJTEK37B53vLLzGNXis436SLk5vYD7QQK7LuERtKunuSuxdwTYkS48Bb1Vf - // const status = await solanaConnection.getSignatureStatus(signedTx); - // console.log(status); // { context: { apiVersion: '2.0.5', slot: 321490377 }, value: { confirmationStatus: 'confirmed', confirmations: 0, err: null, slot: 321490377, status: { Ok: null } } } - // const confirmation = await solanaConnection.confirmTransaction(signedTx); - // console.log(confirmation); // { context: { slot: 321490379 }, value: { err: null } } - - const signatureBuffer = Buffer.from(ethers.utils.base58.decode(signedTx)); - solanaTransaction.addSignature(solanaKeypair.publicKey, signatureBuffer); - - if (!solanaTransaction.verifySignatures()) { - throw new Error( - `Signature: ${signedTx} doesn't validate for the Solana transaction.` - ); - } - - log('βœ… testSignMessageWithSolanaEncryptedKey'); - } finally { - devEnv.releasePrivateKeyFromUser(alice); - } -}; diff --git a/local-tests/tests/wrapped-keys/util.ts b/local-tests/tests/wrapped-keys/util.ts deleted file mode 100644 index 4f3573fe33..0000000000 --- a/local-tests/tests/wrapped-keys/util.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { LIT_NETWORKS_KEYS } from '@lit-protocol/types'; -import { LIT_CHAINS } from '@lit-protocol/constants'; -import { ethers } from 'ethers'; -import { config } from '@lit-protocol/wrapped-keys'; -import { - litActionRepositoryCommon, - litActionRepository, -} from '@lit-protocol/wrapped-keys-lit-actions'; - -import type { - LitActionCodeRepository, - LitActionCodeRepositoryCommon, - EthereumLitTransaction, -} from '@lit-protocol/wrapped-keys'; - -const emptyLitActionRepositoryCommon: LitActionCodeRepositoryCommon = { - batchGenerateEncryptedKeys: '', -}; - -const emptyLitActionRepository: LitActionCodeRepository = { - signTransaction: { - evm: '', - solana: '', - }, - signMessage: { - evm: '', - solana: '', - }, - generateEncryptedKey: { - evm: '', - solana: '', - }, - exportPrivateKey: { - evm: '', - solana: '', - }, -}; - -export function resetLitActionsCode() { - config.setLitActionsCodeCommon(emptyLitActionRepositoryCommon); - config.setLitActionsCode(emptyLitActionRepository); -} - -export function setLitActionsCodeToLocal() { - config.setLitActionsCodeCommon(litActionRepositoryCommon); - config.setLitActionsCode(litActionRepository); -} - -export function getChainForNetwork(network: LIT_NETWORKS_KEYS): { - chain: string; - chainId: number; -} { - switch (network) { - case 'cayenne': - case 'habanero': - case 'manzano': - return { - chain: 'chronicleTestnet', - chainId: LIT_CHAINS['chronicleTestnet'].chainId, - }; - case 'datil-dev': - return { - chain: 'yellowstone', - chainId: LIT_CHAINS['yellowstone'].chainId, - }; - case 'datil-test': - return { - chain: 'yellowstone', - chainId: LIT_CHAINS['yellowstone'].chainId, - }; - case 'datil': - return { - chain: 'yellowstone', - chainId: LIT_CHAINS['yellowstone'].chainId, - }; - default: - throw new Error(`Cannot identify chain params for ${network}`); - } -} - -export function getGasParamsForNetwork(network: LIT_NETWORKS_KEYS): { - gasPrice?: string; - gasLimit: number; -} { - switch (network) { - case 'cayenne': - case 'habanero': - case 'manzano': - return { - gasPrice: '0.001', - gasLimit: 30000, - }; - case 'datil-dev': - return { gasLimit: 5000000 }; - case 'datil-test': - return { gasLimit: 5000000 }; - case 'datil': - return { gasLimit: 5000000 }; - default: - throw new Error(`Cannot identify chain params for ${network}`); - } -} - -export function getBaseTransactionForNetwork({ - toAddress, - network, -}: { - toAddress: string; - network: LIT_NETWORKS_KEYS; -}): EthereumLitTransaction { - return { - toAddress, - value: '0.0001', // in ethers (Lit tokens) - ...getChainForNetwork(network), - ...getGasParamsForNetwork(network), - dataHex: ethers.utils.hexlify( - ethers.utils.toUtf8Bytes('Test transaction from Alice to bob') - ), - }; -} diff --git a/nx.json b/nx.json index d51223447f..2c8d2cb6fa 100644 --- a/nx.json +++ b/nx.json @@ -64,5 +64,8 @@ "default": ["{projectRoot}/**/*", "sharedGlobals"], "sharedGlobals": [], "production": ["default", "!{projectRoot}/src/test-setup.[jt]s"] + }, + "release": { + "projects": ["!@lit-protocol/tinny", "!@lit-protocol/e2e-tests"] } } diff --git a/package.json b/package.json index 5eb612672f..7a0759cce8 100644 --- a/package.json +++ b/package.json @@ -15,9 +15,9 @@ "bundles": "yarn node ./esbuilder/lit-connect-modal/esbuild.js", "postBuild:mapDistFolderNameToPackageJson": "node ./tools/scripts/map-dist-folder-name-to-package-json.mjs", "postBuild:mapDepsToDist": "node tools/scripts/map-deps-to-dist.mjs packages dist @lit-protocol", - "test:ci": "nx affected --target=test --all --code-coverage", - "test:local": "node ./local-tests/build.mjs && dotenvx run --env-file=.env -- node ./local-tests/build/test.mjs", - "test:unit": "nx run-many --target=test", + "test:ci": "nx affected --target=test --exclude=e2e-tests", + "test:e2e": "nx run e2e-tests:test", + "test:unit": "nx run-many --target=test --exclude=e2e-tests", "test:unit:watch": "nx run-many --target=test --watch", "test:unit:bun": "bun ./tools/scripts/unit-test-with-bun.mjs", "publish:packages": "yarn node ./tools/scripts/pub.mjs --prod", @@ -123,7 +123,8 @@ "form-data": "^4.0.0", "inquirer": "^9.2.21", "ipfs-unixfs-importer": "12.0.1", - "jest": "27.5.1", + "jest": "29.7.0", + "jest-environment-node": "^29.7.0", "lerna": "^5.4.3", "live-server": "^1.2.2", "node-fetch": "^2.6.1", diff --git a/packages/core/src/lib/lit-core.ts b/packages/core/src/lib/lit-core.ts index 51b267c1a6..31d565c6f5 100644 --- a/packages/core/src/lib/lit-core.ts +++ b/packages/core/src/lib/lit-core.ts @@ -221,6 +221,7 @@ export class LitCore { // if the user wants to override the storage option explicitly we override. Object.defineProperty(globalThis, 'localStorage', { value: this.config.storageProvider?.provider, + configurable: true, }); } else if ( isNode() && diff --git a/packages/e2e-tests/.eslintrc.json b/packages/e2e-tests/.eslintrc.json new file mode 100644 index 0000000000..9d9c0db55b --- /dev/null +++ b/packages/e2e-tests/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/packages/e2e-tests/jest.config.ts b/packages/e2e-tests/jest.config.ts new file mode 100644 index 0000000000..23b7c8501a --- /dev/null +++ b/packages/e2e-tests/jest.config.ts @@ -0,0 +1,12 @@ +/* eslint-disable */ +export default { + displayName: 'e2e-tests', + preset: 'ts-jest', + transform: { + '^.+\\.ts$': 'ts-jest', + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../coverage/packages/e2e-tests', + setupFilesAfterEnv: ['../../jest.setup.js'], + testEnvironment: './setup.config.js', +}; diff --git a/packages/e2e-tests/package.json b/packages/e2e-tests/package.json new file mode 100644 index 0000000000..eb80481149 --- /dev/null +++ b/packages/e2e-tests/package.json @@ -0,0 +1,24 @@ +{ + "name": "@lit-protocol/e2e-tests", + "license": "MIT", + "homepage": "https://github.com/Lit-Protocol/js-sdk", + "repository": { + "type": "git", + "url": "https://github.com/LIT-Protocol/js-sdk" + }, + "keywords": [ + "library" + ], + "bugs": { + "url": "https://github.com/LIT-Protocol/js-sdk/issues" + }, + "type": "commonjs", + "gitHead": "0d7334c2c55f448e91fe32f29edc5db8f5e09e4b", + "tags": [ + "universal" + ], + "version": "6.10.0", + "private": true, + "main": "./dist/src/index.js", + "typings": "./dist/src/index.d.ts" +} diff --git a/packages/e2e-tests/project.json b/packages/e2e-tests/project.json new file mode 100644 index 0000000000..dad0e4f51b --- /dev/null +++ b/packages/e2e-tests/project.json @@ -0,0 +1,45 @@ +{ + "name": "e2e-tests", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "packages/e2e-tests/src", + "projectType": "library", + "targets": { + "build": { + "executor": "@nx/js:tsc", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/packages/e2e-tests", + "main": "packages/e2e-tests/src/index.ts", + "tsConfig": "packages/e2e-tests/tsconfig.lib.json", + "assets": ["packages/e2e-tests/*.md"], + "updateBuildableProjectDepsInPackageJson": true + } + }, + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["packages/e2e-tests/**/*.ts"] + } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/packages/e2e-tests"], + "options": { + "jestConfig": "packages/e2e-tests/jest.config.ts", + "passWithNoTests": true, + "runInBand": false + } + }, + "testWatch": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/packages/e2e-tests"], + "options": { + "jestConfig": "packages/e2e-tests/jest.config.ts", + "passWithNoTests": true, + "watch": true + } + } + }, + "tags": ["scope:e2e-tests"] +} diff --git a/packages/e2e-tests/setup.config.js b/packages/e2e-tests/setup.config.js new file mode 100644 index 0000000000..c5bbf01387 --- /dev/null +++ b/packages/e2e-tests/setup.config.js @@ -0,0 +1,39 @@ +/** + * Jest Node Env docs: https://jestjs.io/docs/configuration#testenvironment-string + * Global setup file for jest e2e tests + * Loads all global context and provides to each test runner as needed + * env loading has been moved into + */ + +const NodeEnvironment = require('jest-environment-node').TestEnvironment; + +const TinnyEnvironment = require('@lit-protocol/tinny').TinnyEnvironment; + +require('dotenv').config(); +console.log('loaded configuration from .env', __dirname); + +class CustomEnvironment extends NodeEnvironment { + _hasLoadedTinny = false; + constructor(config) { + super(config); + } + + async setup() { + await super.setup(); + if (!this._hasLoadedTinny) { + this.global.devEnv = new TinnyEnvironment(); + await this.global.devEnv.init(); + this._hasLoadedTinny = true; + } + } + + async teardown() { + await super.teardown(); + } + + runScript(script) { + return super.runScript(script); + } +} + +module.exports = CustomEnvironment; diff --git a/packages/e2e-tests/src/tests/Delegation.spec.ts b/packages/e2e-tests/src/tests/Delegation.spec.ts new file mode 100644 index 0000000000..55710912e2 --- /dev/null +++ b/packages/e2e-tests/src/tests/Delegation.spec.ts @@ -0,0 +1,227 @@ +/* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */ +import { expect, jest } from '@jest/globals'; + +import { + LitAbility, + LitActionResource, + LitPKPResource, +} from '@lit-protocol/auth-helpers'; +import { AuthMethodScope, AuthMethodType } from '@lit-protocol/constants'; +import { + TinnyEnvironment, + TinnyPerson, + getEoaSessionSigsWithCapacityDelegations, +} from '@lit-protocol/tinny'; + +describe('Delegation', () => { + let devEnv: TinnyEnvironment; + let alice: TinnyPerson; + let bob: TinnyPerson; + + beforeAll(async () => { + //@ts-expect-error is defined + devEnv = global.devEnv; + alice = await devEnv.createRandomPerson(); + bob = await devEnv.createRandomPerson(); + }); + + afterEach(() => { + devEnv.releasePrivateKeyFromUser(alice); + devEnv.releasePrivateKeyFromUser(bob); + }); + + beforeEach(() => { + jest.spyOn(console, 'warn').mockImplementation(jest.fn()); + }); + + afterAll(async () => { + await devEnv.litNodeClient?.disconnect(); + }); + + it('PKP to PKP delegation executeJS', async () => { + // Checking the scopes of the PKP owned by Bob + const bobsAuthMethodAuthId = await LitAuthClient.getAuthIdByAuthMethod( + bob.authMethod + ); + + const scopes = + await bob.contractsClient?.pkpPermissionsContract.read.getPermittedAuthMethodScopes( + // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain + bob.authMethodOwnedPkp?.tokenId!, + AuthMethodType.EthWallet, + bobsAuthMethodAuthId, + 3 + ); + + if (!scopes![AuthMethodScope.SignAnything]) { + throw new Error('Bob does not have the "SignAnything" scope on his PKP'); + } + + // As a dApp owner, create a capacity delegation authSig for Bob's PKP wallet + const capacityDelegationAuthSig = + // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain + await alice.createCapacityDelegationAuthSig([bob.pkp?.ethAddress!]); + + // As a dApp owner, delegate the capacity credits NFT to Bob + const bobPkpSessionSigs = await devEnv.litNodeClient?.getPkpSessionSigs({ + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain + pkpPublicKey: bob.authMethodOwnedPkp?.publicKey!, + authMethods: [bob.authMethod!], + resourceAbilityRequests: [ + { + resource: new LitPKPResource('*'), + ability: LitAbility.PKPSigning, + }, + { + resource: new LitActionResource('*'), + ability: LitAbility.LitActionExecution, + }, + ], + capabilityAuthSigs: [capacityDelegationAuthSig], + }); + + const res = await devEnv.litNodeClient?.executeJs({ + sessionSigs: bobPkpSessionSigs!, + code: `(async () => { + const sigShare = await LitActions.signEcdsa({ + toSign: dataToSign, + publicKey, + sigName: "sig", + }); + })();`, + jsParams: { + dataToSign: alice.loveLetter, + publicKey: bob.authMethodOwnedPkp?.publicKey, + }, + }); + + // -- Expected output: + // { + // claims: {}, + // signatures: { + // sig: { + // r: "00fdf6f2fc3f13410393939bb678c8ec26c0eb46bfc39dbecdcf58540b7f9237", + // s: "480b578c78137150db2420669c47b220001b42a0bb4e92194ce7b76f6fd78ddc", + // recid: 0, + // signature: "0x00fdf6f2fc3f13410393939bb678c8ec26c0eb46bfc39dbecdcf58540b7f9237480b578c78137150db2420669c47b220001b42a0bb4e92194ce7b76f6fd78ddc1b", + // publicKey: "0465BFEE5CCFF60C0AF1D9B9481B680C2E34894A88F68F44CC094BA27501FD062A3C4AC61FA850BFA22D81D41AF72CBF983909501440FE51187F5FB3D1BC55C44E", + // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", + // }, + // }, + // decryptions: [], + // response: undefined, + // logs: "", + // } + + // -- assertions + expect(res?.signatures?.sig.r).toBeDefined(); + expect(res?.signatures?.sig.s).toBeDefined(); + expect(res?.signatures?.sig.dataSigned).toBeDefined(); + expect(res?.signatures?.sig.publicKey).toBeDefined(); + + // -- signatures.sig.signature must start with 0x + expect(res?.signatures.sig.signature.startsWith('0x')).toBe(true); + }); + + it('PKP to EOA ExecuteJs', async () => { + const appOwnersCapacityDelegationAuthSig = + await alice.createCapacityDelegationAuthSig([bob.wallet.address]); + + // 4. Bob receives the capacity delegation authSig use it to generate session sigs + const bobsSessionSigs = await getEoaSessionSigsWithCapacityDelegations( + devEnv, + bob.wallet, + appOwnersCapacityDelegationAuthSig + ); + + // 5. Bob can now execute JS code using the capacity credits NFT + const res = await devEnv.litNodeClient?.executeJs({ + sessionSigs: bobsSessionSigs!, + code: `(async () => { + const sigShare = await LitActions.signEcdsa({ + toSign: dataToSign, + publicKey, + sigName: "sig", + }); + })();`, + jsParams: { + dataToSign: alice.loveLetter, + publicKey: bob.pkp?.publicKey, + }, + }); + + // Expected output: + // { + // claims: {}, + // signatures: { + // sig: { + // r: "0f4b8b20369a8a021aae7c2083076715820e32d2b18826ea7ccea525a9adadc2", + // s: "43aa338fa2c90e13c88d9b432d7ee6c8e3df006b8ef94ad5b4ab32d64b507f17", + // recid: 1, + // signature: "0x0f4b8b20369a8a021aae7c2083076715820e32d2b18826ea7ccea525a9adadc243aa338fa2c90e13c88d9b432d7ee6c8e3df006b8ef94ad5b4ab32d64b507f171c", + // publicKey: "0406A76D2A6E3E729A537640C8C41592BBC2675799CCBBF310CD410691C028C529C5A8DE8016933CEC0B06EC7AA0FFAFBA2791158A11D382C558376DF392F436AD", + // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", + // }, + // }, + // decryptions: [], + // response: undefined, + // logs: "", + // } + + // -- assertions + expect(res?.signatures?.sig.r).toBeDefined(); + expect(res?.signatures?.sig.s).toBeDefined(); + expect(res?.signatures?.sig.dataSigned).toBeDefined(); + expect(res?.signatures?.sig.publicKey).toBeDefined(); + + // -- signatures.sig.signature must start with 0x + expect(res?.signatures.sig.signature.startsWith('0x')).toBe(true); + + // -- signatures.sig.recid must be parseable as a number + expect(isNaN(res?.signatures.sig.recid)).toBeTruthy(); + }); + + it('PKP to EOA PKP Sign', async () => { + const appOwnersCapacityDelegationAuthSig = + await alice.createCapacityDelegationAuthSig([bob.wallet.address]); + + // 4. Bob receives the capacity delegation authSig use it to generate session sigs + const bobsSessionSigs = await getEoaSessionSigsWithCapacityDelegations( + devEnv, + bob.wallet, + appOwnersCapacityDelegationAuthSig + ); + + // 5. Bob can now execute JS code using the capacity credits NFT + const res = await devEnv.litNodeClient?.pkpSign({ + sessionSigs: bobsSessionSigs!, + toSign: alice.loveLetter, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain + pubKey: bob.pkp?.publicKey!, + }); + + // Expected output: + // { + // r: "0f4b8b20369a8a021aae7c2083076715820e32d2b18826ea7ccea525a9adadc2", + // s: "43aa338fa2c90e13c88d9b432d7ee6c8e3df006b8ef94ad5b4ab32d64b507f17", + // recid: 1, + // signature: "0x0f4b8b20369a8a021aae7c2083076715820e32d2b18826ea7ccea525a9adadc243aa338fa2c90e13c88d9b432d7ee6c8e3df006b8ef94ad5b4ab32d64b507f171c", + // publicKey: "0406A76D2A6E3E729A537640C8C41592BBC2675799CCBBF310CD410691C028C529C5A8DE8016933CEC0B06EC7AA0FFAFBA2791158A11D382C558376DF392F436AD", + // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", + // }, + // + // } + + // -- assertions + expect(res?.r).toBeDefined(); + expect(res?.s).toBeDefined(); + expect(res?.dataSigned).toBeDefined(); + expect(res?.publicKey).toBeDefined(); + + // -- signatures.sig.signature must start with 0x + expect(res?.signature.startsWith('0x')).toBeDefined(); + + // -- signatures.sig.recid must be parseable as a number + expect(isNaN(res?.recid!)).toBeTruthy(); + }); +}); diff --git a/packages/e2e-tests/src/tests/PKPEthers.spec.ts b/packages/e2e-tests/src/tests/PKPEthers.spec.ts new file mode 100644 index 0000000000..f3d664cbe7 --- /dev/null +++ b/packages/e2e-tests/src/tests/PKPEthers.spec.ts @@ -0,0 +1,813 @@ +import { expect, jest } from '@jest/globals'; +import { + MessageTypes, + SignTypedDataVersion, + TypedMessage, + recoverTypedSignature, +} from '@metamask/eth-sig-util'; +import { ethers } from 'ethers'; + +import { + createSiweMessageWithRecaps, + generateAuthSig, + LitAbility, + LitActionResource, + LitPKPResource, +} from '@lit-protocol/auth-helpers'; +import { LitNodeClient } from '@lit-protocol/lit-node-client'; +import { PKPEthersWallet, ethRequestHandler } from '@lit-protocol/pkp-ethers'; +import { + TinnyEnvironment, + getEoaSessionSigs, + TinnyPerson, + getLitActionSessionSigs, + getLitActionSessionSigsUsingIpfsId, +} from '@lit-protocol/tinny'; +import { + AuthCallbackParams, + AuthSig, + LitResourceAbilityRequest, + SessionSigsMap, +} from '@lit-protocol/types'; + +try { + jest.setTimeout(100_000); +} catch (e) { + // ... continue execution +} + +describe('PKP Ethers', () => { + let devEnv: TinnyEnvironment; + let alice: TinnyPerson; + beforeAll(async () => { + //@ts-expect-error defined in global + devEnv = global.devEnv; + }); + + beforeEach(async () => { + alice = await devEnv.createRandomPerson(); + }); + + afterEach(() => { + alice && devEnv.releasePrivateKeyFromUser(alice); + }); + + beforeEach(() => { + jest.spyOn(console, 'warn').mockImplementation(jest.fn()); + }); + + afterAll(async () => { + await devEnv.litNodeClient?.disconnect(); + }); + + describe('Sign Message', () => { + it('LitAction Session', async () => { + await signMessage(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await signMessage(devEnv, alice, getLitActionSessionSigsUsingIpfsId); + }); + + it('EOA Wallet', async () => { + await signMessage(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await signMessage(devEnv, alice, getEoaSessionSigs); + }); + }); + + describe('ETH Signing', () => { + it('LitAction Session', async () => { + await ethTransaction(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await ethTransaction(devEnv, alice, getLitActionSessionSigsUsingIpfsId); + }); + + it('EOA Wallet', async () => { + await ethTransaction(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await ethTransaction(devEnv, alice, getEoaSessionSigs); + }); + }); + + describe('ETH Personal Signing', () => { + it('LitAction Session', async () => { + await ethPersonalSign(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await ethPersonalSign(devEnv, alice, getLitActionSessionSigsUsingIpfsId); + }); + + it('EOA Wallet', async () => { + await ethPersonalSign(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await ethPersonalSign(devEnv, alice, getEoaSessionSigs); + }); + }); + + describe('Sign Transaction', () => { + it('LitAction Session', async () => { + await signTransaction(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await signTransaction(devEnv, alice, getLitActionSessionSigsUsingIpfsId); + }); + + it('EOA Wallet', async () => { + await signTransaction(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await signTransaction(devEnv, alice, getEoaSessionSigs); + }); + }); + + describe('Eth Sign Typed Data', () => { + it('LitAction Session', async () => { + await signTypedDataV1(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await signTypedDataV1(devEnv, alice, getLitActionSessionSigsUsingIpfsId); + }); + + it('EOA Wallet', async () => { + await signTypedDataV1(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await signTypedDataV1(devEnv, alice, getEoaSessionSigs); + }); + }); + + describe('Sign Typed Data Util', () => { + it('LitAction Session', async () => { + await ethTypedDataUtil(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await ethTypedDataUtil(devEnv, alice, getLitActionSessionSigsUsingIpfsId); + }); + + it('EOA Wallet', async () => { + await ethTypedDataUtil(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await ethTypedDataUtil(devEnv, alice, getEoaSessionSigs); + }); + }); + + describe('SignedTypedDataV1', () => { + it('LitAction Session', async () => { + await signTypedDataV1(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await signTypedDataV1(devEnv, alice, getLitActionSessionSigsUsingIpfsId); + }); + + it('EOA Wallet', async () => { + await signTypedDataV1(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await signTypedDataV1(devEnv, alice, getEoaSessionSigs); + }); + }); + + describe('SignedTypedDatav3', () => { + it('LitAction Session', async () => { + await signTypedDatav3(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await signTypedDatav3(devEnv, alice, getLitActionSessionSigsUsingIpfsId); + }); + + it('EOA Wallet', async () => { + await signTypedDatav3(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await signTypedDatav3(devEnv, alice, getEoaSessionSigs); + }); + }); + + describe('Signed Typed Data v4', () => { + it('LitAction Session', async () => { + await signTypedDatav4(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await signTypedDatav4(devEnv, alice, getLitActionSessionSigsUsingIpfsId); + }); + + it('EOA Wallet', async () => { + await signTypedDatav4(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await signTypedDatav4(devEnv, alice, getEoaSessionSigs); + }); + }); + + describe('Sign With AuthContext', () => { + it('LitAction Session', async () => { + await signWithAuthContext(devEnv, alice); + }); + + it('LitAction IPFS Session', async () => { + await signWithAuthContext(devEnv, alice); + }); + + it('EOA Wallet', async () => { + await signWithAuthContext(devEnv, alice); + }); + + it('PKP Session', async () => { + await signWithAuthContext(devEnv, alice); + }); + }); +}); + +const signMessage = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson, + generator: ( + devEnv: TinnyEnvironment, + person: TinnyPerson, + resources?: LitResourceAbilityRequest[] + ) => Promise +): Promise => { + const eoaSessionSigs = await generator(devEnv, alice); + + const pkpEthersWallet = new PKPEthersWallet({ + litNodeClient: devEnv.litNodeClient!, + pkpPubKey: alice.pkp?.publicKey as string, + controllerSessionSigs: eoaSessionSigs, + }); + + await pkpEthersWallet.init(); + + expect( + pkpEthersWallet.signMessage(alice.loveLetter) + ).resolves.not.toThrowError(); +}; + +const ethTransaction = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson, + generator: ( + devEnv: TinnyEnvironment, + person: TinnyPerson, + resources?: LitResourceAbilityRequest[] + ) => Promise +): Promise => { + const eoaSessionSigs = await generator(devEnv, alice); + + const pkpEthersWallet = new PKPEthersWallet({ + litNodeClient: devEnv.litNodeClient!, + pkpPubKey: alice.pkp?.publicKey as string, + controllerSessionSigs: eoaSessionSigs, + }); + + await pkpEthersWallet.init(); + + // Message to sign + const message = 'Hello world'; + const hexMsg = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(message)); + + // DATA, 20 Bytes - address + // DATA, N Bytes - message to sign + // Reference: https://ethereum.github.io/execution-apis/api-documentation/#eth_sign + expect( + ethRequestHandler({ + signer: pkpEthersWallet, + payload: { + method: 'eth_sign', + params: [alice.pkp?.ethAddress, hexMsg], + }, + }).then((signature: string) => { + const recoveredAddr = ethers.utils.verifyMessage(message, signature); + expect(signature.length).toEqual(132); + expect(recoveredAddr).toEqual(alice.pkp?.ethAddress); + }) + ).resolves.not.toThrowError(); +}; + +const signTransaction = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson, + generator: ( + devEnv: TinnyEnvironment, + person: TinnyPerson, + resources?: LitResourceAbilityRequest[] + ) => Promise +): Promise => { + const eoaSessionSigs = await generator(devEnv, alice); + + const pkpEthersWallet = new PKPEthersWallet({ + litNodeClient: devEnv?.litNodeClient as LitNodeClient, + pkpPubKey: alice.pkp?.publicKey as string, + controllerSessionSigs: eoaSessionSigs, + }); + + await pkpEthersWallet.init(); + + // -- eth_sendTransaction parameters + + // Transaction to sign and send + const from = alice.pkp?.ethAddress as string; + const to = alice.pkp?.ethAddress; + const gasLimit = ethers.BigNumber.from('21000'); + const value = ethers.BigNumber.from('0'); + const data = '0x'; + + // pkp-ethers signer will automatically add missing fields (nonce, chainId, gasPrice, gasLimit) + const tx = { + from: from, + to: to, + gasLimit, + value, + data, + }; + + // eth_sendTransaction parameters + // Transaction - Object + // Reference: https://ethereum.github.io/execution-apis/api-documentation/#eth_sendTransaction + // A serialized form of the whole transaction + ethRequestHandler({ + signer: pkpEthersWallet, + payload: { + method: 'eth_signTransaction', + params: [tx], + }, + }).then((rawSignedTx: string) => { + const parsedTransaction = ethers.utils.parseTransaction(rawSignedTx); + + const signature = ethers.utils.joinSignature({ + r: parsedTransaction.r!, + s: parsedTransaction.s!, + v: parsedTransaction.v!, + }); + + const rawTx = { + nonce: parsedTransaction.nonce, + gasPrice: parsedTransaction.gasPrice, + gasLimit: parsedTransaction.gasLimit, + to: parsedTransaction.to, + value: parsedTransaction.value, + data: parsedTransaction.data, + chainId: parsedTransaction.chainId, // Include chainId if the transaction is EIP-155 + }; + + const txHash = ethers.utils.keccak256( + ethers.utils.serializeTransaction(rawTx) + ); + + const { v, r, s } = parsedTransaction; + + const recoveredAddress = ethers.utils.recoverAddress(txHash, { + r: r!, + s: s!, + v: v!, + }); + + // ==================== Post-Validation ==================== + expect(parsedTransaction).toBeDefined(); + + expect(signature.length).toEqual(132); + + expect(recoveredAddress.toLowerCase()).toEqual( + alice.pkp?.ethAddress.toLowerCase() + ); + }); +}; + +const ethTypedDataUtil = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson, + generator: ( + devEnv: TinnyEnvironment, + person: TinnyPerson, + resources?: LitResourceAbilityRequest[] + ) => Promise +): Promise => { + const eoaSessionSigs = await generator(devEnv, alice); + + const pkpEthersWallet = new PKPEthersWallet({ + litNodeClient: devEnv?.litNodeClient as LitNodeClient, + pkpPubKey: alice.pkp?.publicKey as string, + controllerSessionSigs: eoaSessionSigs, + }); + + await pkpEthersWallet.init(); + + // Example from https://github.com/MetaMask/test-dapp/blob/main/src/index.js#L1033 + const msgParams = { + types: { + EIP712Domain: [ + { name: 'name', type: 'string' }, + { name: 'version', type: 'string' }, + { name: 'chainId', type: 'uint256' }, + { name: 'verifyingContract', type: 'address' }, + ], + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + primaryType: 'Mail', + domain: { + name: 'Ether Mail', + version: '1', + chainId: 80001, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', + }, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + }; + + expect( + ethRequestHandler({ + signer: pkpEthersWallet, + payload: { + method: 'eth_signTypedData', + params: [alice?.pkp?.ethAddress, JSON.stringify(msgParams)], + }, + }).then((signature: string) => { + // https://docs.ethers.io/v5/api/utils/signing-key/#utils-verifyTypedData + const recoveredAddr = ethers.utils.verifyTypedData( + msgParams.domain, + { Person: msgParams.types.Person, Mail: msgParams.types.Mail }, + msgParams.message, + signature + ); + + expect(signature.length).toEqual(132); + + expect(recoveredAddr.toLowerCase()).toEqual( + alice.pkp?.ethAddress.toLowerCase() + ); + }) + ).resolves; +}; + +const signTypedDataV1 = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson, + generator: ( + devEnv: TinnyEnvironment, + person: TinnyPerson, + resources?: LitResourceAbilityRequest[] + ) => Promise +): Promise => { + const eoaSessionSigs = await generator(devEnv, alice); + + const pkpEthersWallet = new PKPEthersWallet({ + litNodeClient: devEnv?.litNodeClient as LitNodeClient, + pkpPubKey: alice.pkp?.publicKey as string, + controllerSessionSigs: eoaSessionSigs, + }); + + await pkpEthersWallet.init(); + + // -- eth_signTypedData_v1 parameters + const msgParams = [ + { + type: 'string', + name: 'Message', + value: 'Hi, Alice!', + }, + { + type: 'uint32', + name: 'A number', + value: '1337', + }, + ]; + + expect( + ethRequestHandler({ + signer: pkpEthersWallet, + payload: { + method: 'eth_signTypedData_v1', + params: [msgParams, alice.pkp?.ethAddress], + }, + }).then((signature: string) => { + const recoveredAddr = recoverTypedSignature({ + data: msgParams, + signature: signature, + version: SignTypedDataVersion.V1, + }); + + // ==================== Post-Validation ==================== + if (signature.length !== 132) { + throw new Error('❌ signature should be 132 characters long'); + } + + expect(recoveredAddr.toLowerCase()).toEqual( + alice.pkp?.ethAddress.toLowerCase() + ); + }) + ).resolves.not.toThrowError(); +}; + +const signTypedDatav3 = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson, + generator: ( + devEnv: TinnyEnvironment, + person: TinnyPerson, + resources?: LitResourceAbilityRequest[] + ) => Promise +): Promise => { + const eoaSessionSigs = await generator(devEnv, alice); + + const pkpEthersWallet = new PKPEthersWallet({ + litNodeClient: devEnv.litNodeClient as LitNodeClient, + pkpPubKey: alice.pkp?.publicKey as string, + controllerSessionSigs: eoaSessionSigs, + }); + + await pkpEthersWallet.init(); + + // -- eth_signTypedData_v3 parameters + + const msgParams = { + types: { + EIP712Domain: [ + { name: 'name', type: 'string' }, + { name: 'version', type: 'string' }, + { name: 'chainId', type: 'uint256' }, + { name: 'verifyingContract', type: 'address' }, + ], + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + primaryType: 'Mail', + domain: { + name: 'Ether Mail', + version: '1', + chainId: 80001, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', + }, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + }; + + expect( + ethRequestHandler({ + signer: pkpEthersWallet, + payload: { + method: 'eth_signTypedData_v3', + params: [alice.pkp?.ethAddress, JSON.stringify(msgParams)], + }, + }).then((signature: string) => { + const recoveredAddr = recoverTypedSignature({ + data: { + types: msgParams.types, + domain: msgParams.domain, + primaryType: msgParams.primaryType as 'Mail', + message: msgParams.message, + }, + signature: signature, + version: SignTypedDataVersion.V3, + }); + + expect(signature.length).toEqual(132); + + expect(recoveredAddr.toLowerCase()).toEqual( + alice.pkp?.ethAddress.toLowerCase() + ); + }) + ).resolves; +}; + +const signTypedDatav4 = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson, + generator: ( + devEnv: TinnyEnvironment, + person: TinnyPerson, + resources?: LitResourceAbilityRequest[] + ) => Promise +): Promise => { + const eoaSessionSigs = await generator(devEnv, alice); + + const pkpEthersWallet = new PKPEthersWallet({ + litNodeClient: devEnv.litNodeClient as LitNodeClient, + pkpPubKey: alice.pkp?.publicKey as string, + controllerSessionSigs: eoaSessionSigs, + }); + + await pkpEthersWallet.init(); + + // -- eth_signTypedData_v3 parameters + + const msgParams = { + domain: { + chainId: 80001, + name: 'Ether Mail', + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', + version: '1', + }, + message: { + contents: 'Hello, Bob!', + from: { + name: 'Cow', + wallets: [ + '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF', + ], + }, + to: [ + { + name: 'Bob', + wallets: [ + '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + '0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57', + '0xB0B0b0b0b0b0B000000000000000000000000000', + ], + }, + ], + }, + primaryType: 'Mail', + types: { + EIP712Domain: [ + { name: 'name', type: 'string' }, + { name: 'version', type: 'string' }, + { name: 'chainId', type: 'uint256' }, + { name: 'verifyingContract', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person[]' }, + { name: 'contents', type: 'string' }, + ], + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallets', type: 'address[]' }, + ], + }, + }; + + expect( + ethRequestHandler({ + signer: pkpEthersWallet, + payload: { + method: 'eth_signTypedData_v4', + params: [alice.pkp?.ethAddress, JSON.stringify(msgParams)], + }, + }).then((signature: string) => { + const recoveredAddr = recoverTypedSignature({ + data: msgParams as TypedMessage, + signature: signature, + version: SignTypedDataVersion.V4, + }); + + expect(signature.length).toEqual(132); + + expect(recoveredAddr.toLowerCase()).toEqual( + alice.pkp?.ethAddress.toLowerCase() + ); + }) + ).resolves.not.toThrow(); +}; + +const signWithAuthContext = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson +): Promise => { + const pkpEthersWallet = new PKPEthersWallet({ + pkpPubKey: alice.pkp?.publicKey as string, + litNodeClient: devEnv.litNodeClient as LitNodeClient, + authContext: { + getSessionSigsProps: { + authNeededCallback: async function ( + params: AuthCallbackParams + ): Promise { + const toSign = await createSiweMessageWithRecaps({ + uri: params.uri!, + expiration: params.expiration!, + resources: params.resourceAbilityRequests!, + walletAddress: alice.wallet.address, + nonce: (await devEnv.litNodeClient?.getLatestBlockhash()) as string, + litNodeClient: devEnv.litNodeClient, + }); + + const authSig = await generateAuthSig({ + signer: alice.wallet, + toSign, + }); + + return authSig; + }, + resourceAbilityRequests: [ + { + resource: new LitPKPResource('*'), + ability: LitAbility.PKPSigning, + }, + { + resource: new LitActionResource('*'), + ability: LitAbility.LitActionExecution, + }, + ], + }, + }, + }); + + await pkpEthersWallet.init(); + + expect( + pkpEthersWallet.signMessage(alice.loveLetter).then((signature) => { + expect(signature).toBeDefined(); + expect(signature.length).toEqual(132); + }) + ).resolves.not.toThrowError(); +}; + +const ethPersonalSign = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson, + generator: ( + devEnv: TinnyEnvironment, + person: TinnyPerson, + resources?: LitResourceAbilityRequest[] + ) => Promise +): Promise => { + const pkpSessionSigs = await generator(devEnv, alice); + + const pkpEthersWallet = new PKPEthersWallet({ + litNodeClient: devEnv.litNodeClient as LitNodeClient, + pkpPubKey: alice.pkp?.publicKey as string, + controllerSessionSigs: pkpSessionSigs, + }); + + await pkpEthersWallet.init(); + + // -- personal_sign parameters + + // Message to sign + const message = 'Free the web'; + const hexMsg = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(message)); + + // personal_sign parameters + // DATA, N Bytes - message to sign. + // DATA, 20 Bytes - address + // Reference: https://metamask.github.io/api-playground/api-documentation/#personal_sign + expect( + ethRequestHandler({ + signer: pkpEthersWallet, + payload: { + method: 'personal_sign', + params: [hexMsg, alice.pkp?.ethAddress], + }, + }).then((signature: string) => { + const recoveredAddr = ethers.utils.verifyMessage(message, signature); + + expect(signature.length).toEqual(132); + expect(recoveredAddr).toEqual(alice.pkp?.ethAddress); + }) + ).resolves.not.toThrowError(); +}; diff --git a/packages/e2e-tests/src/tests/Relayer.spec.ts b/packages/e2e-tests/src/tests/Relayer.spec.ts new file mode 100644 index 0000000000..237a5a12db --- /dev/null +++ b/packages/e2e-tests/src/tests/Relayer.spec.ts @@ -0,0 +1,50 @@ +import { ProviderType } from '@lit-protocol/constants'; +import { + EthWalletProvider, + LitAuthClient, +} from '@lit-protocol/lit-auth-client'; +import { TinnyEnvironment } from '@lit-protocol/tinny'; + +try { + jest.setTimeout(100_000); +} catch (e) { + // ... continue execution +} + +describe('Relayer', () => { + let devEnv: TinnyEnvironment; + beforeAll(async () => { + //@ts-expect-error global defined + devEnv = global.devEnv; + }); + + beforeEach(() => { + jest.spyOn(console, 'warn').mockImplementation(jest.fn()); + }); + + afterAll(async () => { + await devEnv.litNodeClient?.disconnect(); + }); + + it('Fetch PKPS', async () => { + const alice = await devEnv.createRandomPerson(); + + const litAuthClient = new LitAuthClient({ + litRelayConfig: { + relayApiKey: 'test-api-key', + }, + litNodeClient: devEnv.litNodeClient, + }); + + // -- test fetch pkps + const ethWalletProvider = litAuthClient.initProvider( + ProviderType.EthWallet + ); + + const pkps = await ethWalletProvider.fetchPKPsThroughRelayer( + alice.authMethod! + ); + + expect(pkps.length).toBeGreaterThan(0); + }); +}); diff --git a/packages/e2e-tests/src/tests/SOLAuthSig.spec.ts b/packages/e2e-tests/src/tests/SOLAuthSig.spec.ts new file mode 100644 index 0000000000..0c78e2113a --- /dev/null +++ b/packages/e2e-tests/src/tests/SOLAuthSig.spec.ts @@ -0,0 +1,77 @@ +import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs'; +import { + TinnyEnvironment, + AccessControlConditions, + TinnyPerson, +} from '@lit-protocol/tinny'; +import { ILitNodeClient } from '@lit-protocol/types'; + +try { + jest.setTimeout(100_000); +} catch (e) { + // ... continue execution +} + +describe('Sol AuthSig', () => { + let devEnv: TinnyEnvironment; + let alice: TinnyPerson; + beforeAll(async () => { + //@ts-expect-error defined in global + devEnv = global.devEnv; + }); + + beforeEach(async () => { + alice = await devEnv.createRandomPerson(); + }); + + afterEach(() => { + alice && devEnv.releasePrivateKeyFromUser(alice); + }); + + beforeEach(() => { + jest.spyOn(console, 'warn').mockImplementation(jest.fn()); + }); + + afterAll(async () => { + await devEnv.litNodeClient?.disconnect(); + }); + + it('DecryptString', async () => { + const accs = AccessControlConditions.getSolBasicAccessControlConditions({ + userAddress: devEnv.bareSolAuthSig?.address, + }); + + const encryptRes = await LitJsSdk.encryptString( + { + solRpcConditions: accs, + dataToEncrypt: 'Hello world', + }, + devEnv.litNodeClient as unknown as ILitNodeClient + ); + + // -- Expected output:Β΄ + // { + // ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D", + // dataToEncryptHash: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c", + // } + + // -- assertions + expect(encryptRes.ciphertext).toBeDefined(); + + expect(encryptRes.dataToEncryptHash).toBeDefined(); + + // -- Decrypt the encrypted string + const decryptRes = await LitJsSdk.decryptToString( + { + solRpcConditions: accs, + ciphertext: encryptRes.ciphertext, + dataToEncryptHash: encryptRes.dataToEncryptHash, + authSig: devEnv.bareSolAuthSig, + chain: 'solana', + }, + devEnv.litNodeClient as unknown as ILitNodeClient + ); + + expect(decryptRes).toEqual('Hello world'); + }); +}); diff --git a/packages/e2e-tests/src/tests/SessionSigs.spec.ts b/packages/e2e-tests/src/tests/SessionSigs.spec.ts new file mode 100644 index 0000000000..8943e76204 --- /dev/null +++ b/packages/e2e-tests/src/tests/SessionSigs.spec.ts @@ -0,0 +1,782 @@ +import { expect, jest } from '@jest/globals'; + +import { + LitAbility, + LitAccessControlConditionResource, + LitActionResource, + LitPKPResource, +} from '@lit-protocol/auth-helpers'; +import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs'; +import { + LIT_TESTNET, + AccessControlConditions, + TinnyEnvironment, + TinnyPerson, + getLitActionSessionSigs, + getEoaSessionSigs, + getPkpSessionSigs, + getLitActionSessionSigsUsingIpfsId, +} from '@lit-protocol/tinny'; +import { + ILitNodeClient, + LitResourceAbilityRequest, + SessionSigsMap, +} from '@lit-protocol/types'; + +try { + jest.setTimeout(100_000); +} catch (e) { + // ... continue execution +} + +describe('SessionSigs', () => { + let devEnv: TinnyEnvironment; + let alice: TinnyPerson; + beforeAll(async () => { + //@ts-expect-error defined in global + devEnv = global.devEnv; + }); + + beforeEach(async () => { + alice = await devEnv.createRandomPerson(); + }); + + afterEach(() => { + alice && devEnv.releasePrivateKeyFromUser(alice); + }); + + beforeEach(() => { + jest.spyOn(console, 'warn').mockImplementation(jest.fn()); + }); + + afterAll(async () => { + await devEnv.litNodeClient?.disconnect(); + }); + + describe('DecryptString', () => { + it('LitAction Session', async () => { + await decryptString(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await decryptString(devEnv, alice, getLitActionSessionSigsUsingIpfsId); + }); + + it('EOA Wallet', async () => { + await decryptString(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await decryptString(devEnv, alice, getPkpSessionSigs); + }); + }); + + describe('Claim Key', () => { + if (devEnv && !devEnv.setUnavailable(LIT_TESTNET.MANZANO)) { + it('LitAction Session', async () => { + await executeJsClaimKey(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await executeJsClaimKey( + devEnv, + alice, + getLitActionSessionSigsUsingIpfsId + ); + }); + + it('EOA Wallet', async () => { + await executeJsClaimKey(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await executeJsClaimKey(devEnv, alice, getPkpSessionSigs); + }); + } + }); + + describe('Claim Key Multiple', () => { + if (devEnv && !devEnv.setUnavailable(LIT_TESTNET.MANZANO)) { + it('LitAction Session', async () => { + await executeJsClaimKeys(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await executeJsClaimKeys( + devEnv, + alice, + getLitActionSessionSigsUsingIpfsId + ); + }); + + it('EOA Wallet', async () => { + await executeJsClaimKeys(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await executeJsClaimKeys(devEnv, alice, getPkpSessionSigs); + }); + } + }); + + describe('ExecuteJS JSON Response', () => { + if (devEnv && !devEnv.setUnavailable(LIT_TESTNET.MANZANO)) { + it('LitAction Session', async () => { + await executeJsJSONResponse(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await executeJsJSONResponse( + devEnv, + alice, + getLitActionSessionSigsUsingIpfsId + ); + }); + + it('EOA Wallet', async () => { + await executeJsJSONResponse(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await executeJsJSONResponse(devEnv, alice, getPkpSessionSigs); + }); + } + }); + + describe('PKP Sign', () => { + if (devEnv && !devEnv.setUnavailable(LIT_TESTNET.MANZANO)) { + it('LitAction Session', async () => { + await pkpSign(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await pkpSign(devEnv, alice, getLitActionSessionSigsUsingIpfsId); + }); + + it('EOA Wallet', async () => { + await pkpSign(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await pkpSign(devEnv, alice, getPkpSessionSigs); + }); + } + }); + + describe('ExecuteJS Signing', () => { + if (devEnv && !devEnv.setUnavailable(LIT_TESTNET.MANZANO)) { + it('LitAction Session', async () => { + await executeJsSigning(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await executeJsSigning( + devEnv, + alice, + getLitActionSessionSigsUsingIpfsId + ); + }); + + it('EOA Wallet', async () => { + await executeJsSigning(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await executeJsSigning(devEnv, alice, getPkpSessionSigs); + }); + } + }); + + describe('ExecuteJS Signing Parallel', () => { + if (devEnv && !devEnv.setUnavailable(LIT_TESTNET.MANZANO)) { + it('LitAction Session', async () => { + await executeJsSigningParallel(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await executeJsSigningParallel( + devEnv, + alice, + getLitActionSessionSigsUsingIpfsId + ); + }); + + it('EOA Wallet', async () => { + await executeJsSigningParallel(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await executeJsSigningParallel(devEnv, alice, getPkpSessionSigs); + }); + } + }); + + describe('Broadcast And Collect', () => { + if (devEnv && !devEnv.setUnavailable(LIT_TESTNET.MANZANO)) { + it('LitAction Session', async () => { + await broadcastAndCollect(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await broadcastAndCollect( + devEnv, + alice, + getLitActionSessionSigsUsingIpfsId + ); + }); + + it('EOA Wallet', async () => { + await broadcastAndCollect(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await broadcastAndCollect(devEnv, alice, getPkpSessionSigs); + }); + } + }); + + describe('Decrypt And Combine', () => { + if (devEnv && !devEnv.setUnavailable(LIT_TESTNET.MANZANO)) { + it('LitAction Session', async () => { + await decryptAndCombine(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await decryptAndCombine( + devEnv, + alice, + getLitActionSessionSigsUsingIpfsId + ); + }); + + it('EOA Wallet', async () => { + await decryptAndCombine(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await decryptAndCombine(devEnv, alice, getPkpSessionSigs); + }); + } + }); + + describe('Sign And Combine ECDSA', () => { + if (devEnv && !devEnv.setUnavailable(LIT_TESTNET.MANZANO)) { + it('LitAction Session', async () => { + await signAndCombine(devEnv, alice, getLitActionSessionSigs); + }); + + it('LitAction IPFS Session', async () => { + await signAndCombine(devEnv, alice, getLitActionSessionSigsUsingIpfsId); + }); + + it('EOA Wallet', async () => { + await signAndCombine(devEnv, alice, getEoaSessionSigs); + }); + + it('PKP Session', async () => { + await signAndCombine(devEnv, alice, getPkpSessionSigs); + }); + } + }); +}); + +const executeJsClaimKeys = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson, + generator: ( + devEnv: TinnyEnvironment, + person: TinnyPerson, + resources?: LitResourceAbilityRequest[] + ) => Promise +): Promise => { + const litActionSessionSigs = await generator(devEnv, alice, [ + { + resource: new LitPKPResource('*'), + ability: LitAbility.PKPSigning, + }, + { + resource: new LitActionResource('*'), + ability: LitAbility.LitActionExecution, + }, + ]); + + const res = await devEnv.litNodeClient?.executeJs({ + sessionSigs: litActionSessionSigs!, + code: `(async () => { + Lit.Actions.claimKey({keyId: "foo"}); + Lit.Actions.claimKey({keyId: "bar"}); + })();`, + }); + + // Expected output: + // { + // claims: { + // bar: { + // signatures: [ + // { + // r: "0x7ee7b329462acb08d1dd1d3fba17f8ac76263454e2582bc0d5f36c74f4aaac68", + // s: "0x1b20cd8ac8ab1efdcf500d7ff100229deee42ce44b6420619c609a694af33aad", + // v: 28, + // }, { + // r: "0x2bd6db983d5f5dd239b4fe27b087acf0547e49a69e6c62b8e1435d3890a5d4c5", + // s: "0x15a8a80b2a5bf16e9c155bfe9d5da1109847334b8a0a74a9ce277cdfc6b05fdd", + // v: 28, + // }, { + // r: "0x9294c656bdb6764fca46e431dc4b15c653e6347a41eb657d23145d93a1fa19d0", + // s: "0x7afe0be470e9393dda32c356a9a262f7794a59f8e75e551bdb7634beb3a0a114", + // v: 28, + // } + // ], + // derivedKeyId: "0961c21c8a46c4992003a7b7af9449c15f772a269633ae3242f6ed146708a819", + // }, + // foo: { + // signatures: [ + // { + // r: "0xc39c073d69c8878bf06c813af9d090b41e15319abc9677e20f07085c96451e98", + // s: "0x6ef6a3d4b365119f4a9613a89fd57af01c4a350a20222935581be306b4c8aba4", + // v: 27, + // }, { + // r: "0xa2473911de4b252349cadde340de121ce3195929cd1ebb4c717f3d9d65c67988", + // s: "0x597a45d27a3100fa0bb144644f6bdec62c8a827f35427814cea64f8d3d9a9fa8", + // v: 27, + // }, { + // r: "0x97c393fb1f733b946bfaafdbb13c46192f4cf5ad2b2a9fcf9ff0355a7a2dc5fa", + // s: "0x152737c1b0aba904182bb5ac70e3a99ba4301b631df55bd21b91d705eb5ef4d2", + // v: 27, + // } + // ], + // derivedKeyId: "7698c828a5e4ae6dd6f98ae72fcb5a96bc83f53fa6a09c614e28ceab8198d5ca", + // }, + // }, + // signatures: {}, + // decryptions: [], + // response: undefined, + // logs: "", + // } + + // assertions + expect(res?.claims?.['foo']).toBeDefined(); + expect(res?.claims?.['foo']?.derivedKeyId).toBeDefined(); + + expect(res?.claims?.['foo'].signatures).toBeDefined(); + + res?.claims?.['foo'].signatures.forEach((sig) => { + expect(!sig.r).toBeDefined(); + expect(!sig.s).toBeDefined(); + expect(!sig.v).toBeDefined(); + }); + + expect(res?.claims?.['bar']).toBeDefined(); + expect(res?.claims?.['bar']?.derivedKeyId).toBeDefined(); + + expect(res?.claims?.['bar'].signatures).toBeDefined(); + + res?.claims?.['bar'].signatures.forEach((sig) => { + expect(!sig.r).toBeDefined(); + expect(!sig.s).toBeDefined(); + expect(!sig.v).toBeDefined(); + }); +}; + +const executeJsClaimKey = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson, + generator: ( + devEnv: TinnyEnvironment, + person: TinnyPerson, + resources?: LitResourceAbilityRequest[] + ) => Promise +): Promise => { + const litActionSessionSigs = await generator(devEnv, alice); + + const res = await devEnv.litNodeClient?.executeJs({ + sessionSigs: litActionSessionSigs!, + code: `(async () => { + Lit.Actions.claimKey({keyId: "foo"}); + })();`, + }); + + // Expected output: + // { + // claims: { + // bar: { + // signatures: [ + // { + // r: "0x7ee7b329462acb08d1dd1d3fba17f8ac76263454e2582bc0d5f36c74f4aaac68", + // s: "0x1b20cd8ac8ab1efdcf500d7ff100229deee42ce44b6420619c609a694af33aad", + // v: 28, + // }, { + // r: "0x2bd6db983d5f5dd239b4fe27b087acf0547e49a69e6c62b8e1435d3890a5d4c5", + // s: "0x15a8a80b2a5bf16e9c155bfe9d5da1109847334b8a0a74a9ce277cdfc6b05fdd", + // v: 28, + // }, { + // r: "0x9294c656bdb6764fca46e431dc4b15c653e6347a41eb657d23145d93a1fa19d0", + // s: "0x7afe0be470e9393dda32c356a9a262f7794a59f8e75e551bdb7634beb3a0a114", + // v: 28, + // } + // ], + // derivedKeyId: "0961c21c8a46c4992003a7b7af9449c15f772a269633ae3242f6ed146708a819", + // } + // }, + // signatures: {}, + // decryptions: [], + // response: undefined, + // logs: "", + // } + + expect(res?.claims?.['foo']).toBeDefined(); + expect(res?.claims?.['foo']?.derivedKeyId).toBeDefined(); + + expect(res?.claims?.['foo'].signatures).toBeDefined(); + + res?.claims?.['foo'].signatures.forEach((sig) => { + expect(!sig.r).toBeDefined(); + expect(!sig.s).toBeDefined(); + expect(!sig.v).toBeDefined(); + }); +}; + +const pkpSign = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson, + generator: ( + devEnv: TinnyEnvironment, + person: TinnyPerson, + resources?: LitResourceAbilityRequest[] + ) => Promise +): Promise => { + const litActionSessionSigs = await generator(devEnv, alice); + + const res = await devEnv.litNodeClient?.pkpSign({ + toSign: alice.loveLetter, + pubKey: alice.authMethodOwnedPkp?.publicKey as string, + sessionSigs: litActionSessionSigs as SessionSigsMap, + }); + + // -- Expected output: + // { + // r: "ab2cef959db920d56f001c3b05637ee49af4c4441f2867ea067c413594a4c87b", + // s: "4bf11e17b4bb618aa6ed75cbf0406e6babfd953c5b201da697077c5fbf5b542e", + // recid: 1, + // signature: "0xab2cef959db920d56f001c3b05637ee49af4c4441f2867ea067c413594a4c87b4bf11e17b4bb618aa6ed75cbf0406e6babfd953c5b201da697077c5fbf5b542e1c", + // publicKey: "04400AD53C2F8BA11EBC69F05D1076D5BEE4EAE668CD66BABADE2E0770F756FDEEFC2C1D20F9A698EA3FEC6E9C944FF9FAFC2DC339B8E9392AFB9CC8AE75C5E5EC", + // dataSigned: "7D87C5EA75F7378BB701E404C50639161AF3EFF66293E9F375B5F17EB50476F4", + // } + + expect(res?.r).toBeDefined(); + expect(res?.s).toBeDefined(); + expect(res?.dataSigned).toBeDefined(); + expect(res?.publicKey).toBeDefined(); +}; + +const executeJsJSONResponse = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson, + generator: ( + devEnv: TinnyEnvironment, + person: TinnyPerson, + resources?: LitResourceAbilityRequest[] + ) => Promise +): Promise => { + const litActionSessionSigs = await generator(devEnv, alice); + + const res = await devEnv.litNodeClient?.executeJs({ + sessionSigs: litActionSessionSigs!, + code: `(async () => { + console.log('hello world') + + LitActions.setResponse({ + response: JSON.stringify({hello: 'world'}) + }); + + })();`, + }); + + expect(res?.response).toBeDefined(); + expect(res?.logs).toBeDefined(); + expect(res?.logs.includes('hello world')).toBeTruthy(); + expect(res?.success).toBeTruthy(); +}; + +const executeJsSigning = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson, + generator: ( + devEnv: TinnyEnvironment, + person: TinnyPerson, + resources?: LitResourceAbilityRequest[] + ) => Promise +): Promise => { + const litActionSessionSigs = await generator(devEnv, alice, [ + { + resource: new LitPKPResource('*'), + ability: LitAbility.PKPSigning, + }, + { + resource: new LitActionResource('*'), + ability: LitAbility.LitActionExecution, + }, + ]); + + const res = await devEnv.litNodeClient?.executeJs({ + sessionSigs: litActionSessionSigs!, + code: `(async () => { + const sigShare = await LitActions.signEcdsa({ + toSign: dataToSign, + publicKey, + sigName: "sig", + }); + })();`, + jsParams: { + dataToSign: alice.loveLetter, + publicKey: alice.authMethodOwnedPkp?.publicKey, + }, + }); + + expect(res?.signatures?.sig.r).toBeDefined(); + expect(res?.signatures?.sig.s).toBeDefined(); + expect(res?.signatures?.sig.dataSigned).toBeDefined(); + expect(res?.signatures?.sig.publicKey).toBeDefined(); +}; + +const executeJsSigningParallel = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson, + generator: ( + devEnv: TinnyEnvironment, + person: TinnyPerson, + resources?: LitResourceAbilityRequest[] + ) => Promise +): Promise => { + const litActionSessionSigs = await generator(devEnv, alice); + + const fn = async () => { + return await devEnv.litNodeClient?.executeJs({ + sessionSigs: litActionSessionSigs!, + code: `(async () => { + const sigShare = await LitActions.signEcdsa({ + toSign: dataToSign, + publicKey, + sigName: "sig", + }); + })();`, + jsParams: { + dataToSign: alice.loveLetter, + publicKey: alice.authMethodOwnedPkp?.publicKey, + }, + }); + }; + + const res = await Promise.all([fn(), fn(), fn()]); + + res.forEach((r) => { + expect(r?.signatures?.sig.r).toBeDefined(); + expect(r?.signatures?.sig.s).toBeDefined(); + expect(r?.signatures?.sig.dataSigned).toBeDefined(); + expect(r?.signatures?.sig.publicKey).toBeDefined(); + }); +}; + +const decryptString = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson, + generator: ( + devEnv: TinnyEnvironment, + person: TinnyPerson, + resources?: LitResourceAbilityRequest[] + ) => Promise +): Promise => { + // set access control conditions for encrypting and decrypting + const accs = AccessControlConditions.getEmvBasicAccessControlConditions({ + userAddress: + generator.name === 'getEoaSessionSigs' + ? alice.wallet.address + : (alice.authMethodOwnedPkp?.ethAddress as string), + }); + + const encryptRes = await LitJsSdk.encryptString( + { + accessControlConditions: accs, + dataToEncrypt: 'Hello world', + }, + devEnv.litNodeClient as unknown as ILitNodeClient + ); + + // -- Expected output: + // { + // ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D", + // dataToEncryptHash: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c", + // } + + // -- assertions + expect(encryptRes.ciphertext).toBeDefined(); + + expect(encryptRes.dataToEncryptHash).toBeDefined(); + + const accsResourceString = + await LitAccessControlConditionResource.generateResourceString( + accs, + encryptRes.dataToEncryptHash + ); + + const litActionSessionSigs2 = await generator(devEnv, alice, [ + { + resource: new LitAccessControlConditionResource(accsResourceString), + ability: LitAbility.AccessControlConditionDecryption, + }, + ]); + + // -- Decrypt the encrypted string + const decryptRes = await LitJsSdk.decryptToString( + { + accessControlConditions: accs, + ciphertext: encryptRes.ciphertext, + dataToEncryptHash: encryptRes.dataToEncryptHash, + sessionSigs: litActionSessionSigs2, + chain: 'ethereum', + }, + devEnv.litNodeClient as unknown as ILitNodeClient + ); + + expect(decryptRes).toEqual('Hello world'); +}; + +const broadcastAndCollect = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson, + generator: ( + devEnv: TinnyEnvironment, + person: TinnyPerson, + resources?: LitResourceAbilityRequest[] + ) => Promise +) => { + const litActionSessionSigs = await generator(devEnv, alice); + + const res = await devEnv.litNodeClient?.executeJs({ + sessionSigs: litActionSessionSigs!, + code: `(async () => { + let rand = Math.floor(Math.random() * 100); + const resp = await Lit.Actions.broadcastAndCollect({ + name: "temperature", + value: rand.toString(), + }); + Lit.Actions.setResponse({ + response: JSON.stringify(resp) + }); + })();`, + jsParams: {}, + }); + + const response = res?.response; + expect(response).toBeDefined(); +}; + +const decryptAndCombine = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson, + generator: ( + devEnv: TinnyEnvironment, + person: TinnyPerson, + resources?: LitResourceAbilityRequest[] + ) => Promise +) => { + // set access control conditions for encrypting and decrypting + const accs = AccessControlConditions.getEmvBasicAccessControlConditions({ + userAddress: + generator.name === 'getEoaSessionSigs' + ? (alice.authSig?.address as string) + : (alice.authMethodOwnedPkp?.ethAddress as string), + }); + + const litActionSessionSigs = await generator(devEnv, alice); + + const encryptRes = await LitJsSdk.encryptString( + { + accessControlConditions: accs, + dataToEncrypt: 'Hello world', + }, + devEnv.litNodeClient as unknown as ILitNodeClient + ); + + // -- Expected output: + // { + // ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D", + // dataToEncryptHash: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c", + // } + + // -- assertions + expect(encryptRes.ciphertext).toBeDefined(); + + expect(!encryptRes.dataToEncryptHash).toBeDefined(); + + const res = await devEnv.litNodeClient?.executeJs({ + sessionSigs: litActionSessionSigs!, + code: `(async () => { + const resp = await Lit.Actions.decryptAndCombine({ + accessControlConditions, + ciphertext, + dataToEncryptHash, + authSig: null, + chain: 'ethereum', + }); + Lit.Actions.setResponse({ + response: resp + }); + })();`, + jsParams: { + accessControlConditions: accs, + dataToEncryptHash: encryptRes.dataToEncryptHash, + ciphertext: encryptRes.ciphertext, + }, + }); + + expect(res).toHaveProperty('response', 'Hello world'); +}; + +const signAndCombine = async ( + devEnv: TinnyEnvironment, + alice: TinnyPerson, + generator: ( + devEnv: TinnyEnvironment, + person: TinnyPerson, + resources?: LitResourceAbilityRequest[] + ) => Promise +) => { + const litActionSessionSigs = await generator(devEnv, alice); + + const res = await devEnv.litNodeClient?.executeJs({ + sessionSigs: litActionSessionSigs!, + code: `(async () => { + const sigShare = await LitActions.signAndCombineEcdsa({ + toSign: dataToSign, + publicKey, + sigName: "sig", + }); + Lit.Actions.setResponse({ + response: sigShare + }); + })();`, + jsParams: { + dataToSign: alice.loveLetter, + publicKey: alice.pkp?.publicKey, + }, + }); + + /** + Response format + { + "success": true, + "signedData": {}, + "decryptedData": {}, + "claimData": {}, + "response": "{\"r\":\"026eede14267ca76064a7e22dbe6f9e44d786c7b5917b7d023f45ee4e84ce1ea47\",\"s\":\"22a6048bcb88d724d45bdb6161fefd151483f41d592d167e5c33f42e9fe6dac6\",\"v\":0}", + "logs": "" + } + */ + + expect(res?.response).toBeDefined(); + const sig = JSON.parse(res?.response as string); + expect(sig.r).toBeDefined(); + expect(sig.s).toBeDefined(); + expect(sig.v).toBeDefined(); +}; diff --git a/packages/e2e-tests/src/tests/WrappedKeys.spec.ts b/packages/e2e-tests/src/tests/WrappedKeys.spec.ts new file mode 100644 index 0000000000..90f7c258b0 --- /dev/null +++ b/packages/e2e-tests/src/tests/WrappedKeys.spec.ts @@ -0,0 +1,1124 @@ +import { expect, jest } from '@jest/globals'; +import { + Connection, + Keypair, + LAMPORTS_PER_SOL, + PublicKey, + SystemProgram, + Transaction, + clusterApiUrl, +} from '@solana/web3.js'; +import bs58 from 'bs58'; +import { ethers } from 'ethers'; +import nacl from 'tweetnacl'; + +import { LIT_CHAINS } from '@lit-protocol/constants'; +import { encryptString } from '@lit-protocol/encryption'; +import { + TinnyEnvironment, + getPkpSessionSigs, + getEoaSessionSigs, + TinnyPerson, +} from '@lit-protocol/tinny'; +import { + AuthSig, + ILitNodeClient, + LIT_NETWORKS_KEYS, + SessionSigsMap, +} from '@lit-protocol/types'; +import { + EthereumLitTransaction, + SerializedTransaction, + api, +} from '@lit-protocol/wrapped-keys'; +// Using absolute pathing as these members are not exported from the module +import { getPkpAccessControlCondition } from '@lit-protocol/wrapped-keys/src/lib/api/utils'; +import { LIT_PREFIX } from '@lit-protocol/wrapped-keys/src/lib/constants'; +import { LIT_ACTION_CID_REPOSITORY } from '@lit-protocol/wrapped-keys/src/lib/lit-actions-client/constants'; + +const { + importPrivateKey, + signTransactionWithEncryptedKey, + signMessageWithEncryptedKey, + generatePrivateKey, + exportPrivateKey, +} = api; + +/** + * Helper migrated from tinny utils due to an issue with root level dependency resolve + * Migration is acceptible due to aggreagation of test casses into a snigle file context. + * @returns {string} + */ +export function randomSolanaPrivateKey() { + const BASE58_ALPHABET = + '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; + const SOLANA_PRIVATE_KEY_LENGTH = 88; + + let result = ''; + const charactersLength = BASE58_ALPHABET.length; + for (let i = 0; i < SOLANA_PRIVATE_KEY_LENGTH; i++) { + const randomIndex = Math.floor(Math.random() * charactersLength); + result += BASE58_ALPHABET.charAt(randomIndex); + } + return result; +} + +try { + jest.setTimeout(100_0000); +} catch (e) { + // ... continue execution +} + +describe('Wrapped Keys', () => { + let devEnv: TinnyEnvironment; + let alice: TinnyPerson; + beforeAll(async () => { + //@ts-expect-error defined in global + devEnv = global.devEnv; + }); + + beforeEach(async () => { + alice = await devEnv.createRandomPerson(); + }); + + afterEach(() => { + alice && devEnv.releasePrivateKeyFromUser(alice); + }); + + beforeEach(() => { + jest.spyOn(console, 'warn').mockImplementation(jest.fn()); + }); + + afterAll(async () => { + await devEnv.litNodeClient?.disconnect(); + }); + + it('Sign Tx Sol Encrypted Key', async () => { + const pkpSessionSigs = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const solanaKeypair = Keypair.generate(); + const privateKey = Buffer.from(solanaKeypair.secretKey).toString('hex'); + + const { pkpAddress, id } = await importPrivateKey({ + pkpSessionSigs: pkpSessionSigs!, + privateKey, + litNodeClient: devEnv?.litNodeClient as ILitNodeClient, + publicKey: '0xdeadbeef', + keyType: 'K256', + memo: 'Test key', + }); + + const alicePkpAddress = alice.authMethodOwnedPkp?.ethAddress; + expect(pkpAddress).toEqual(alicePkpAddress); + + const pkpSessionSigsSigning = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const solanaTransaction = new Transaction(); + solanaTransaction.add( + SystemProgram.transfer({ + fromPubkey: solanaKeypair.publicKey, + toPubkey: new PublicKey(solanaKeypair.publicKey), + lamports: LAMPORTS_PER_SOL / 100, // Transfer 0.01 SOL + }) + ); + solanaTransaction.feePayer = solanaKeypair.publicKey; + + const solanaConnection = new Connection( + clusterApiUrl('devnet'), + 'confirmed' + ); + const { blockhash } = await solanaConnection.getLatestBlockhash(); + solanaTransaction.recentBlockhash = blockhash; + + const serializedTransaction = solanaTransaction + .serialize({ + requireAllSignatures: false, // should be false as we're not signing the message + verifySignatures: false, // should be false as we're not signing the message + }) + .toString('base64'); + + const unsignedTransaction: SerializedTransaction = { + serializedTransaction, + chain: 'devnet', + }; + + const signedTx = await signTransactionWithEncryptedKey({ + pkpSessionSigs: pkpSessionSigsSigning!, + network: 'solana', + unsignedTransaction, + broadcast: false, + litNodeClient: devEnv?.litNodeClient as ILitNodeClient, + id, + }); + + const signatureBuffer = Buffer.from(signedTx, 'base64'); + solanaTransaction.addSignature(solanaKeypair.publicKey, signatureBuffer); + + expect(solanaTransaction.verifySignatures()).toBeTruthy(); + }); + + it('Sign Message Sol Encryption Key', async () => { + const pkpSessionSigs = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const solanaKeypair = Keypair.generate(); + const privateKey = Buffer.from(solanaKeypair.secretKey).toString('hex'); + + const { pkpAddress, id } = await importPrivateKey({ + pkpSessionSigs: pkpSessionSigs!, + privateKey, + litNodeClient: devEnv?.litNodeClient as ILitNodeClient, + publicKey: '0xdeadbeef', + keyType: 'K256', + memo: 'Test key', + }); + + const alicePkpAddress = alice.authMethodOwnedPkp?.ethAddress; + if (pkpAddress !== alicePkpAddress) { + throw new Error( + `Received address: ${pkpAddress} doesn't match Alice's PKP address: ${alicePkpAddress}` + ); + } + + const pkpSessionSigsSigning = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const messageToSign = 'This is a test message'; + + const signature = await signMessageWithEncryptedKey({ + pkpSessionSigs: pkpSessionSigsSigning!, + network: 'solana', + messageToSign, + litNodeClient: devEnv?.litNodeClient as ILitNodeClient, + id, + }); + + console.log('signature'); + console.log(signature); + + const signatureIsValidForPublicKey = nacl.sign.detached.verify( + Buffer.from(messageToSign), + bs58.decode(signature), + solanaKeypair.publicKey.toBuffer() + ); + + expect(signatureIsValidForPublicKey).toBeTruthy(); + }); + + it('Import Key', async () => { + const pkpSessionSigs = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const privateKey = randomSolanaPrivateKey(); + // '4rXcTBAZVypFRGGER4TwSuGGxMvmRwvYA3jwuZfDY4YKX4VEbuUaPCWrZGSxujKknQCdN8UD9wMW8XYmT1BiLxmB'; + + const { pkpAddress } = await importPrivateKey({ + pkpSessionSigs: pkpSessionSigs!, + privateKey, + litNodeClient: devEnv?.litNodeClient as ILitNodeClient, + publicKey: '0xdeadbeef', + keyType: 'K256', + memo: 'Test key', + }); + + const alicePkpAddress = alice.authMethodOwnedPkp?.ethAddress; + expect(pkpAddress).toEqual(alicePkpAddress); + }); + + it('Generate Solana Wrapped Key', async () => { + const pkpSessionSigs = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const { pkpAddress, generatedPublicKey, id } = await generatePrivateKey({ + pkpSessionSigs: pkpSessionSigs!, + network: 'solana', + litNodeClient: devEnv?.litNodeClient as ILitNodeClient, + memo: 'Test Key', + }); + + const alicePkpAddress = alice.authMethodOwnedPkp?.ethAddress; + expect(pkpAddress).toEqual(alicePkpAddress); + + const pkpSessionSigsSigning = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const messageToSign = 'This is a test message'; + + const signature = await signMessageWithEncryptedKey({ + pkpSessionSigs: pkpSessionSigsSigning!, + litNodeClient: devEnv?.litNodeClient as ILitNodeClient, + network: 'solana', + messageToSign, + id, + }); + + const signatureIsValidForPublicKey = nacl.sign.detached.verify( + Buffer.from(messageToSign), + bs58.decode(signature), + bs58.decode(generatedPublicKey) + ); + + expect(signatureIsValidForPublicKey).toBeDefined(); + + const pkpSessionSigsExport = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const { decryptedPrivateKey } = await exportPrivateKey({ + pkpSessionSigs: pkpSessionSigsExport!, + litNodeClient: devEnv?.litNodeClient as ILitNodeClient, + network: 'solana', + id, + }); + + const solanaKeyPair = Keypair.fromSecretKey( + Buffer.from(decryptedPrivateKey, 'hex') + ); + const decryptedPublicKey = solanaKeyPair.publicKey; + + expect(decryptedPublicKey.toString()).toEqual(generatedPublicKey); + }); + + it('Generate ETH Wrapped Key', async () => { + const pkpSessionSigs = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const { pkpAddress, generatedPublicKey, id } = await generatePrivateKey({ + pkpSessionSigs: pkpSessionSigs!, + network: 'evm', + litNodeClient: devEnv.litNodeClient!, + memo: 'Test Key', + }); + + const alicePkpAddress = alice.authMethodOwnedPkp?.ethAddress; + expect(pkpAddress).toEqual(alicePkpAddress); + + const pkpSessionSigsExport = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const { decryptedPrivateKey } = await exportPrivateKey({ + pkpSessionSigs: pkpSessionSigsExport!, + litNodeClient: devEnv.litNodeClient!, + network: 'evm', + id, + }); + + const wallet = new ethers.Wallet(decryptedPrivateKey); + const decryptedPublicKey = wallet.publicKey; + + expect(decryptedPublicKey).toEqual(generatedPublicKey); + }); + + it('Fail Import Wrapped Key Same Private Key', async () => { + const pkpSessionSigs = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const privateKey = + '4rXcTBAZVypFRGGER4TwSuGGxMvmRwvYA3jwuZfDY4YKX4VEbuUaPCWrZGSxujKknQCdN8UD9wMW8XYmT1BiLxmB'; // Already exists in the DB + + expect( + importPrivateKey({ + pkpSessionSigs: pkpSessionSigs!, + privateKey, + litNodeClient: devEnv.litNodeClient!, + publicKey: '0xdeadbeef', + keyType: 'K256', + memo: 'Test Key', + }) + ).rejects.toThrowError( + new Error( + 'Failed to make request for wrapped key: There is already a wrapped key stored with the same dataToEncryptHash. A wrapped key may only be associated with a single pkpAddress.' + ) + ); + + devEnv.releasePrivateKeyFromUser(alice); + }); + + it('Fail Import Wrapped Key Same PKP', async () => { + const pkpSessionSigs = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const privateKey1 = randomSolanaPrivateKey(); + + const { pkpAddress } = await importPrivateKey({ + pkpSessionSigs: pkpSessionSigs!, + privateKey: privateKey1, + litNodeClient: devEnv.litNodeClient!, + publicKey: '0xdeadbeef', + keyType: 'K256', + memo: 'Test Key', + }); + + const alicePkpAddress = alice.authMethodOwnedPkp?.ethAddress; + expect(pkpAddress).toEqual(alicePkpAddress); + + const privateKey2 = randomSolanaPrivateKey(); + + expect( + importPrivateKey({ + pkpSessionSigs: pkpSessionSigs!, + privateKey: privateKey2, + litNodeClient: devEnv.litNodeClient!, + publicKey: '0xdeadbeef', + keyType: 'K256', + memo: 'Test Key', + }) + ).rejects.toThrowError(new Error()); + }); + + it('Fail Max Expiration Session Sig', async () => { + const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); + + const privateKey = randomSolanaPrivateKey(); + + expect( + importPrivateKey({ + pkpSessionSigs: pkpSessionSigs!, + privateKey, + litNodeClient: devEnv.litNodeClient!, + publicKey: '0xdeadbeef', + keyType: 'K256', + memo: 'Test Key', + }) + ).rejects.toThrow( + new Error( + 'Failed to make request for wrapped key: Not Authorized: Invalid sessionSig: Expires too far in the future; must be within 15 of now.' + ) + ); + }); + + it('Fail Import Invalid Session Sig', async () => { + const tamperPkpSessionSigs = ( + pkpSessionSig: SessionSigsMap + ): SessionSigsMap => { + const tamperedPkpSessionSigs: SessionSigsMap = {}; + + for (const key in pkpSessionSig) { + if (pkpSessionSig[key]) { + const authSig = pkpSessionSig[key]; + const updatedAuthSig: AuthSig = { + ...authSig, + address: authSig.address.slice(0, -1), + }; + tamperedPkpSessionSigs[key] = updatedAuthSig; + } + } + + return tamperedPkpSessionSigs; + }; + + const pkpSessionSigs = await getPkpSessionSigs(devEnv, alice); + const privateKey = randomSolanaPrivateKey(); + + expect( + importPrivateKey({ + pkpSessionSigs: tamperPkpSessionSigs(pkpSessionSigs!), + privateKey, + litNodeClient: devEnv.litNodeClient!, + publicKey: '0xdeadbeef', + keyType: 'K256', + memo: 'Test Key', + }) + ).rejects.toThrowError('bad public key size'); + }); + + it('Fail Import Expired Session Sig', async () => { + const pkpSessionSigs: SessionSigsMap = { + 'https://207.244.70.36:8474': { + sig: '1827d1c7b79c979ce76d0b9e130f6804dbf7c7838b6dfa41d4cadf690b9a8bec23321dde6cc573e8a592c395193074ade303d94f3c198d8f0017ca0aca91bd0f', + derivedVia: 'litSessionSignViaNacl', + signedMessage: `{"sessionKey":"4fd3d6ae41190cdd33a07bc5feb4a51b0c882474e6b51eb37cf799d6668eb44b","resourceAbilityRequests":[{"resource":{"resource":"*","resourcePrefix":"lit-pkp"},"ability":"pkp-signing"},{"resource":{"resource":"*","resourcePrefix":"lit-litaction"},"ability":"lit-action-execution"}],"capabilities":[{"sig":"{\\"ProofOfPossession\\":\\"8f060f34f55e996e8396c5036cb456dbf3b3cf79a6c9d2a9c036a27dae6be5cb286c0170c45404ce60d45ad5df384a030450f4eabe61af68d7267d2de035a1ff0697097b3b32413581d8550b198599b8ee5c29a78999c05f8806e33923705748\\"}","algo":"LIT_BLS","derivedVia":"lit.bls","signedMessage":"litprotocol.com wants you to sign in with your Ethereum account:\\n0xd1Af1AAC50aC837C873200D17b78664aFCde597C\\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:4fd3d6ae41190cdd33a07bc5feb4a51b0c882474e6b51eb37cf799d6668eb44b\\nVersion: 1\\nChain ID: 1\\nNonce: 0xa8b687976835989b8ac57e8e6cb17fa316cc9ef74ea6174a588f08b11571829c\\nIssued At: 2024-06-02T19:46:47Z\\nExpiration Time: 2024-06-03T19:47:14.907Z\\nResources:\\n- urn:recap:eyJhdHQiOnsibGl0LWxpdGFjdGlvbjovLyoiOnsiVGhyZXNob2xkL0V4ZWN1dGlvbiI6W3t9XX0sImxpdC1wa3A6Ly8qIjp7IlRocmVzaG9sZC9TaWduaW5nIjpbe31dfSwibGl0LXJlc29sdmVkYXV0aGNvbnRleHQ6Ly8qIjp7IkF1dGgvQXV0aCI6W3siYXV0aF9jb250ZXh0Ijp7ImFjdGlvbklwZnNJZHMiOltdLCJhdXRoTWV0aG9kQ29udGV4dHMiOlt7ImFwcElkIjoibGl0IiwiYXV0aE1ldGhvZFR5cGUiOjEsImV4cGlyYXRpb24iOjE3MTc0NDQwMjAsInVzZWRGb3JTaWduU2Vzc2lvbktleVJlcXVlc3QiOnRydWUsInVzZXJJZCI6IjB4MkY2ZjU4NzRhNGQyNTFlMzVDZDc4YjM1NzZDQTkwYkQyZjA1RmUwQiJ9XSwiYXV0aFNpZ0FkZHJlc3MiOm51bGwsImN1c3RvbUF1dGhSZXNvdXJjZSI6IiIsInJlc291cmNlcyI6W119fV19fSwicHJmIjpbXX0","address":"0xd1Af1AAC50aC837C873200D17b78664aFCde597C"}],"issuedAt":"2024-06-02T19:47:16.707Z","expiration":"2024-06-03T19:47:14.907Z","nodeAddress":"https://207.244.70.36:8474"}`, + address: + '4fd3d6ae41190cdd33a07bc5feb4a51b0c882474e6b51eb37cf799d6668eb44b', + algo: 'ed25519', + }, + 'https://207.244.70.36:8473': { + sig: '762b9849d2cc77d0c75aa354c3cce63abca008a9a07ec3efc69ee8a4954650c3362b8cb83cd3d63310ad98b446be5e68cb8193f9d486453b2df72188dc698d0e', + derivedVia: 'litSessionSignViaNacl', + signedMessage: `{"sessionKey":"4fd3d6ae41190cdd33a07bc5feb4a51b0c882474e6b51eb37cf799d6668eb44b","resourceAbilityRequests":[{"resource":{"resource":"*","resourcePrefix":"lit-pkp"},"ability":"pkp-signing"},{"resource":{"resource":"*","resourcePrefix":"lit-litaction"},"ability":"lit-action-execution"}],"capabilities":[{"sig":"{\\"ProofOfPossession\\":\\"8f060f34f55e996e8396c5036cb456dbf3b3cf79a6c9d2a9c036a27dae6be5cb286c0170c45404ce60d45ad5df384a030450f4eabe61af68d7267d2de035a1ff0697097b3b32413581d8550b198599b8ee5c29a78999c05f8806e33923705748\\"}","algo":"LIT_BLS","derivedVia":"lit.bls","signedMessage":"litprotocol.com wants you to sign in with your Ethereum account:\\n0xd1Af1AAC50aC837C873200D17b78664aFCde597C\\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:4fd3d6ae41190cdd33a07bc5feb4a51b0c882474e6b51eb37cf799d6668eb44b\\nVersion: 1\\nChain ID: 1\\nNonce: 0xa8b687976835989b8ac57e8e6cb17fa316cc9ef74ea6174a588f08b11571829c\\nIssued At: 2024-06-02T19:46:47Z\\nExpiration Time: 2024-06-03T19:47:14.907Z\\nResources:\\n- urn:recap:eyJhdHQiOnsibGl0LWxpdGFjdGlvbjovLyoiOnsiVGhyZXNob2xkL0V4ZWN1dGlvbiI6W3t9XX0sImxpdC1wa3A6Ly8qIjp7IlRocmVzaG9sZC9TaWduaW5nIjpbe31dfSwibGl0LXJlc29sdmVkYXV0aGNvbnRleHQ6Ly8qIjp7IkF1dGgvQXV0aCI6W3siYXV0aF9jb250ZXh0Ijp7ImFjdGlvbklwZnNJZHMiOltdLCJhdXRoTWV0aG9kQ29udGV4dHMiOlt7ImFwcElkIjoibGl0IiwiYXV0aE1ldGhvZFR5cGUiOjEsImV4cGlyYXRpb24iOjE3MTc0NDQwMjAsInVzZWRGb3JTaWduU2Vzc2lvbktleVJlcXVlc3QiOnRydWUsInVzZXJJZCI6IjB4MkY2ZjU4NzRhNGQyNTFlMzVDZDc4YjM1NzZDQTkwYkQyZjA1RmUwQiJ9XSwiYXV0aFNpZ0FkZHJlc3MiOm51bGwsImN1c3RvbUF1dGhSZXNvdXJjZSI6IiIsInJlc291cmNlcyI6W119fV19fSwicHJmIjpbXX0","address":"0xd1Af1AAC50aC837C873200D17b78664aFCde597C"}],"issuedAt":"2024-06-02T19:47:16.707Z","expiration":"2024-06-03T19:47:14.907Z","nodeAddress":"https://207.244.70.36:8473"}`, + address: + '4fd3d6ae41190cdd33a07bc5feb4a51b0c882474e6b51eb37cf799d6668eb44b', + algo: 'ed25519', + }, + 'https://207.244.70.36:8475': { + sig: '5e506dc973cc1540dcb3bd1de251afa687caf277cb5f3efe107339ecf4c25607d4bdf5d8c8910874519252e026a49cc66cea0b07bc5d38342c7cb2613decbe0a', + derivedVia: 'litSessionSignViaNacl', + signedMessage: `{"sessionKey":"4fd3d6ae41190cdd33a07bc5feb4a51b0c882474e6b51eb37cf799d6668eb44b","resourceAbilityRequests":[{"resource":{"resource":"*","resourcePrefix":"lit-pkp"},"ability":"pkp-signing"},{"resource":{"resource":"*","resourcePrefix":"lit-litaction"},"ability":"lit-action-execution"}],"capabilities":[{"sig":"{\\"ProofOfPossession\\":\\"8f060f34f55e996e8396c5036cb456dbf3b3cf79a6c9d2a9c036a27dae6be5cb286c0170c45404ce60d45ad5df384a030450f4eabe61af68d7267d2de035a1ff0697097b3b32413581d8550b198599b8ee5c29a78999c05f8806e33923705748\\"}","algo":"LIT_BLS","derivedVia":"lit.bls","signedMessage":"litprotocol.com wants you to sign in with your Ethereum account:\\n0xd1Af1AAC50aC837C873200D17b78664aFCde597C\\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:4fd3d6ae41190cdd33a07bc5feb4a51b0c882474e6b51eb37cf799d6668eb44b\\nVersion: 1\\nChain ID: 1\\nNonce: 0xa8b687976835989b8ac57e8e6cb17fa316cc9ef74ea6174a588f08b11571829c\\nIssued At: 2024-06-02T19:46:47Z\\nExpiration Time: 2024-06-03T19:47:14.907Z\\nResources:\\n- urn:recap:eyJhdHQiOnsibGl0LWxpdGFjdGlvbjovLyoiOnsiVGhyZXNob2xkL0V4ZWN1dGlvbiI6W3t9XX0sImxpdC1wa3A6Ly8qIjp7IlRocmVzaG9sZC9TaWduaW5nIjpbe31dfSwibGl0LXJlc29sdmVkYXV0aGNvbnRleHQ6Ly8qIjp7IkF1dGgvQXV0aCI6W3siYXV0aF9jb250ZXh0Ijp7ImFjdGlvbklwZnNJZHMiOltdLCJhdXRoTWV0aG9kQ29udGV4dHMiOlt7ImFwcElkIjoibGl0IiwiYXV0aE1ldGhvZFR5cGUiOjEsImV4cGlyYXRpb24iOjE3MTc0NDQwMjAsInVzZWRGb3JTaWduU2Vzc2lvbktleVJlcXVlc3QiOnRydWUsInVzZXJJZCI6IjB4MkY2ZjU4NzRhNGQyNTFlMzVDZDc4YjM1NzZDQTkwYkQyZjA1RmUwQiJ9XSwiYXV0aFNpZ0FkZHJlc3MiOm51bGwsImN1c3RvbUF1dGhSZXNvdXJjZSI6IiIsInJlc291cmNlcyI6W119fV19fSwicHJmIjpbXX0","address":"0xd1Af1AAC50aC837C873200D17b78664aFCde597C"}],"issuedAt":"2024-06-02T19:47:16.707Z","expiration":"2024-06-03T19:47:14.907Z","nodeAddress":"https://207.244.70.36:8475"}`, + address: + '4fd3d6ae41190cdd33a07bc5feb4a51b0c882474e6b51eb37cf799d6668eb44b', + algo: 'ed25519', + }, + }; + + const privateKey = randomSolanaPrivateKey(); + + expect( + importPrivateKey({ + pkpSessionSigs, + privateKey, + litNodeClient: devEnv.litNodeClient!, + publicKey: '0xdeadbeef', + keyType: 'K256', + memo: 'Test Key', + }) + ).rejects.toThrowError( + new Error( + 'Failed to make request for wrapped key: Not Authorized: Invalid sessionSig: Expired' + ) + ); + }); + + it('Fail EOA Session Sig', async () => { + const eoaSessionSigs = await getEoaSessionSigs(devEnv, alice); + + const privateKey = randomSolanaPrivateKey(); + + expect( + importPrivateKey({ + pkpSessionSigs: eoaSessionSigs!, + privateKey, + litNodeClient: devEnv.litNodeClient!, + publicKey: '0xdeadbeef', + keyType: 'K256', + memo: 'Test Key', + }) + ).rejects.toThrowError( + new Error('SessionSig is not from a PKP; no LIT_BLS capabilities found') + ); + }); + + it('Fail Eth Sign Tx Missing Params', async () => { + const pkpSessionSigs = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const privateKey = ethers.Wallet.createRandom().privateKey; + + const { pkpAddress, id } = await importPrivateKey({ + pkpSessionSigs: pkpSessionSigs!, + privateKey, + litNodeClient: devEnv.litNodeClient!, + publicKey: '0xdeadbeef', + keyType: 'K256', + memo: 'Test Key', + }); + + const alicePkpAddress = alice.authMethodOwnedPkp?.ethAddress; + expect(pkpAddress).toEqual(alicePkpAddress); + + const pkpSessionSigsSigning = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + expect( + signTransactionWithEncryptedKey({ + pkpSessionSigs: pkpSessionSigsSigning!, + network: 'evm', + unsignedTransaction: { + ...getChainForNetwork( + devEnv.litNodeClient?.config?.litNetwork as LIT_NETWORKS_KEYS + ), + // @ts-expect-error This test is intentionally using the type incorrectly. + serializedTransaction: 'random-value', + }, + broadcast: false, + id, + litNodeClient: devEnv.litNodeClient!, + }) + ).rejects.toThrowError( + new Error( + 'Error executing the Signing Lit Action: Error: Missing required field: toAddress' + ) + ); + }); + + it('Fail Eth Sign Invalid Param', async () => { + const pkpSessionSigs = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const privateKey = ethers.Wallet.createRandom().privateKey; + + const { pkpAddress, id } = await importPrivateKey({ + pkpSessionSigs: pkpSessionSigs!, + privateKey, + litNodeClient: devEnv.litNodeClient!, + publicKey: '0xdeadbeef', + keyType: 'K256', + memo: 'Test Key', + }); + + const alicePkpAddress = alice.authMethodOwnedPkp?.ethAddress; + expect(pkpAddress).toEqual(alicePkpAddress); + + const pkpSessionSigsSigning = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const unsignedTransaction: EthereumLitTransaction = { + ...getBaseTransactionForNetwork({ + network: devEnv.litNodeClient!.config.litNetwork, + toAddress: alice.wallet.address, + }), + dataHex: 'Test transaction from Alice to bob', + }; + + expect( + signTransactionWithEncryptedKey({ + pkpSessionSigs: pkpSessionSigsSigning!, + network: 'evm', + unsignedTransaction, + broadcast: false, + litNodeClient: devEnv.litNodeClient!, + id, + }) + ).rejects.toThrowError( + new Error( + 'Error executing the Signing Lit Action: Error: When signing transaction- invalid hexlify value (argument="value", value="Test transaction from Alice to bob", code=INVALID_ARGUMENT, version=bytes/5.7.0)' + ) + ); + }); + + it('Fail Eth TX Invalid Decryption', async () => { + const privateKey = ethers.Wallet.createRandom().privateKey; + const alicePkpAddress = alice.authMethodOwnedPkp!.ethAddress; + const decryptionAccessControlCondition = + getPkpAccessControlCondition(alicePkpAddress); + const { ciphertext, dataToEncryptHash } = await encryptString( + { + accessControlConditions: [decryptionAccessControlCondition], + dataToEncrypt: LIT_PREFIX + privateKey, + }, + devEnv.litNodeClient! + ); + + const bob = await devEnv.createRandomPerson(); + const pkpSessionSigsSigning = await getPkpSessionSigs( + devEnv, + bob, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const unsignedTransaction = getBaseTransactionForNetwork({ + network: devEnv.litNodeClient?.config.litNetwork as LIT_NETWORKS_KEYS, + toAddress: alice.wallet.address, + }); + + devEnv.litNodeClient + ?.executeJs({ + sessionSigs: pkpSessionSigsSigning!, + ipfsId: LIT_ACTION_CID_REPOSITORY.signTransaction.evm, + jsParams: { + ciphertext, + dataToEncryptHash, + unsignedTransaction, + accessControlConditions: [decryptionAccessControlCondition], + }, + }) + .then((res) => { + expect(res.response).toEqual( + 'Error: When decrypting to a single node- Access control conditions check failed. Check that you are allowed to decrypt this item.' + ); + }) + .finally(() => { + devEnv.releasePrivateKeyFromUser(bob); + }); + }); + + it('Export', async () => { + const pkpSessionSigsImport = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const privateKey = randomSolanaPrivateKey(); + + const { pkpAddress, id } = await importPrivateKey({ + pkpSessionSigs: pkpSessionSigsImport!, + privateKey, + litNodeClient: devEnv.litNodeClient!, + publicKey: '0xdeadbeef', + keyType: 'K256', + memo: 'Test Key', + }); + + const alicePkpAddress = alice.authMethodOwnedPkp?.ethAddress; + expect(pkpAddress).toEqual(alicePkpAddress); + + const pkpSessionSigsExport = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const { decryptedPrivateKey } = await exportPrivateKey({ + pkpSessionSigs: pkpSessionSigsExport!, + litNodeClient: devEnv.litNodeClient!, + network: 'solana', + id, + }); + + expect(decryptedPrivateKey).toEqual(privateKey); + }); + + it('Eth Sign Tx', async () => { + const pkpSessionSigs = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const privateKey = ethers.Wallet.createRandom().privateKey; + + const { pkpAddress, id } = await importPrivateKey({ + pkpSessionSigs: pkpSessionSigs!, + privateKey, + litNodeClient: devEnv.litNodeClient!, + publicKey: '0xdeadbeef', + keyType: 'K256', + memo: 'Test Key', + }); + + const alicePkpAddress = alice.authMethodOwnedPkp?.ethAddress; + + expect(pkpAddress).toEqual(alicePkpAddress); + + const pkpSessionSigsSigning = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const unsignedTransaction = getBaseTransactionForNetwork({ + network: devEnv.litNodeClient?.config.litNetwork as LIT_NETWORKS_KEYS, + toAddress: alice.wallet.address, + }); + + const signedTx = await signTransactionWithEncryptedKey({ + pkpSessionSigs: pkpSessionSigsSigning!, + network: 'evm', + unsignedTransaction, + broadcast: false, + litNodeClient: devEnv.litNodeClient!, + id, + }); + + expect(!ethers.utils.isHexString(signedTx)).toBeTruthy(); + }); + + it('Eth Sign Message', async () => { + const pkpSessionSigs = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const privateKey = ethers.Wallet.createRandom().privateKey; + + const { pkpAddress, id } = await importPrivateKey({ + pkpSessionSigs: pkpSessionSigs!, + privateKey, + litNodeClient: devEnv.litNodeClient!, + publicKey: '0xdeadbeef', + keyType: 'K256', + memo: 'Test Key', + }); + + const alicePkpAddress = alice.authMethodOwnedPkp?.ethAddress; + expect(pkpAddress).toEqual(alicePkpAddress); + + const pkpSessionSigsSigning = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const unsignedStringMessage = 'This is a test message'; + + const signature = await signMessageWithEncryptedKey({ + pkpSessionSigs: pkpSessionSigsSigning!, + network: 'evm', + messageToSign: unsignedStringMessage, + litNodeClient: devEnv.litNodeClient!, + id, + }); + + expect(ethers.utils.isHexString(signature)).toBeTruthy(); + + const unsignedBinaryMessage = ethers.utils.arrayify( + ethers.utils.toUtf8Bytes(unsignedStringMessage) + ); + + const signatureBinary = await signMessageWithEncryptedKey({ + pkpSessionSigs: pkpSessionSigsSigning!, + network: 'evm', + messageToSign: unsignedBinaryMessage, + litNodeClient: devEnv.litNodeClient!, + id, + }); + + expect(ethers.utils.isHexString(signatureBinary)).toBeTruthy(); + + expect(signatureBinary).toEqual(signature); + }); + + it('Eth Sign Message Generate Key', async () => { + const pkpSessionSigs = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const privateKey = ethers.Wallet.createRandom().privateKey; + + const { pkpAddress, id } = await importPrivateKey({ + pkpSessionSigs: pkpSessionSigs!, + privateKey, + litNodeClient: devEnv.litNodeClient!, + publicKey: '0xdeadbeef', + keyType: 'K256', + memo: 'Test Key', + }); + + const alicePkpAddress = alice.authMethodOwnedPkp?.ethAddress; + expect(pkpAddress).toEqual(alicePkpAddress); + + const pkpSessionSigsSigning = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const unsignedStringMessage = 'This is a test message'; + + const signature = await signMessageWithEncryptedKey({ + pkpSessionSigs: pkpSessionSigsSigning!, + network: 'evm', + messageToSign: unsignedStringMessage, + litNodeClient: devEnv.litNodeClient!, + id, + }); + + expect(ethers.utils.isHexString(signature)).toBeTruthy(); + + const unsignedBinaryMessage = ethers.utils.arrayify( + ethers.utils.toUtf8Bytes(unsignedStringMessage) + ); + + const signatureBinary = await signMessageWithEncryptedKey({ + pkpSessionSigs: pkpSessionSigsSigning!, + network: 'evm', + messageToSign: unsignedBinaryMessage, + litNodeClient: devEnv.litNodeClient!, + id, + }); + + expect(ethers.utils.isHexString(signature)).toBeTruthy(); + + expect(signatureBinary).toEqual(signature); + }); + + it('Eth Broadcast With Fetch Gas Params', async () => { + const pkpSessionSigs = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const wrappedKeysWallet = ethers.Wallet.createRandom(); + const wrappedKeysWalletPrivateKey = wrappedKeysWallet.privateKey; + + const wrappedKeysWalletAddress = wrappedKeysWallet.address; + console.log(`Sending funds to ${wrappedKeysWalletAddress}`); + await devEnv.getFunds(wrappedKeysWallet.address, '0.005'); + + const { pkpAddress, id } = await importPrivateKey({ + pkpSessionSigs: pkpSessionSigs!, + privateKey: wrappedKeysWalletPrivateKey, + litNodeClient: devEnv.litNodeClient!, + publicKey: '0xdeadbeef', + keyType: 'K256', + memo: 'Test Key', + }); + + const alicePkpAddress = alice.authMethodOwnedPkp?.ethAddress; + expect(pkpAddress).toEqual(alicePkpAddress); + + const pkpSessionSigsSigning = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const unsignedTransaction: EthereumLitTransaction = { + toAddress: alice.wallet.address, + value: '0.0001', // in ethers (Lit tokens) + dataHex: ethers.utils.hexlify( + ethers.utils.toUtf8Bytes('Test transaction from Alice to bob') + ), + ...getChainForNetwork( + devEnv.litNodeClient?.config.litNetwork as LIT_NETWORKS_KEYS + ), + }; + + const signedTx = await signTransactionWithEncryptedKey({ + pkpSessionSigs: pkpSessionSigsSigning!, + network: 'evm', + unsignedTransaction, + broadcast: true, + litNodeClient: devEnv.litNodeClient!, + id, + }); + + // TODO: Get the raw input from the tx hash, convert it to UTF-8 and assert that it contains "Test transaction from Alice to bob" + expect(ethers.utils.isHexString(signedTx)).toBeTruthy(); + }); + + it('Eth Broadcast Tx', async () => { + const pkpSessionSigs = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const wrappedKeysWallet = ethers.Wallet.createRandom(); + const wrappedKeysWalletPrivateKey = wrappedKeysWallet.privateKey; + + const wrappedKeysWalletAddress = wrappedKeysWallet.address; + console.log(`Sending funds to ${wrappedKeysWalletAddress}`); + await devEnv.getFunds(wrappedKeysWallet.address, '0.005'); + + const { pkpAddress, id } = await importPrivateKey({ + pkpSessionSigs: pkpSessionSigs!, + privateKey: wrappedKeysWalletPrivateKey, + litNodeClient: devEnv.litNodeClient!, + publicKey: '0xdeadbeef', + keyType: 'K256', + memo: 'Test Key', + }); + + const alicePkpAddress = alice.authMethodOwnedPkp?.ethAddress; + expect(pkpAddress).toEqual(alicePkpAddress); + + const pkpSessionSigsSigning = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const unsignedTransaction = getBaseTransactionForNetwork({ + network: devEnv.litNodeClient?.config.litNetwork as LIT_NETWORKS_KEYS, + toAddress: alice.wallet.address, + }); + + const signedTx = await signTransactionWithEncryptedKey({ + pkpSessionSigs: pkpSessionSigsSigning!, + network: 'evm', + unsignedTransaction, + broadcast: true, + litNodeClient: devEnv.litNodeClient!, + id, + }); + + // TODO: Get the raw input from the tx hash, convert it to UTF-8 and assert that it contains "Test transaction from Alice to bob" + expect(ethers.utils.isHexString(signedTx)).toBeTruthy(); + }); + + it('Eth Broadcast Tx Generated Key', async () => { + const pkpSessionSigs = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const { pkpAddress, generatedPublicKey, id } = await generatePrivateKey({ + pkpSessionSigs: pkpSessionSigs!, + network: 'evm', + litNodeClient: devEnv.litNodeClient!, + memo: 'Test Key', + }); + + const generatedKeysWalletAddress = + ethers.utils.computeAddress(generatedPublicKey); + console.log(`Sending funds to ${generatedKeysWalletAddress}`); + await devEnv.getFunds(generatedKeysWalletAddress, '0.005'); + + const alicePkpAddress = alice.authMethodOwnedPkp?.ethAddress; + expect(pkpAddress).toEqual(alicePkpAddress); + + const pkpSessionSigsSigning = await getPkpSessionSigs( + devEnv, + alice, + undefined, + new Date(Date.now() + 1000 * 60 * 10).toISOString() + ); // 10 mins expiry + + const unsignedTransaction = getBaseTransactionForNetwork({ + network: devEnv.litNodeClient?.config.litNetwork as LIT_NETWORKS_KEYS, + toAddress: alice.wallet.address, + }); + + const signedTx = await signTransactionWithEncryptedKey({ + pkpSessionSigs: pkpSessionSigsSigning!, + network: 'evm', + unsignedTransaction, + broadcast: true, + litNodeClient: devEnv.litNodeClient!, + id, + }); + + expect(ethers.utils.isHexString(signedTx)).toBeTruthy(); + }); +}); + +/** + * UTILITIES + */ +export function getChainForNetwork(network: LIT_NETWORKS_KEYS): { + chain: string; + chainId: number; +} { + switch (network) { + case 'cayenne': + case 'habanero': + case 'manzano': + return { + chain: 'chronicleTestnet', + chainId: LIT_CHAINS['chronicleTestnet'].chainId, + }; + case 'datil-dev': + return { + chain: 'yellowstone', + chainId: LIT_CHAINS['yellowstone'].chainId, + }; + case 'datil-test': + return { + chain: 'yellowstone', + chainId: LIT_CHAINS['yellowstone'].chainId, + }; + case 'datil': + return { + chain: 'yellowstone', + chainId: LIT_CHAINS['yellowstone'].chainId, + }; + default: + throw new Error(`Cannot identify chain params for ${network}`); + } +} + +export function getGasParamsForNetwork(network: LIT_NETWORKS_KEYS): { + gasPrice?: string; + gasLimit: number; +} { + switch (network) { + case 'cayenne': + case 'habanero': + case 'manzano': + return { + gasPrice: '0.001', + gasLimit: 30000, + }; + case 'datil-dev': + return { gasLimit: 5000000 }; + case 'datil-test': + return { gasLimit: 5000000 }; + case 'datil': + return { gasLimit: 5000000 }; + default: + throw new Error(`Cannot identify chain params for ${network}`); + } +} + +export function getBaseTransactionForNetwork({ + toAddress, + network, +}: { + toAddress: string; + network: LIT_NETWORKS_KEYS; +}): EthereumLitTransaction { + return { + toAddress, + value: '0.0001', // in ethers (Lit tokens) + ...getChainForNetwork(network), + ...getGasParamsForNetwork(network), + dataHex: ethers.utils.hexlify( + ethers.utils.toUtf8Bytes('Test transaction from Alice to bob') + ), + }; +} diff --git a/packages/e2e-tests/src/tests/connection.spec.ts b/packages/e2e-tests/src/tests/connection.spec.ts new file mode 100644 index 0000000000..0806423f4b --- /dev/null +++ b/packages/e2e-tests/src/tests/connection.spec.ts @@ -0,0 +1,39 @@ +import { expect, jest } from '@jest/globals'; + +import { TinnyEnvironment } from '@lit-protocol/tinny'; + +try { + jest.setTimeout(60000); +} catch (e) { + // ... continue execution +} + +describe('Connections', () => { + beforeEach(() => { + jest.spyOn(console, 'warn').mockImplementation(jest.fn()); + }); + + let devEnv: TinnyEnvironment; + beforeAll(() => { + //@ts-expect-error defined in global + devEnv = global.devEnv; + }); + + afterAll(async () => { + await devEnv.litNodeClient?.disconnect(); + }); + + it('Testing Network Handshake', async () => { + expect(devEnv.litNodeClient).toBeDefined(); + expect(devEnv.litNodeClient?.ready).toBe(true); + expect(devEnv.litNodeClient?.config.litNetwork).toBe( + devEnv.processEnvs.NETWORK + ); + expect(devEnv.litNodeClient?.networkPubKey).toBeDefined(); + expect(devEnv.litNodeClient?.hdRootPubkeys).toBeDefined(); + expect(devEnv.litNodeClient?.connectedNodes?.size).toBeGreaterThanOrEqual( + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain + devEnv.litNodeClient?.config?.minNodeCount! + ); + }); +}); diff --git a/packages/e2e-tests/tsconfig.json b/packages/e2e-tests/tsconfig.json new file mode 100644 index 0000000000..f5b85657a8 --- /dev/null +++ b/packages/e2e-tests/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/packages/e2e-tests/tsconfig.lib.json b/packages/e2e-tests/tsconfig.lib.json new file mode 100644 index 0000000000..e85ef50f65 --- /dev/null +++ b/packages/e2e-tests/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "declaration": true, + "types": [] + }, + "include": ["**/*.ts"], + "exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.test.ts"] +} diff --git a/packages/e2e-tests/tsconfig.spec.json b/packages/e2e-tests/tsconfig.spec.json new file mode 100644 index 0000000000..546f12877f --- /dev/null +++ b/packages/e2e-tests/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] +} diff --git a/packages/encryption/src/lib/encryption.ts b/packages/encryption/src/lib/encryption.ts index f591549e02..4b50e5e01b 100644 --- a/packages/encryption/src/lib/encryption.ts +++ b/packages/encryption/src/lib/encryption.ts @@ -142,6 +142,7 @@ export async function decryptFromJson( // FIXME: The return type of this function is inferrable based on the value of `params.dataType` if (parsedJsonData.dataType === 'string') { + //@ts-ignore compatible but not formally return decryptToString( { accessControlConditions: parsedJsonData.accessControlConditions, @@ -157,6 +158,7 @@ export async function decryptFromJson( litNodeClient ); } else if (parsedJsonData.dataType === 'file') { + //@ts-ignore compatible but not formally return decryptToFile( { accessControlConditions: parsedJsonData.accessControlConditions, diff --git a/packages/lit-node-client-nodejs/src/lib/helpers/validate-bls-session-sigs.spec.ts b/packages/lit-node-client-nodejs/src/lib/helpers/validate-bls-session-sigs.spec.ts index f1563339e8..6e9ccd8fdb 100644 --- a/packages/lit-node-client-nodejs/src/lib/helpers/validate-bls-session-sigs.spec.ts +++ b/packages/lit-node-client-nodejs/src/lib/helpers/validate-bls-session-sigs.spec.ts @@ -1,3 +1,5 @@ +import { SiweMessage } from 'siwe'; + import { blsSessionSigVerify } from './validate-bls-session-sig'; describe('BlsSessionSigVerify', () => { @@ -16,25 +18,27 @@ describe('BlsSessionSigVerify', () => { 'Chain ID: 1\n' + 'Nonce: 0x1f623ab8dfe6bbd3b3dc22c7a041deb697c14817bce471b1bd1d86a25d5a319c\n' + 'Issued At: 2024-06-11T15:55:23Z\n' + - 'Expiration Time: 2024-06-12T15:55:47.655Z\n' + + 'Expiration Time: 2030-06-12T15:55:47.655Z\n' + 'Resources:\n' + '- urn:recap:eyJhdHQiOnsibGl0LWxpdGFjdGlvbjovLyoiOnsiVGhyZXNob2xkL0V4ZWN1dGlvbiI6W3t9XX0sImxpdC1wa3A6Ly8qIjp7IlRocmVzaG9sZC9TaWduaW5nIjpbe31dfSwibGl0LXJlc29sdmVkYXV0aGNvbnRleHQ6Ly8qIjp7IkF1dGgvQXV0aCI6W3siYXV0aF9jb250ZXh0Ijp7ImFjdGlvbklwZnNJZHMiOlsiUW1ZM3F1bjlxWDNmVUJIVmZyQTlmM3Y5UnB5eVBvOFJIRXVFTjFYWVBxMVByQSJdLCJhdXRoTWV0aG9kQ29udGV4dHMiOlt7ImFwcElkIjoibGl0IiwiYXV0aE1ldGhvZFR5cGUiOjEsImV4cGlyYXRpb24iOjE3MTgyMDc3MzgsInVzZWRGb3JTaWduU2Vzc2lvbktleVJlcXVlc3QiOnRydWUsInVzZXJJZCI6IjB4NjEwM2U1MGUyQzA0OWM5MjgxNEE1Mjc1YURDZDlBNzE2NjY3OTUxZSJ9XSwiYXV0aFNpZ0FkZHJlc3MiOm51bGwsImN1c3RvbUF1dGhSZXNvdXJjZSI6InRydWUiLCJyZXNvdXJjZXMiOltdfX1dfX0sInByZiI6W119', address: '0xf087a967D9eA9445D9182692C2944DcC0Af57341', }; - let networkPubKey = + const networkPubKey = 'a43499a4b786da2dd28af9f209eb152ff6f646b34b68a02954967271e17fb4c511fd67b81e067f690c6f38acab70585d'; + const message = new SiweMessage(authSig.signedMessage); it(`should verify valid bls signatrue`, () => { expect( blsSessionSigVerify( - (public_key: any, message: any, signature: any) => { + (public_key, message, signature) => { expect(typeof public_key).toBe('string'); expect(typeof message).toBe('string'); expect(typeof signature).toBe('string'); }, networkPubKey, - authSig + authSig, + message ) ).toBeUndefined(); }); diff --git a/packages/lit-node-client-nodejs/src/lib/lit-node-client-nodejs.spec.ts b/packages/lit-node-client-nodejs/src/lib/lit-node-client-nodejs.spec.ts index 74068b2e2a..cd51305c84 100644 --- a/packages/lit-node-client-nodejs/src/lib/lit-node-client-nodejs.spec.ts +++ b/packages/lit-node-client-nodejs/src/lib/lit-node-client-nodejs.spec.ts @@ -6,6 +6,7 @@ global.jestTesting = true; import { LitNodeClientNodeJs } from './lit-node-client-nodejs'; +import { LocalStorage } from 'node-localstorage'; const isClass = (v) => { return typeof v === 'function' && /^\s*class\s+/.test(v.toString()); @@ -41,16 +42,23 @@ describe('LitNodeClientNodeJs', () => { it('should be able to defined a storage provider', async () => { const tmp = globalThis.localStorage; - Object.defineProperty(globalThis, 'localStorage', { value: undefined }); - const ls = require('node-localstorage').LocalStorage; + Object.defineProperty(globalThis, 'localStorage', { + value: undefined, + configurable: true, + }); + const litNodeClient = new LitNodeClientNodeJs({ litNetwork: 'custom', storageProvider: { - provider: new ls('./storage.test.db'), + provider: new LocalStorage('./storage.test.db'), }, }); expect(litNodeClient).toBeDefined(); - expect(litNodeClient.config.storageProvider?.provider).toBeInstanceOf(ls); + expect(litNodeClient.config.storageProvider?.provider).toBeInstanceOf( + LocalStorage + ); + + //@ts-expect-error redefine ls Object.defineProperty(globalThis, 'localStorage', { value: tmp }); }); diff --git a/packages/logger/src/lib/logger.spec.ts b/packages/logger/src/lib/logger.spec.ts index cfa72d8d48..528af1e59b 100644 --- a/packages/logger/src/lib/logger.spec.ts +++ b/packages/logger/src/lib/logger.spec.ts @@ -1,10 +1,18 @@ -import { Logger, LogLevel, LogManager } from './logger'; +import { LogLevel, LogManager } from './logger'; describe('logger', () => { let lm: LogManager; beforeEach(() => { LogManager.clearInstance(); lm = LogManager.Instance; + + jest.spyOn(console, 'warn').mockImplementation(jest.fn()); + jest.spyOn(console, 'info').mockImplementation(jest.fn()); + jest.spyOn(console, 'debug').mockImplementation(jest.fn()); + jest.spyOn(console, 'error').mockImplementation(jest.fn()); + jest.spyOn(console, 'timeLog').mockImplementation(jest.fn()); + jest.spyOn(console, 'time').mockImplementation(jest.fn()); + jest.spyOn(console, 'log').mockImplementation(jest.fn()); }); it('Log Manager singleton should be defined', () => { @@ -122,7 +130,7 @@ describe('logger', () => { const requestIds = lm.LoggerIds; expect(requestIds.length).toBe(2); - expect(loggerA.timestamp).toEqual(requestIds[0]); - expect(loggerB.timestamp).toEqual(requestIds[1]); + expect(loggerA.id).toEqual(requestIds[0]); + expect(loggerB.id).toEqual(requestIds[1]); }); }); diff --git a/packages/pkp-walletconnect/src/lib/pkp-walletconnect.spec.ts b/packages/pkp-walletconnect/src/lib/pkp-walletconnect.spec.ts index 9e3b10aedf..be19e80914 100644 --- a/packages/pkp-walletconnect/src/lib/pkp-walletconnect.spec.ts +++ b/packages/pkp-walletconnect/src/lib/pkp-walletconnect.spec.ts @@ -1,13 +1,14 @@ // @ts-expect-error - set global variable for testing global.jestTesting = true; -import * as LITCONFIG from 'lit.config.json'; -import { PKPClient } from '@lit-protocol/pkp-client'; import { Core } from '@walletconnect/core'; import { SignClientTypes } from '@walletconnect/types'; import { getSdkError } from '@walletconnect/utils'; import { Web3Wallet } from '@walletconnect/web3wallet'; +import { LitNodeClientNodeJs } from '@lit-protocol/lit-node-client-nodejs'; +import { PKPClient } from '@lit-protocol/pkp-client'; + import { PKPWalletConnect } from './pkp-walletconnect'; const LITCONFIG = { @@ -40,6 +41,7 @@ describe('PKPWalletConnect', () => { controllerAuthSig: LITCONFIG.CONTROLLER_AUTHSIG, pkpPubKey: PKP_PUBKEY, cosmosAddressPrefix: 'cosmos', + litNodeClient: new LitNodeClientNodeJs({ litNetwork: 'cayenne' }), }); pkpWalletConnect = new PKPWalletConnect(true); diff --git a/packages/tinny/.eslintrc.json b/packages/tinny/.eslintrc.json new file mode 100644 index 0000000000..adbe7ae2df --- /dev/null +++ b/packages/tinny/.eslintrc.json @@ -0,0 +1,25 @@ +{ + "extends": ["../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "@nx/dependency-checks": "error" + } + } + ] +} diff --git a/packages/tinny/README.md b/packages/tinny/README.md new file mode 100644 index 0000000000..60a09abfe3 --- /dev/null +++ b/packages/tinny/README.md @@ -0,0 +1,11 @@ +# tinny + +This library was generated with [Nx](https://nx.dev). + +## Building + +Run `nx build tinny` to build the library. + +## Running unit tests + +Run `nx test tinny` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/packages/tinny/jest.config.ts b/packages/tinny/jest.config.ts new file mode 100644 index 0000000000..04643a7ef0 --- /dev/null +++ b/packages/tinny/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: 'tinny', + preset: '../../jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../coverage/packages/tinny', +}; diff --git a/packages/tinny/package.json b/packages/tinny/package.json new file mode 100644 index 0000000000..698ac00060 --- /dev/null +++ b/packages/tinny/package.json @@ -0,0 +1,11 @@ +{ + "name": "@lit-protocol/tinny", + "version": "6.10.0", + "private": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "type": "commonjs", + "main": "./dist/src/index.js", + "typings": "./dist/src/index.d.ts" +} diff --git a/packages/tinny/project.json b/packages/tinny/project.json new file mode 100644 index 0000000000..79939cafc0 --- /dev/null +++ b/packages/tinny/project.json @@ -0,0 +1,33 @@ +{ + "name": "tinny", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "packages/tinny/src", + "projectType": "library", + "targets": { + "build": { + "executor": "@nx/js:tsc", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/packages/tinny", + "main": "packages/tinny/src/index.ts", + "tsConfig": "packages/tinny/tsconfig.lib.json", + "assets": ["packages/tinny/*.md"] + } + }, + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["packages/logger/**/*.ts"] + } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "packages/tinny/jest.config.ts" + } + } + }, + "tags": [] +} diff --git a/packages/tinny/src/index.ts b/packages/tinny/src/index.ts new file mode 100644 index 0000000000..bf1cd525e1 --- /dev/null +++ b/packages/tinny/src/index.ts @@ -0,0 +1,31 @@ +import { AccessControlConditions } from './lib/accs/accs'; +import { + getEoaSessionSigs, + getEoaSessionSigsWithCapacityDelegations, +} from './lib/session-sigs/get-eoa-session-sigs'; +import { + getLitActionSessionSigs, + getLitActionSessionSigsUsingIpfsId, + getInvalidLitActionIpfsSessionSigs, + getInvalidLitActionSessionSigs, +} from './lib/session-sigs/get-lit-action-session-sigs'; +import { getPkpSessionSigs } from './lib/session-sigs/get-pkp-session-sigs'; +import { ShivaClient } from './lib/shiva-client'; +import { LIT_TESTNET } from './lib/tinny-config'; +import { TinnyEnvironment } from './lib/tinny-environment'; +import { TinnyPerson } from './lib/tinny-person'; + +export { + LIT_TESTNET, + TinnyEnvironment, + TinnyPerson, + ShivaClient, + getEoaSessionSigs, + getEoaSessionSigsWithCapacityDelegations, + getPkpSessionSigs, + getInvalidLitActionIpfsSessionSigs, + getInvalidLitActionSessionSigs, + getLitActionSessionSigs, + getLitActionSessionSigsUsingIpfsId, + AccessControlConditions, +}; diff --git a/local-tests/setup/accs/accs.ts b/packages/tinny/src/lib/accs/accs.ts similarity index 93% rename from local-tests/setup/accs/accs.ts rename to packages/tinny/src/lib/accs/accs.ts index ff7c66564e..db07c7dec1 100644 --- a/local-tests/setup/accs/accs.ts +++ b/packages/tinny/src/lib/accs/accs.ts @@ -7,6 +7,8 @@ import { export namespace AccessControlConditions { export const getEmvBasicAccessControlConditions = ({ userAddress, + }: { + userAddress: string; }): LPACC_EVM_BASIC[] => { return [ { @@ -25,6 +27,8 @@ export namespace AccessControlConditions { export const getSolBasicAccessControlConditions = ({ userAddress, + }: { + userAddress: string; }): LPACC_SOL[] => { return [ { @@ -45,6 +49,8 @@ export namespace AccessControlConditions { export const getCosmosBasicAccessControlConditions = ({ userAddress, + }: { + userAddress: string; }): LPACC_EVM_ATOM[] => { return [ { diff --git a/local-tests/setup/networkContext.example.json b/packages/tinny/src/lib/networkContext.example.json similarity index 100% rename from local-tests/setup/networkContext.example.json rename to packages/tinny/src/lib/networkContext.example.json diff --git a/local-tests/setup/networkContext.json b/packages/tinny/src/lib/networkContext.json similarity index 100% rename from local-tests/setup/networkContext.json rename to packages/tinny/src/lib/networkContext.json diff --git a/local-tests/setup/session-sigs/get-eoa-session-sigs.ts b/packages/tinny/src/lib/session-sigs/get-eoa-session-sigs.ts similarity index 76% rename from local-tests/setup/session-sigs/get-eoa-session-sigs.ts rename to packages/tinny/src/lib/session-sigs/get-eoa-session-sigs.ts index 68c060f01d..ffea35fbae 100644 --- a/local-tests/setup/session-sigs/get-eoa-session-sigs.ts +++ b/packages/tinny/src/lib/session-sigs/get-eoa-session-sigs.ts @@ -1,20 +1,22 @@ +import { ethers } from 'ethers'; + import { LitActionResource, LitPKPResource, generateAuthSig, createSiweMessageWithRecaps, } from '@lit-protocol/auth-helpers'; +import { LitNetwork } from '@lit-protocol/constants'; +import { log } from '@lit-protocol/misc'; import { AuthCallbackParams, AuthSig, LitAbility, LitResourceAbilityRequest, } from '@lit-protocol/types'; -import { log } from '@lit-protocol/misc'; -import { ethers } from 'ethers'; -import { CENTRALISATION_BY_NETWORK, LitNetwork } from '@lit-protocol/constants'; -import { TinnyPerson } from '../tinny-person'; + import { TinnyEnvironment } from '../tinny-environment'; +import { TinnyPerson } from '../tinny-person'; /** * Retrieves the session signatures for an EOA in a given Tinny environment. @@ -29,12 +31,9 @@ export const getEoaSessionSigs = async ( person: TinnyPerson, resourceAbilityRequests?: LitResourceAbilityRequest[] ) => { - const centralisation = - CENTRALISATION_BY_NETWORK[devEnv.litNodeClient.config.litNetwork]; - - if (centralisation === 'decentralised') { + if (devEnv.litNodeClient?.config.litNetwork === LitNetwork.Manzano) { console.warn( - 'Decentralised network detected. Adding superCapacityDelegationAuthSig to eoaSessionSigs' + 'Manzano network detected. Adding capacityDelegationAuthSig to eoaSessionSigs' ); } @@ -50,7 +49,7 @@ export const getEoaSessionSigs = async ( }, ]; - const sessionSigs = await devEnv.litNodeClient.getSessionSigs({ + const sessionSigs = await devEnv.litNodeClient?.getSessionSigs({ chain: 'ethereum', resourceAbilityRequests: _resourceAbilityRequests, authNeededCallback: async ({ @@ -77,7 +76,8 @@ export const getEoaSessionSigs = async ( expiration: expiration, resources: resourceAbilityRequests, walletAddress: person.wallet.address, - nonce: await devEnv.litNodeClient.getLatestBlockhash(), + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain + nonce: await devEnv.litNodeClient?.getLatestBlockhash()!, litNodeClient: devEnv.litNodeClient, }); @@ -89,10 +89,11 @@ export const getEoaSessionSigs = async ( return authSig; }, - ...(centralisation === 'decentralised' && { - capabilityAuthSigs: [devEnv.superCapacityDelegationAuthSig], - }), - }); + // -- only add this for manzano network because of rate limiting + ...(devEnv.litNodeClient.config.litNetwork === LitNetwork.Manzano + ? { capabilityAuthSigs: [devEnv.superCapacityDelegationAuthSig] } + : {}), + } as any); // todo: remove any cast log('[getEoaSessionSigs]: ', getEoaSessionSigs); @@ -104,16 +105,7 @@ export const getEoaSessionSigsWithCapacityDelegations = async ( fromWallet: ethers.Wallet, capacityDelegationAuthSig: AuthSig ) => { - const centralisation = - CENTRALISATION_BY_NETWORK[devEnv.litNodeClient.config.litNetwork]; - - if (centralisation === 'decentralised') { - console.warn( - 'Decentralised network detected. Adding superCapacityDelegationAuthSig to eoaSessionSigs' - ); - } - - const sessionSigs = await devEnv.litNodeClient.getSessionSigs({ + const sessionSigs = await devEnv.litNodeClient?.getSessionSigs({ chain: 'ethereum', resourceAbilityRequests: [ { @@ -147,7 +139,8 @@ export const getEoaSessionSigsWithCapacityDelegations = async ( expiration: expiration, resources: resourceAbilityRequests, walletAddress: fromWallet.address, - nonce: await devEnv.litNodeClient.getLatestBlockhash(), + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain + nonce: await devEnv.litNodeClient?.getLatestBlockhash()!, litNodeClient: devEnv.litNodeClient, }); @@ -158,11 +151,7 @@ export const getEoaSessionSigsWithCapacityDelegations = async ( return authSig; }, - ...(centralisation === 'decentralised' && { - capabilityAuthSigs: [ - capacityDelegationAuthSig ?? devEnv.superCapacityDelegationAuthSig, - ], - }), + capacityDelegationAuthSig: capacityDelegationAuthSig, }); log('[getEoaSessionSigs]: ', getEoaSessionSigs); diff --git a/local-tests/setup/session-sigs/get-lit-action-session-sigs.ts b/packages/tinny/src/lib/session-sigs/get-lit-action-session-sigs.ts similarity index 65% rename from local-tests/setup/session-sigs/get-lit-action-session-sigs.ts rename to packages/tinny/src/lib/session-sigs/get-lit-action-session-sigs.ts index a3c85bdda6..0ac832f0dc 100644 --- a/local-tests/setup/session-sigs/get-lit-action-session-sigs.ts +++ b/packages/tinny/src/lib/session-sigs/get-lit-action-session-sigs.ts @@ -1,5 +1,8 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ import { LitActionResource, LitPKPResource } from '@lit-protocol/auth-helpers'; +import { LitNetwork } from '@lit-protocol/constants'; import { LitAbility, LitResourceAbilityRequest } from '@lit-protocol/types'; + import { CENTRALISATION_BY_NETWORK, GLOBAL_OVERWRITE_IPFS_CODE_BY_NETWORK, @@ -39,12 +42,9 @@ export const getLitActionSessionSigs = async ( alice: TinnyPerson, resourceAbilityRequests?: LitResourceAbilityRequest[] ) => { - const centralisation = - CENTRALISATION_BY_NETWORK[devEnv.litNodeClient.config.litNetwork]; - - if (centralisation === 'decentralised') { + if (devEnv.litNodeClient?.config.litNetwork === LitNetwork.Manzano) { console.warn( - 'Decentralised network detected. Adding superCapacityDelegationAuthSig to eoaSessionSigs' + 'Manzano network detected. Adding capacityDelegationAuthSig to litActionSessionSigs' ); } @@ -61,21 +61,23 @@ export const getLitActionSessionSigs = async ( ]; const litActionSessionSigs = - await devEnv.litNodeClient.getLitActionSessionSigs({ - pkpPublicKey: alice.authMethodOwnedPkp.publicKey, - authMethods: [alice.authMethod], + await devEnv.litNodeClient?.getLitActionSessionSigs({ + // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain + pkpPublicKey: alice.authMethodOwnedPkp?.publicKey!, + authMethods: [alice.authMethod!], resourceAbilityRequests: _resourceAbilityRequests, litActionCode: Buffer.from(VALID_SESSION_SIG_LIT_ACTION_CODE).toString( 'base64' ), jsParams: { - publicKey: alice.authMethodOwnedPkp.publicKey, + publicKey: alice.authMethodOwnedPkp?.publicKey, sigName: 'unified-auth-sig', }, - ...(centralisation === 'decentralised' && { - capabilityAuthSigs: [devEnv.superCapacityDelegationAuthSig], - }), + // -- only add this for manzano network + ...(devEnv.litNodeClient.config.litNetwork === LitNetwork.Manzano + ? { capacityDelegationAuthSig: devEnv.superCapacityDelegationAuthSig } + : {}), }); return litActionSessionSigs; @@ -86,12 +88,9 @@ export const getLitActionSessionSigsUsingIpfsId = async ( alice: TinnyPerson, resourceAbilityRequests?: LitResourceAbilityRequest[] ) => { - const centralisation = - CENTRALISATION_BY_NETWORK[devEnv.litNodeClient.config.litNetwork]; - - if (centralisation === 'decentralised') { + if (devEnv.litNodeClient?.config.litNetwork === LitNetwork.Manzano) { console.warn( - 'Decentralised network detected. Adding superCapacityDelegationAuthSig to eoaSessionSigs' + 'Manzano network detected. Adding capacityDelegationAuthSig to litActionSessionSigs' ); } @@ -107,19 +106,21 @@ export const getLitActionSessionSigsUsingIpfsId = async ( }, ]; - const litActionSessionSigs = await devEnv.litNodeClient.getPkpSessionSigs({ - pkpPublicKey: alice.authMethodOwnedPkp.publicKey, - authMethods: [alice.authMethod], + const litActionSessionSigs = await devEnv.litNodeClient?.getPkpSessionSigs({ + // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain + pkpPublicKey: alice.authMethodOwnedPkp?.publicKey!, + authMethods: [alice.authMethod!], resourceAbilityRequests: _resourceAbilityRequests, litActionIpfsId: VALID_IPFS_ID, jsParams: { - publicKey: alice.authMethodOwnedPkp.publicKey, + publicKey: alice.authMethodOwnedPkp!.publicKey, sigName: 'unified-auth-sig', }, - ...(centralisation === 'decentralised' && { - capabilityAuthSigs: [devEnv.superCapacityDelegationAuthSig], - }), + // -- only add this for manzano network + ...(devEnv.litNodeClient.config.litNetwork === LitNetwork.Manzano + ? { capacityDelegationAuthSig: devEnv.superCapacityDelegationAuthSig } + : {}), }); return litActionSessionSigs; @@ -129,9 +130,10 @@ export const getInvalidLitActionSessionSigs = async ( devEnv: TinnyEnvironment, alice: TinnyPerson ) => { - const litActionSessionSigs = await devEnv.litNodeClient.getPkpSessionSigs({ - pkpPublicKey: alice.authMethodOwnedPkp.publicKey, - authMethods: [alice.authMethod], + const litActionSessionSigs = await devEnv.litNodeClient?.getPkpSessionSigs({ + // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain + pkpPublicKey: alice.authMethodOwnedPkp?.publicKey!, + authMethods: [alice.authMethod!], resourceAbilityRequests: [ { resource: new LitPKPResource('*'), @@ -142,7 +144,7 @@ export const getInvalidLitActionSessionSigs = async ( 'base64' ), jsParams: { - publicKey: alice.authMethodOwnedPkp.publicKey, + publicKey: alice.authMethodOwnedPkp?.publicKey, sigName: 'unified-auth-sig', }, ipfsOptions: { @@ -160,9 +162,10 @@ export const getInvalidLitActionIpfsSessionSigs = async ( devEnv: TinnyEnvironment, alice: TinnyPerson ) => { - const litActionSessionSigs = await devEnv.litNodeClient.getPkpSessionSigs({ - pkpPublicKey: alice.authMethodOwnedPkp.publicKey, - authMethods: [alice.authMethod], + const litActionSessionSigs = await devEnv.litNodeClient?.getPkpSessionSigs({ + // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain + pkpPublicKey: alice.authMethodOwnedPkp?.publicKey!, + authMethods: [alice.authMethod!], resourceAbilityRequests: [ { resource: new LitPKPResource('*'), @@ -171,7 +174,7 @@ export const getInvalidLitActionIpfsSessionSigs = async ( ], litActionIpfsId: INVALID_IPFS_ID, jsParams: { - publicKey: alice.authMethodOwnedPkp.publicKey, + publicKey: alice.authMethodOwnedPkp?.publicKey, sigName: 'unified-auth-sig', }, ipfsOptions: { diff --git a/local-tests/setup/session-sigs/get-pkp-session-sigs.ts b/packages/tinny/src/lib/session-sigs/get-pkp-session-sigs.ts similarity index 62% rename from local-tests/setup/session-sigs/get-pkp-session-sigs.ts rename to packages/tinny/src/lib/session-sigs/get-pkp-session-sigs.ts index 99097085fe..2f547248cb 100644 --- a/local-tests/setup/session-sigs/get-pkp-session-sigs.ts +++ b/packages/tinny/src/lib/session-sigs/get-pkp-session-sigs.ts @@ -1,7 +1,8 @@ import { LitActionResource, LitPKPResource } from '@lit-protocol/auth-helpers'; -import { LitAbility, LitResourceAbilityRequest } from '@lit-protocol/types'; +import { LitNetwork } from '@lit-protocol/constants'; import { log } from '@lit-protocol/misc'; -import { CENTRALISATION_BY_NETWORK, LitNetwork } from '@lit-protocol/constants'; +import { LitAbility, LitResourceAbilityRequest } from '@lit-protocol/types'; + import { TinnyEnvironment } from '../tinny-environment'; import { TinnyPerson } from '../tinny-person'; @@ -11,12 +12,9 @@ export const getPkpSessionSigs = async ( resourceAbilityRequests?: LitResourceAbilityRequest[], expiration?: string ) => { - const centralisation = - CENTRALISATION_BY_NETWORK[devEnv.litNodeClient.config.litNetwork]; - - if (centralisation === 'decentralised') { + if (devEnv.litNodeClient?.config.litNetwork === LitNetwork.Manzano) { console.warn( - 'Decentralised network detected. Adding superCapacityDelegationAuthSig to eoaSessionSigs' + 'Manzano network detected. Adding capacityDelegationAuthSig to pkpSessionSigs' ); } @@ -32,15 +30,16 @@ export const getPkpSessionSigs = async ( }, ]; - const pkpSessionSigs = await devEnv.litNodeClient.getPkpSessionSigs({ - pkpPublicKey: alice.authMethodOwnedPkp.publicKey, - authMethods: [alice.authMethod], + const pkpSessionSigs = await devEnv.litNodeClient?.getPkpSessionSigs({ + pkpPublicKey: alice.authMethodOwnedPkp?.publicKey!, + authMethods: [alice.authMethod!], expiration, resourceAbilityRequests: _resourceAbilityRequests, - ...(centralisation === 'decentralised' && { - capabilityAuthSigs: [devEnv.superCapacityDelegationAuthSig], - }), + // -- only add this for manzano network + ...(devEnv.litNodeClient.config.litNetwork === LitNetwork.Manzano + ? { capacityDelegationAuthSig: devEnv.superCapacityDelegationAuthSig } + : {}), }); log('[getPkpSessionSigs]: ', pkpSessionSigs); diff --git a/local-tests/setup/shiva-client.d.ts b/packages/tinny/src/lib/shiva-client.d.ts similarity index 85% rename from local-tests/setup/shiva-client.d.ts rename to packages/tinny/src/lib/shiva-client.d.ts index 7bb27c17a6..babd930377 100644 --- a/local-tests/setup/shiva-client.d.ts +++ b/packages/tinny/src/lib/shiva-client.d.ts @@ -1,5 +1,5 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -type ContractAbis = { +interface ContractAbis { litToken: string; erc20: string; backupRecovery: string; @@ -12,9 +12,9 @@ type ContractAbis = { pkpHelper: string; contractResolver: string; paymentDelegation: string; -}; +} -type ContractAddresses = { +interface ContractAddresses { litToken: string; backupRecovery: string; staking: string; @@ -27,9 +27,9 @@ type ContractAddresses = { contractResolver: string; keyDeriver: string; paymentDelegation: string; -}; +} -type TestNetCreateRequest = { +interface TestNetCreateRequest { nodeCount: number; pollingInterval: string; epochLength: number; @@ -39,26 +39,26 @@ type TestNetCreateRequest = { which: string | null; ecdsaRoundTimeout: string | null; enableRateLimiting: string | null; -}; +} -type TestNetInfo = { +interface TestNetInfo { contractAddresses: ContractAddresses; - validatorAddresses: Array; + validatorAddresses: string[]; contractResolverAbi: string; rpcUrl: string; epochLength: number; contractAbis: ContractAbis; -}; +} -type TestNetResponse = { +interface TestNetResponse { testnetId: string; command: string; wasCanceled: boolean; body: T | null; lastStateObserved: string | null; - messages: Array | null; - errors: Array | null; -}; + messages: string[] | null; + errors: string[] | null; +} type TestNetState = 'Busy' | 'Active' | 'Mutating' | 'Shutdown' | 'UNKNOWN'; diff --git a/local-tests/setup/shiva-client.ts b/packages/tinny/src/lib/shiva-client.ts similarity index 88% rename from local-tests/setup/shiva-client.ts rename to packages/tinny/src/lib/shiva-client.ts index fbf1075179..941cff7e11 100644 --- a/local-tests/setup/shiva-client.ts +++ b/packages/tinny/src/lib/shiva-client.ts @@ -1,6 +1,7 @@ -import { LitContractResolverContext } from '@lit-protocol/types'; import { ethers } from 'ethers'; -import { PKPPermissions } from '../../dist/packages/contracts-sdk/src/abis/PKPPermissions.sol/PKPPermissions'; + +import { LitContractResolverContext } from '@lit-protocol/types'; + import { TestNetCreateRequest, TestNetInfo, @@ -9,8 +10,17 @@ import { } from './shiva-client.d'; class ShivaError extends Error { + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(shivaResponse: TestNetResponse) { let message = `An error occurred on request to testnet with id: ${shivaResponse.testnetId}`; + + if (!shivaResponse.errors) { + super(message); + this.name = 'ShivaError'; + + return; + } + for (const error of shivaResponse.errors) { message += ' ' + error; } @@ -62,10 +72,10 @@ export interface ShivaEnvs { * on the network from the implementation within this class. Each testnet is a unique network */ export class TestnetClient { - private _id: string; - private _info: TestNetInfo; - private _processEnvs: ShivaEnvs; - private _currentState: TestNetState; + private _id: string | undefined; + private _info: TestNetInfo | undefined; + private _processEnvs: ShivaEnvs | undefined; + private _currentState: TestNetState | undefined; constructor(id: string, envs: ShivaEnvs) { this._processEnvs = envs; @@ -135,14 +145,16 @@ export class TestnetClient { let state = 'Busy'; while (state != 'Active' && state != `UNKNOWN`) { const res = await fetch( - this._processEnvs.TESTNET_MANAGER_URL + '/test/poll/testnet/' + this._id + this._processEnvs?.TESTNET_MANAGER_URL + + '/test/poll/testnet/' + + this._id ); const stateRes: TestNetResponse = await _processTestnetResponse(res); - state = stateRes.body; + state = stateRes.body as TestNetState; console.log('found state to be', state); - await new Promise((res, _) => { + await new Promise((res) => { setTimeout(() => { res(); }, 500); @@ -157,13 +169,13 @@ export class TestnetClient { */ public async getTestnetConfig() { const res = await fetch( - this._processEnvs.TESTNET_MANAGER_URL + + this._processEnvs?.TESTNET_MANAGER_URL + '/test/get/info/testnet/' + this._id ); const testnetInfoRes = await _processTestnetResponse(res); - this._info = testnetInfoRes.body; + this._info = testnetInfoRes.body as TestNetInfo; return testnetInfoRes; } @@ -174,12 +186,12 @@ export class TestnetClient { */ public async transitionEpochAndWait() { const res = await fetch( - this._processEnvs.TESTNET_MANAGER_URL + + this._processEnvs?.TESTNET_MANAGER_URL + '/test/action/transition/epoch/wait/' + this._id ); - let transitionEpochAndWaitRes = _processTestnetResponse(res); + const transitionEpochAndWaitRes = _processTestnetResponse(res); return transitionEpochAndWaitRes; } @@ -190,7 +202,7 @@ export class TestnetClient { */ public async stopRandomNetworkPeerAndWaitForNextEpoch() { const res = await fetch( - this._processEnvs.TESTNET_MANAGER_URL + + this._processEnvs?.TESTNET_MANAGER_URL + '/test/action/stop/random/wait/' + this._id ); @@ -204,7 +216,9 @@ export class TestnetClient { public async stopTestnet() { console.log('stopping testnet with id:', this._id); const res = await fetch( - this._processEnvs.TESTNET_MANAGER_URL + '/test/delete/testnet/' + this._id + this._processEnvs?.TESTNET_MANAGER_URL + + '/test/delete/testnet/' + + this._id ); return _processTestnetResponse(res); @@ -248,7 +262,7 @@ export class ShivaClient { existingTestnets[0], new TestnetClient(existingTestnets[0], this.processEnvs) ); - return this._clients.get(existingTestnets[0]); + return this._clients.get(existingTestnets[0]) as TestnetClient; } else { console.log( 'lit node binary path: ', @@ -258,7 +272,7 @@ export class ShivaClient { 'lit action server binary path: ', this.processEnvs.LIT_ACTION_BINARY_PATH ); - let body: Partial = createReq ?? { + const body: Partial = createReq ?? { nodeCount: 3, pollingInterval: '2000', epochLength: 90_000, @@ -290,7 +304,7 @@ export class ShivaClient { new TestnetClient(createTestnet.testnetId, this.processEnvs) ); - return this._clients.get(createTestnet.testnetId); + return this._clients.get(createTestnet.testnetId) as TestnetClient; } } } @@ -302,7 +316,7 @@ async function _processTestnetResponse( try { createTestnet = (await response.json()) as TestNetResponse; } catch (err) { - let message = await response.text(); + const message = await response.text(); throw new Error('Error while performing testnet request: ' + message); } diff --git a/local-tests/setup/tinny-config.ts b/packages/tinny/src/lib/tinny-config.ts similarity index 96% rename from local-tests/setup/tinny-config.ts rename to packages/tinny/src/lib/tinny-config.ts index 8ebf013197..8bba8c8ce1 100644 --- a/local-tests/setup/tinny-config.ts +++ b/packages/tinny/src/lib/tinny-config.ts @@ -2,17 +2,17 @@ import { LitNodeClient } from '@lit-protocol/lit-node-client'; import { LitContractResolverContext } from '@lit-protocol/types'; export enum LIT_TESTNET { - LOCALCHAIN = 'localchain', + LOCALCHAIN = 'custom', MANZANO = 'manzano', CAYENNE = 'cayenne', DATIL_DEV = 'datil-dev', DATIL_TEST = 'datil-test', - DATIL_PROD = 'datil', } export enum LIT_RPC { LOCAL_ANVIL = 'http://127.0.0.1:8545', CHRONICLE = 'https://chain-rpc.litprotocol.com/http', + VESUVIUS = 'https://vesuvius-rpc.litprotocol.com', YELLOWSTONE = 'https://yellowstone-rpc.litprotocol.com', } @@ -25,7 +25,6 @@ export const RPC_MAP = { [LIT_TESTNET.CAYENNE]: LIT_RPC.CHRONICLE, [LIT_TESTNET.DATIL_DEV]: LIT_RPC.YELLOWSTONE, [LIT_TESTNET.DATIL_TEST]: LIT_RPC.YELLOWSTONE, - [LIT_TESTNET.DATIL_PROD]: LIT_RPC.YELLOWSTONE, }; /** @@ -128,11 +127,11 @@ export interface ProcessEnvs { /** * Represents the PKP information. */ -export type PKPInfo = { +export interface PKPInfo { tokenId: string; publicKey: string; ethAddress: string; -}; +} export interface TinnyEnvConfig { rpc: string; diff --git a/local-tests/setup/tinny-environment.ts b/packages/tinny/src/lib/tinny-environment.ts similarity index 85% rename from local-tests/setup/tinny-environment.ts rename to packages/tinny/src/lib/tinny-environment.ts index 50c2c5552c..9385c0d5e0 100644 --- a/local-tests/setup/tinny-environment.ts +++ b/packages/tinny/src/lib/tinny-environment.ts @@ -1,11 +1,9 @@ -import { - LIT_TESTNET, - ProcessEnvs, - RPC_MAP, - TinnyEnvConfig, -} from './tinny-config'; -import { LitNodeClient } from '@lit-protocol/lit-node-client'; +import { ethers, Signer } from 'ethers'; + +import { createSiweMessage, generateAuthSig } from '@lit-protocol/auth-helpers'; +import { CENTRALISATION_BY_NETWORK } from '@lit-protocol/constants'; import { LitContracts } from '@lit-protocol/contracts-sdk'; +import { LitNodeClient } from '@lit-protocol/lit-node-client'; import { AuthSig, CosmosAuthSig, @@ -13,13 +11,17 @@ import { LitContractResolverContext, SolanaAuthSig, } from '@lit-protocol/types'; -import { TinnyPerson } from './tinny-person'; -import { ethers, Signer } from 'ethers'; -import { createSiweMessage, generateAuthSig } from '@lit-protocol/auth-helpers'; import { ShivaClient, TestnetClient } from './shiva-client'; +import { + LIT_TESTNET, + ProcessEnvs, + RPC_MAP, + TinnyEnvConfig, +} from './tinny-config'; +// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries import { toErrorWithMessage } from './tinny-utils'; -import { CENTRALISATION_BY_NETWORK } from '@lit-protocol/constants'; +import { TinnyPerson } from '../index'; console.log('checking env', process.env['DEBUG']); export class TinnyEnvironment { @@ -29,26 +31,27 @@ export class TinnyEnvironment { * Environment variables used in the process. */ public processEnvs: ProcessEnvs = { - MAX_ATTEMPTS: parseInt(process.env['MAX_ATTEMPTS']) || 1, - TEST_TIMEOUT: parseInt(process.env['TEST_TIMEOUT']) || 45000, + MAX_ATTEMPTS: parseInt(process.env['MAX_ATTEMPTS']!) || 1, + TEST_TIMEOUT: parseInt(process.env['TEST_TIMEOUT']!) || 45000, NETWORK: (process.env['NETWORK'] as LIT_TESTNET) || LIT_TESTNET.LOCALCHAIN, DEBUG: process.env['DEBUG'] === 'true', REQUEST_PER_KILOSECOND: - parseInt(process.env['REQUEST_PER_KILOSECOND']) || + parseInt(process.env['REQUEST_PER_KILOSECOND']!) || (process.env['NETWORK'] as LIT_TESTNET) === 'datil-dev' ? 1 : 200, - LIT_RPC_URL: process.env['LIT_RPC_URL'], + LIT_RPC_URL: process.env['LIT_RPC_URL']!, WAIT_FOR_KEY_INTERVAL: - parseInt(process.env['WAIT_FOR_KEY_INTERVAL']) || 3000, + parseInt(process.env['WAIT_FOR_KEY_INTERVAL']!) || 3000, BOOTSTRAP_URLS: process.env['BOOTSTRAP_URLS']?.split(',') || [ 'http://127.0.0.1:7470', 'http://127.0.0.1:7471', 'http://127.0.0.1:7472', ], - TIME_TO_RELEASE_KEY: parseInt(process.env['TIME_TO_RELEASE_KEY']) || 10000, + TIME_TO_RELEASE_KEY: parseInt(process.env['TIME_TO_RELEASE_KEY']!) || 10000, RUN_IN_BAND: process.env['RUN_IN_BAND'] === 'true', - RUN_IN_BAND_INTERVAL: parseInt(process.env['RUN_IN_BAND_INTERVAL']) || 5000, + RUN_IN_BAND_INTERVAL: + parseInt(process.env['RUN_IN_BAND_INTERVAL']!) || 5000, // Available Accounts // ================== @@ -72,17 +75,17 @@ export class TinnyEnvironment { '0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97', '0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6', ], - KEY_IN_USE: new Array(), + KEY_IN_USE: [], NO_SETUP: process.env['NO_SETUP'] === 'true', USE_SHIVA: process.env['USE_SHIVA'] === 'true', NETWORK_CONFIG: process.env['NETWORK_CONFIG'] ?? './networkContext.json', }; - public litNodeClient: LitNodeClient; - public contractsClient: LitContracts; + public litNodeClient: LitNodeClient | undefined; + public contractsClient: LitContracts | undefined; public rpc: string; - public superCapacityDelegationAuthSig: AuthSig; - public bareEthAuthSig: AuthSig; + public superCapacityDelegationAuthSig: AuthSig | undefined; + public bareEthAuthSig: AuthSig | undefined; public bareSolAuthSig: SolanaAuthSig = { sig: '706047fcab06ada3cbfeb6990617c1705d59bafb20f5f1c8103d764fb5eaec297328d164e2b891095866b28acc1ab2df288a8729cf026228ef3c4970238b190a', derivedVia: 'solana.signMessage', @@ -102,7 +105,10 @@ export class TinnyEnvironment { public testnet: TestnetClient | undefined; //=========== PRIVATE MEMBERS =========== private _shivaClient: ShivaClient = new ShivaClient(); - private _contractContext: LitContractContext | LitContractResolverContext; + private _contractContext: + | LitContractContext + | LitContractResolverContext + | undefined; constructor(network?: LIT_TESTNET) { // -- setup networkj @@ -146,7 +152,7 @@ export class TinnyEnvironment { ); } - world: Map = new Map(); + world: Map = new Map(); /** * Retrieves an available private key from a list, marking it as in use and scheduling @@ -170,6 +176,7 @@ export class TinnyEnvironment { privateKey: string; index: number; }> { + // eslint-disable-next-line no-constant-condition while (true) { const index = this.processEnvs.KEY_IN_USE.findIndex((used) => !used); // Find the first unused key @@ -273,7 +280,8 @@ export class TinnyEnvironment { ); } - if (globalThis.wasmSevSnpUtils) { + // @ts-expect-error property is defined on globalThis + if (globalThis['wasmSevSnpUtils']) { console.warn( 'WASM modules already loaded. wil overide. when connect is called' ); @@ -283,7 +291,7 @@ export class TinnyEnvironment { if (!this.litNodeClient.ready) { console.error('❌ litNodeClient not ready'); - process.exit(); + process.exit(1); } } @@ -296,7 +304,7 @@ export class TinnyEnvironment { this?.testnet?.ContractContext ?? this._contractContext; return { rpc: this.rpc, - litNodeClient: this.litNodeClient, + litNodeClient: this.litNodeClient!, network: this.network, processEnvs: this.processEnvs, contractContext: contractContext as LitContractResolverContext, @@ -349,8 +357,10 @@ export class TinnyEnvironment { setUnavailable = (network: LIT_TESTNET) => { if (this.processEnvs.NETWORK === network) { - throw new Error('LIT_IGNORE_TEST'); + return true; } + + return false; }; /** @@ -368,7 +378,7 @@ export class TinnyEnvironment { ) { this.testnet = await this._shivaClient.startTestnetManager(); // wait for the testnet to be active before we start the tests. - let state = await this.testnet.pollTestnetForActive(); + const state = await this.testnet.pollTestnetForActive(); if (state === `UNKNOWN`) { console.log( 'Testnet state found to be Unknown meaning there was an error with testnet creation. shutting down' @@ -406,7 +416,7 @@ export class TinnyEnvironment { const toSign = await createSiweMessage({ walletAddress: wallet.address, - nonce: await this.litNodeClient.getLatestBlockhash(), + nonce: (await this?.litNodeClient?.getLatestBlockhash()) ?? '', expiration: new Date( Date.now() + 29 * 24 * 60 * 60 * 1000 ).toISOString(), @@ -432,7 +442,7 @@ export class TinnyEnvironment { this.network === LIT_TESTNET.LOCALCHAIN && this._shivaClient.processEnvs.STOP_TESTNET ) { - await this.testnet.stopTestnet(); + await this.testnet?.stopTestnet(); } else { console.log('skipping testnet shutdown.'); } @@ -503,25 +513,6 @@ export class TinnyEnvironment { // THE FOLLOWING WILL TECHNICALLY NEVER BE CALLED, BUT IT'S HERE FOR FUTURE REFERENCE FOR SWITCHING WALLETS else { - async function _switchWallet() { - // TODO: This wallet should be cached somehwere and reused to create delegation signatures. - // There is a correlation between the number of Capacity Credit NFTs in a wallet and the speed at which nodes can verify a given rate limit authorization. Creating a single wallet to hold all Capacity Credit NFTs improves network performance during tests. - const capacityCreditWallet = - ethers.Wallet.createRandom().connect(provider); - - // get wallet balance - const balance = await wallet.getBalance(); - console.log('this.rpc:', this.rpc); - console.log('this.wallet.address', wallet.address); - console.log('Balance:', balance.toString()); - - const transferTx = await wallet.sendTransaction({ - to: capacityCreditWallet.address, - value: ethers.utils.parseEther('0.001'), - }); - await transferTx.wait(); - } - // await _switchWallet(); this.contractsClient = new LitContracts({ @@ -554,24 +545,29 @@ export class TinnyEnvironment { '[𐬺πŸ§ͺ Tinny Environment𐬺] Mint a Capacity Credits NFT and get a capacity delegation authSig with it' ); - const capacityTokenId = ( - await this.contractsClient.mintCapacityCreditsNFT({ - requestsPerKilosecond: this.processEnvs.REQUEST_PER_KILOSECOND, - daysUntilUTCMidnightExpiration: 2, - }) - ).capacityTokenIdStr; + //@ts-expect-error client is defined + const capacityNft = await this.contractsClient.mintCapacityCreditsNFT({ + requestsPerKilosecond: this.processEnvs.REQUEST_PER_KILOSECOND, + daysUntilUTCMidnightExpiration: 2, + }); + const capacityTokenId = capacityNft.capacityTokenIdStr; try { - this.superCapacityDelegationAuthSig = ( - await this.litNodeClient.createCapacityDelegationAuthSig({ - dAppOwnerWallet: wallet, - capacityTokenId: capacityTokenId, - // Sets a maximum limit of 200 times that the delegation can be used and prevents usage beyond it - uses: '200', - }) - ).capacityDelegationAuthSig; - } catch (e: any) { - if (e.message.includes(`Can't allocate capacity beyond the global max`)) { + //@ts-expect-error client is defined + const resp = await this.litNodeClient.createCapacityDelegationAuthSig({ + dAppOwnerWallet: wallet, + capacityTokenId: capacityTokenId, + // Sets a maximum limit of 200 times that the delegation can be used and prevents usage beyond it + uses: '200', + }); + + this.superCapacityDelegationAuthSig = resp.capacityDelegationAuthSig; + } catch (e: unknown) { + if ( + (e as Error).message.includes( + `Can't allocate capacity beyond the global max` + ) + ) { console.log('❗️Skipping capacity delegation auth sig setup.', e); } else { console.log( @@ -581,4 +577,26 @@ export class TinnyEnvironment { } } } + + async _switchWallet( + wallet: ethers.Wallet, + provider: ethers.providers.Provider + ) { + // TODO: This wallet should be cached somehwere and reused to create delegation signatures. + // There is a correlation between the number of Capacity Credit NFTs in a wallet and the speed at which nodes can verify a given rate limit authorization. + // Creating a single wallet to hold all Capacity Credit NFTs improves network performance during tests. + const capacityCreditWallet = ethers.Wallet.createRandom().connect(provider); + + // get wallet balance + const balance = await wallet.getBalance(); + console.log('this.rpc:', this.rpc); + console.log('this.wallet.address', wallet.address); + console.log('Balance:', balance.toString()); + + const transferTx = await wallet.sendTransaction({ + to: capacityCreditWallet.address, + value: ethers.utils.parseEther('0.001'), + }); + await transferTx.wait(); + } } diff --git a/local-tests/setup/tinny-person.ts b/packages/tinny/src/lib/tinny-person.ts similarity index 86% rename from local-tests/setup/tinny-person.ts rename to packages/tinny/src/lib/tinny-person.ts index 43cf604820..6516239868 100644 --- a/local-tests/setup/tinny-person.ts +++ b/packages/tinny/src/lib/tinny-person.ts @@ -1,38 +1,40 @@ +import { ethers } from 'ethers'; + import { AuthSig, generateAuthSig, createSiweMessage, } from '@lit-protocol/auth-helpers'; +import { AuthMethodScope } from '@lit-protocol/constants'; import { LitContracts } from '@lit-protocol/contracts-sdk'; +import { EthWalletProvider } from '@lit-protocol/lit-auth-client'; import { AuthMethod, BaseSiweMessage, LIT_NETWORKS_KEYS, LitContractContext, } from '@lit-protocol/types'; -import { ethers } from 'ethers'; + import { LIT_TESTNET, PKPInfo, TinnyEnvConfig } from './tinny-config'; -import { EthWalletProvider } from '@lit-protocol/lit-auth-client'; -import { AuthMethodScope } from '@lit-protocol/constants'; export class TinnyPerson { public privateKey: string; public wallet: ethers.Wallet; - public siweMessage: string; - public authSig: AuthSig; - public authMethod: AuthMethod; - public contractsClient: LitContracts; + public siweMessage: string | undefined; + public authSig: AuthSig | undefined; + public authMethod: AuthMethod | undefined; + public contractsClient: LitContracts | undefined; // public capacityTokenId: string; // public capacityDelegationAuthSig: AuthSig; - public pkp: PKPInfo; - public authMethodOwnedPkp: PKPInfo; + public pkp: PKPInfo | undefined; + public authMethodOwnedPkp: PKPInfo | undefined; // Pass this to data to sign public loveLetter: Uint8Array = ethers.utils.arrayify( ethers.utils.keccak256([1, 2, 3, 4, 5]) ); - public provider: ethers.providers.StaticJsonRpcProvider; + public provider: ethers.providers.JsonRpcProvider; public envConfig: TinnyEnvConfig; @@ -130,7 +132,7 @@ export class TinnyPerson { debug: this.envConfig.processEnvs.DEBUG, rpc: this.envConfig.processEnvs.LIT_RPC_URL, // anvil rpc customContext: networkContext as unknown as LitContractContext, - network: 'custom', + network: this.envConfig.processEnvs.NETWORK, }); } else { this.contractsClient = new LitContracts({ @@ -139,6 +141,7 @@ export class TinnyPerson { network: this.envConfig.network, }); } + await this.contractsClient.connect(); /** @@ -180,13 +183,27 @@ export class TinnyPerson { */ async mintCapacityCreditsNFT() { console.log('[𐬺πŸ§ͺ Tinny Person𐬺] Mint a Capacity Credits NFT '); - const capacityTokenId = ( - await this.contractsClient.mintCapacityCreditsNFT({ + const capacityToken = await this.contractsClient + ?.mintCapacityCreditsNFT({ requestsPerKilosecond: this.envConfig.processEnvs.REQUEST_PER_KILOSECOND, daysUntilUTCMidnightExpiration: 2, }) - ).capacityTokenIdStr; + .catch((err) => { + throw new Error( + `Error while minting capacity credit nft, error message: ${ + err.message ?? 'unknown' + }` + ); + }); + + if (!capacityToken) { + throw new Error( + 'Errpr while mitning capacity credit nft: receive undefined value' + ); + } + + const capacityTokenId = capacityToken.capacityTokenIdStr; return capacityTokenId; } @@ -203,16 +220,10 @@ export class TinnyPerson { '[𐬺πŸ§ͺ Tinny Person𐬺] Mint a Capacity Credits NFT and get a capacity delegation authSig with it' ); - const capacityTokenId = ( - await this.contractsClient.mintCapacityCreditsNFT({ - requestsPerKilosecond: - this.envConfig.processEnvs.REQUEST_PER_KILOSECOND, - daysUntilUTCMidnightExpiration: 2, - }) - ).capacityTokenIdStr; + const capacityTokenId = await this.mintCapacityCreditsNFT(); - this.contractsClient.signer = this.wallet; - await this.contractsClient.connect(); + this.contractsClient!.signer = this.wallet; + await this.contractsClient?.connect(); return ( await this.envConfig.litNodeClient.createCapacityDelegationAuthSig({ dAppOwnerWallet: this.wallet, diff --git a/local-tests/setup/tinny-utils.ts b/packages/tinny/src/lib/tinny-utils.ts similarity index 62% rename from local-tests/setup/tinny-utils.ts rename to packages/tinny/src/lib/tinny-utils.ts index 53e0702f98..0a5856a0a5 100644 --- a/local-tests/setup/tinny-utils.ts +++ b/packages/tinny/src/lib/tinny-utils.ts @@ -1,37 +1,3 @@ -import { importer } from 'ipfs-unixfs-importer'; -import { Buffer } from 'buffer'; - -/** - * Converts a string to an IPFS hash. - * @param input - The input string to convert. - * @returns A Promise that resolves to the IPFS hash. - * @throws An error if the generated hash does not start with 'Qm'. - */ -export async function stringToIpfsHash(input: string): Promise { - const blockput = { - put: async (block: any) => { - return block.cid; - }, - }; - - // Convert the input string to a Buffer - const content = Buffer.from(input); - - // Import the content to create an IPFS file - const files = importer([{ content }], blockput as any); - - // Get the first (and only) file result - const result = (await files.next()).value; - - const ipfsHash = (result as any).cid.toString(); - - if (!ipfsHash.startsWith('Qm')) { - throw new Error('Generated hash does not start with Qm'); - } - - return ipfsHash; -} - export function randomSolanaPrivateKey() { const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; @@ -69,7 +35,7 @@ function isErrorWithMessage(error: unknown): error is Error { typeof error === 'object' && error !== null && 'message' in error && - typeof (error as Record).message === 'string' + typeof (error as Record)['message'] === 'string' ); } diff --git a/packages/tinny/src/lib/tinny.spec.ts b/packages/tinny/src/lib/tinny.spec.ts new file mode 100644 index 0000000000..4fb4fc49eb --- /dev/null +++ b/packages/tinny/src/lib/tinny.spec.ts @@ -0,0 +1,7 @@ +import { TinnyEnvironment } from './tinny-environment'; + +describe('tinny', () => { + it('Tinny eviorment should be defined', () => { + expect(TinnyEnvironment).toBeDefined(); + }); +}); diff --git a/packages/tinny/tsconfig.json b/packages/tinny/tsconfig.json new file mode 100644 index 0000000000..f5b85657a8 --- /dev/null +++ b/packages/tinny/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/packages/tinny/tsconfig.lib.json b/packages/tinny/tsconfig.lib.json new file mode 100644 index 0000000000..33eca2c2cd --- /dev/null +++ b/packages/tinny/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/packages/tinny/tsconfig.spec.json b/packages/tinny/tsconfig.spec.json new file mode 100644 index 0000000000..9b2a121d11 --- /dev/null +++ b/packages/tinny/tsconfig.spec.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/packages/wrapped-keys/src/lib/api/utils.spec.ts b/packages/wrapped-keys/src/lib/api/utils.spec.ts index 3b529ff769..e008dfa75e 100644 --- a/packages/wrapped-keys/src/lib/api/utils.spec.ts +++ b/packages/wrapped-keys/src/lib/api/utils.spec.ts @@ -87,19 +87,17 @@ describe('getPkpAccessControlCondition', () => { it('should correctly create the ACC', () => { const pkpAddress = '0xd1Af1AAC50aC837C873200D17b78664aFCde597C'; const acc = getPkpAccessControlCondition(pkpAddress); - expect(acc).toEqual([ - { - contractAddress: '', - standardContractType: '', - chain: CHAIN_ETHEREUM, - method: '', - parameters: [':userAddress'], - returnValueTest: { - comparator: '=', - value: pkpAddress, - }, + expect(acc).toEqual({ + contractAddress: '', + standardContractType: '', + chain: CHAIN_ETHEREUM, + method: '', + parameters: [':userAddress'], + returnValueTest: { + comparator: '=', + value: pkpAddress, }, - ]); + }); }); it('should throw an error for non-Ethereum address', () => { diff --git a/yarn.lock b/yarn.lock index bddb688a6d..6e69683e39 100644 --- a/yarn.lock +++ b/yarn.lock @@ -40,14 +40,14 @@ dependencies: "@ampproject/remapping" "^2.2.0" "@babel/code-frame" "^7.24.7" - "@babel/generator" "^7.24.9" - "@babel/helper-compilation-targets" "^7.24.8" - "@babel/helper-module-transforms" "^7.24.9" - "@babel/helpers" "^7.24.8" - "@babel/parser" "^7.24.8" + "@babel/generator" "^7.24.7" + "@babel/helper-compilation-targets" "^7.24.7" + "@babel/helper-module-transforms" "^7.24.7" + "@babel/helpers" "^7.24.7" + "@babel/parser" "^7.24.7" "@babel/template" "^7.24.7" - "@babel/traverse" "^7.24.8" - "@babel/types" "^7.24.9" + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" @@ -227,7 +227,7 @@ "@babel/traverse" "^7.24.7" "@babel/types" "^7.24.7" -"@babel/helper-module-transforms@^7.24.7", "@babel/helper-module-transforms@^7.24.8", "@babel/helper-module-transforms@^7.24.9": +"@babel/helper-module-transforms@^7.24.7", "@babel/helper-module-transforms@^7.24.8": version "7.24.9" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz#e13d26306b89eea569180868e652e7f514de9d29" integrity sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw== @@ -344,23 +344,14 @@ "@babel/traverse" "^7.24.7" "@babel/types" "^7.24.7" -"@babel/helper-wrap-function@^7.25.0": +"@babel/helpers@^7.24.7": version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz#dab12f0f593d6ca48c0062c28bcfb14ebe812f81" - integrity sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ== + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.0.tgz#e69beb7841cb93a6505531ede34f34e6a073650a" + integrity sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw== dependencies: "@babel/template" "^7.25.0" - "@babel/traverse" "^7.25.0" "@babel/types" "^7.25.0" -"@babel/helpers@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.8.tgz#2820d64d5d6686cca8789dd15b074cd862795873" - integrity sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ== - dependencies: - "@babel/template" "^7.24.7" - "@babel/types" "^7.24.8" - "@babel/helpers@^7.25.0": version "7.25.6" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.6.tgz#57ee60141829ba2e102f30711ffe3afab357cc60" @@ -379,17 +370,17 @@ js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.24.7", "@babel/parser@^7.24.8": +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.24.7": version "7.24.8" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.8.tgz#58a4dbbcad7eb1d48930524a3fd93d93e9084c6f" integrity sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w== -"@babel/parser@^7.25.0", "@babel/parser@^7.25.6": - version "7.25.6" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.6.tgz#85660c5ef388cbbf6e3d2a694ee97a38f18afe2f" - integrity sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q== +"@babel/parser@^7.25.0", "@babel/parser@^7.25.3": + version "7.25.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.3.tgz#91fb126768d944966263f0657ab222a642b82065" + integrity sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw== dependencies: - "@babel/types" "^7.25.6" + "@babel/types" "^7.25.2" "@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.24.7": version "7.24.7" @@ -1422,13 +1413,35 @@ integrity sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ== dependencies: "@babel/code-frame" "^7.24.7" - "@babel/generator" "^7.24.8" + "@babel/parser" "^7.25.0" + "@babel/types" "^7.25.0" + +"@babel/traverse@^7.16.0", "@babel/traverse@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.7.tgz#de2b900163fa741721ba382163fe46a936c40cf5" + integrity sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/generator" "^7.24.7" "@babel/helper-environment-visitor" "^7.24.7" "@babel/helper-function-name" "^7.24.7" "@babel/helper-hoist-variables" "^7.24.7" "@babel/helper-split-export-declaration" "^7.24.7" - "@babel/parser" "^7.24.8" - "@babel/types" "^7.24.8" + "@babel/parser" "^7.24.7" + "@babel/types" "^7.24.7" + debug "^4.3.1" + globals "^11.1.0" + +"@babel/traverse@^7.24.8": + version "7.25.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.3.tgz#f1b901951c83eda2f3e29450ce92743783373490" + integrity sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/generator" "^7.25.0" + "@babel/parser" "^7.25.3" + "@babel/template" "^7.25.0" + "@babel/types" "^7.25.2" debug "^4.3.1" globals "^11.1.0" @@ -2364,18 +2377,6 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.5.1.tgz#260fe7239602fe5130a94f1aa386eff54b014bba" - integrity sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg== - dependencies: - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - jest-message-util "^27.5.1" - jest-util "^27.5.1" - slash "^3.0.0" - "@jest/console@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc" @@ -2388,50 +2389,40 @@ jest-util "^29.7.0" slash "^3.0.0" -"@jest/core@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" - integrity sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ== +"@jest/core@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f" + integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg== dependencies: - "@jest/console" "^27.5.1" - "@jest/reporters" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" + "@jest/console" "^29.7.0" + "@jest/reporters" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" - emittery "^0.8.1" + ci-info "^3.2.0" exit "^0.1.2" graceful-fs "^4.2.9" - jest-changed-files "^27.5.1" - jest-config "^27.5.1" - jest-haste-map "^27.5.1" - jest-message-util "^27.5.1" - jest-regex-util "^27.5.1" - jest-resolve "^27.5.1" - jest-resolve-dependencies "^27.5.1" - jest-runner "^27.5.1" - jest-runtime "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - jest-validate "^27.5.1" - jest-watcher "^27.5.1" + jest-changed-files "^29.7.0" + jest-config "^29.7.0" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-resolve-dependencies "^29.7.0" + jest-runner "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + jest-watcher "^29.7.0" micromatch "^4.0.4" - rimraf "^3.0.0" + pretty-format "^29.7.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.5.1.tgz#d7425820511fe7158abbecc010140c3fd3be9c74" - integrity sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA== - dependencies: - "@jest/fake-timers" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - jest-mock "^27.5.1" - "@jest/environment@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" @@ -2457,18 +2448,6 @@ expect "^29.7.0" jest-snapshot "^29.7.0" -"@jest/fake-timers@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74" - integrity sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ== - dependencies: - "@jest/types" "^27.5.1" - "@sinonjs/fake-timers" "^8.0.1" - "@types/node" "*" - jest-message-util "^27.5.1" - jest-mock "^27.5.1" - jest-util "^27.5.1" - "@jest/fake-timers@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" @@ -2481,15 +2460,6 @@ jest-mock "^29.7.0" jest-util "^29.7.0" -"@jest/globals@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.5.1.tgz#7ac06ce57ab966566c7963431cef458434601b2b" - integrity sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/types" "^27.5.1" - expect "^27.5.1" - "@jest/globals@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d" @@ -2500,38 +2470,7 @@ "@jest/types" "^29.6.3" jest-mock "^29.7.0" -"@jest/reporters@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.5.1.tgz#ceda7be96170b03c923c37987b64015812ffec04" - integrity sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - collect-v8-coverage "^1.0.0" - exit "^0.1.2" - glob "^7.1.2" - graceful-fs "^4.2.9" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^5.1.0" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.1.3" - jest-haste-map "^27.5.1" - jest-resolve "^27.5.1" - jest-util "^27.5.1" - jest-worker "^27.5.1" - slash "^3.0.0" - source-map "^0.6.0" - string-length "^4.0.1" - terminal-link "^2.0.0" - v8-to-istanbul "^8.1.0" - -"@jest/reporters@^29.4.1": +"@jest/reporters@^29.4.1", "@jest/reporters@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7" integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg== @@ -2568,15 +2507,6 @@ dependencies: "@sinclair/typebox" "^0.27.8" -"@jest/source-map@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" - integrity sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg== - dependencies: - callsites "^3.0.0" - graceful-fs "^4.2.9" - source-map "^0.6.0" - "@jest/source-map@^29.6.3": version "29.6.3" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4" @@ -2586,16 +2516,6 @@ callsites "^3.0.0" graceful-fs "^4.2.9" -"@jest/test-result@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.5.1.tgz#56a6585fa80f7cdab72b8c5fc2e871d03832f5bb" - integrity sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag== - dependencies: - "@jest/console" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/istanbul-lib-coverage" "^2.0.0" - collect-v8-coverage "^1.0.0" - "@jest/test-result@^29.4.1", "@jest/test-result@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c" @@ -2606,16 +2526,6 @@ "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" - integrity sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ== - dependencies: - "@jest/test-result" "^27.5.1" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-runtime "^27.5.1" - "@jest/test-sequencer@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce" @@ -5199,13 +5109,6 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== -"@sinonjs/commons@^1.7.0": - version "1.8.6" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9" - integrity sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ== - dependencies: - type-detect "4.0.8" - "@sinonjs/commons@^3.0.0": version "3.0.1" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd" @@ -5220,13 +5123,6 @@ dependencies: "@sinonjs/commons" "^3.0.0" -"@sinonjs/fake-timers@^8.0.1": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" - integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== - dependencies: - "@sinonjs/commons" "^1.7.0" - "@solana/buffer-layout@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz#b996235eaec15b1e0b5092a8ed6028df77fa6c15" @@ -5839,7 +5735,7 @@ "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": version "7.20.6" resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.6.tgz#8dc9f0ae0f202c08d8d4dab648912c8d6038e3f7" integrity sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg== @@ -5989,11 +5885,6 @@ dependencies: "@types/node" "*" -"@types/prettier@^2.1.5": - version "2.7.3" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" - integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== - "@types/responselike@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.3.tgz#cc29706f0a397cfe6df89debfe4bf5cea159db50" @@ -6801,11 +6692,6 @@ JSONStream@^1.0.4, JSONStream@^1.3.5: jsonparse "^1.2.0" through ">=2.2.7 <3" -abab@^2.0.3, abab@^2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" - integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== - abbrev@1, abbrev@^1.0.0, abbrev@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -6859,24 +6745,11 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: mime-types "~2.1.34" negotiator "0.6.3" -acorn-globals@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" - integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== - dependencies: - acorn "^7.1.1" - acorn-walk "^7.1.1" - acorn-jsx@^5.3.1, acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn-walk@^7.1.1: - version "7.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" - integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== - acorn-walk@^8.1.1: version "8.3.3" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.3.tgz#9caeac29eefaa0c41e3d4c65137de4d6f34df43e" @@ -6884,16 +6757,21 @@ acorn-walk@^8.1.1: dependencies: acorn "^8.11.0" -acorn@^7.1.1, acorn@^7.4.0: +acorn@^7.4.0: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.11.0, acorn@^8.11.3, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.9.0: +acorn@^8.11.0: version "8.12.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== +acorn@^8.11.3, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.9.0: + version "8.11.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== + add-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" @@ -7733,7 +7611,7 @@ babel-helpers@^6.24.1: babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-jest@27.5.1, babel-jest@^27.5.1: +babel-jest@27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== @@ -8602,11 +8480,6 @@ brorand@^1.0.1, brorand@^1.1.0: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== -browser-process-hrtime@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" - integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== - browserify-aes@^1.0.4, browserify-aes@^1.0.6, browserify-aes@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" @@ -9953,7 +9826,7 @@ conventional-recommended-bump@^6.1.0: meow "^8.0.0" q "^1.5.1" -convert-source-map@^1.4.0, convert-source-map@^1.5.1, convert-source-map@^1.6.0: +convert-source-map@^1.4.0, convert-source-map@^1.5.1: version "1.9.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== @@ -10130,6 +10003,19 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: safe-buffer "^5.0.1" sha.js "^2.4.8" +create-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" + integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q== + dependencies: + "@jest/types" "^29.6.3" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-config "^29.7.0" + jest-util "^29.7.0" + prompts "^2.0.1" + create-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" @@ -10261,23 +10147,6 @@ csso@^5.0.5: dependencies: css-tree "~2.2.0" -cssom@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" - integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== - -cssom@~0.3.6: - version "0.3.8" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" - integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== - -cssstyle@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" - integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== - dependencies: - cssom "~0.3.6" - cuint@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/cuint/-/cuint-0.2.2.tgz#408086d409550c2631155619e9fa7bcadc3b991b" @@ -10496,15 +10365,6 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -data-urls@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" - integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== - dependencies: - abab "^2.0.3" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.0.0" - data-view-buffer@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.1.tgz#8ea6326efec17a2e42620696e671d7d5a8bc66b2" @@ -10607,11 +10467,6 @@ decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== -decimal.js@^10.2.1: - version "10.4.3" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" - integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== - decode-uri-component@^0.2.0, decode-uri-component@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" @@ -11044,13 +10899,6 @@ domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0: resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== -domexception@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" - integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== - dependencies: - webidl-conversions "^5.0.0" - domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" @@ -11298,11 +11146,6 @@ emittery@^0.13.1: resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== -emittery@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" - integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== - emoji-regex@^7.0.1: version "7.0.3" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" @@ -11693,17 +11536,6 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -escodegen@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" - integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== - dependencies: - esprima "^4.0.1" - estraverse "^5.2.0" - esutils "^2.0.2" - optionalDependencies: - source-map "~0.6.1" - eslint-config-next@12.2.3: version "12.2.3" resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-12.2.3.tgz#468fe9756ccbf7e4452139062db5b4e6557dc885" @@ -12103,7 +11935,7 @@ espree@^9.0.0, espree@^9.6.0, espree@^9.6.1: acorn-jsx "^5.3.2" eslint-visitor-keys "^3.4.1" -esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: +esprima@^4.0.0, esprima@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== @@ -12874,16 +12706,6 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" - integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== - dependencies: - "@jest/types" "^27.5.1" - jest-get-type "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - expect@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" @@ -13405,15 +13227,6 @@ form-data-encoder@1.7.1: resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.1.tgz#ac80660e4f87ee0d3d3c3638b7da8278ddb8ec96" integrity sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg== -form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -13904,7 +13717,7 @@ glob@^10.2.2, glob@^10.3.10: package-json-from-dist "^1.0.0" path-scurry "^1.11.1" -glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0, glob@~7.2.3: +glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0, glob@~7.2.3: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -14398,13 +14211,6 @@ hosted-git-info@^7.0.0: dependencies: lru-cache "^10.0.1" -html-encoding-sniffer@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" - integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== - dependencies: - whatwg-encoding "^1.0.5" - html-encoding-sniffer@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9" @@ -15353,11 +15159,6 @@ is-port-reachable@4.0.0: resolved "https://registry.yarnpkg.com/is-port-reachable/-/is-port-reachable-4.0.0.tgz#dac044091ef15319c8ab2f34604d8794181f8c2d" integrity sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig== -is-potential-custom-element-name@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" - integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== - is-regex@^1.1.4, is-regex@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -15612,7 +15413,7 @@ istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== -istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: +istanbul-lib-instrument@^5.0.4: version "5.2.1" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== @@ -15743,39 +15544,14 @@ jayson@^4.1.1: uuid "^8.3.2" ws "^7.5.10" -jest-changed-files@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" - integrity sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw== +jest-changed-files@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" + integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w== dependencies: - "@jest/types" "^27.5.1" execa "^5.0.0" - throat "^6.0.1" - -jest-circus@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc" - integrity sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - dedent "^0.7.0" - expect "^27.5.1" - is-generator-fn "^2.0.0" - jest-each "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - jest-runtime "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - pretty-format "^27.5.1" - slash "^3.0.0" - stack-utils "^2.0.3" - throat "^6.0.1" + jest-util "^29.7.0" + p-limit "^3.1.0" jest-circus@^29.7.0: version "29.7.0" @@ -15803,55 +15579,24 @@ jest-circus@^29.7.0: slash "^3.0.0" stack-utils "^2.0.3" -jest-cli@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.5.1.tgz#278794a6e6458ea8029547e6c6cbf673bd30b145" - integrity sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw== +jest-cli@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995" + integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg== dependencies: - "@jest/core" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" + "@jest/core" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" chalk "^4.0.0" + create-jest "^29.7.0" exit "^0.1.2" - graceful-fs "^4.2.9" import-local "^3.0.2" - jest-config "^27.5.1" - jest-util "^27.5.1" - jest-validate "^27.5.1" - prompts "^2.0.1" - yargs "^16.2.0" - -jest-config@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.5.1.tgz#5c387de33dca3f99ad6357ddeccd91bf3a0e4a41" - integrity sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA== - dependencies: - "@babel/core" "^7.8.0" - "@jest/test-sequencer" "^27.5.1" - "@jest/types" "^27.5.1" - babel-jest "^27.5.1" - chalk "^4.0.0" - ci-info "^3.2.0" - deepmerge "^4.2.2" - glob "^7.1.1" - graceful-fs "^4.2.9" - jest-circus "^27.5.1" - jest-environment-jsdom "^27.5.1" - jest-environment-node "^27.5.1" - jest-get-type "^27.5.1" - jest-jasmine2 "^27.5.1" - jest-regex-util "^27.5.1" - jest-resolve "^27.5.1" - jest-runner "^27.5.1" - jest-util "^27.5.1" - jest-validate "^27.5.1" - micromatch "^4.0.4" - parse-json "^5.2.0" - pretty-format "^27.5.1" - slash "^3.0.0" - strip-json-comments "^3.1.1" + jest-config "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + yargs "^17.3.1" -jest-config@^29.4.1: +jest-config@^29.4.1, jest-config@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f" integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ== @@ -15899,13 +15644,6 @@ jest-diff@^29.4.1, jest-diff@^29.7.0: jest-get-type "^29.6.3" pretty-format "^29.7.0" -jest-docblock@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" - integrity sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ== - dependencies: - detect-newline "^3.0.0" - jest-docblock@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a" @@ -15913,17 +15651,6 @@ jest-docblock@^29.7.0: dependencies: detect-newline "^3.0.0" -jest-each@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e" - integrity sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ== - dependencies: - "@jest/types" "^27.5.1" - chalk "^4.0.0" - jest-get-type "^27.5.1" - jest-util "^27.5.1" - pretty-format "^27.5.1" - jest-each@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1" @@ -15935,31 +15662,6 @@ jest-each@^29.7.0: jest-util "^29.7.0" pretty-format "^29.7.0" -jest-environment-jsdom@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546" - integrity sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/fake-timers" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - jest-mock "^27.5.1" - jest-util "^27.5.1" - jsdom "^16.6.0" - -jest-environment-node@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz#dedc2cfe52fab6b8f5714b4808aefa85357a365e" - integrity sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/fake-timers" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - jest-mock "^27.5.1" - jest-util "^27.5.1" - jest-environment-node@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" @@ -16021,37 +15723,6 @@ jest-haste-map@^29.7.0: optionalDependencies: fsevents "^2.3.2" -jest-jasmine2@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4" - integrity sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/source-map" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - expect "^27.5.1" - is-generator-fn "^2.0.0" - jest-each "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - jest-runtime "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - pretty-format "^27.5.1" - throat "^6.0.1" - -jest-leak-detector@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8" - integrity sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ== - dependencies: - jest-get-type "^27.5.1" - pretty-format "^27.5.1" - jest-leak-detector@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728" @@ -16060,7 +15731,7 @@ jest-leak-detector@^29.7.0: jest-get-type "^29.6.3" pretty-format "^29.7.0" -jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.1: +jest-matcher-utils@^27.0.0: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== @@ -16080,21 +15751,6 @@ jest-matcher-utils@^29.7.0: jest-get-type "^29.6.3" pretty-format "^29.7.0" -jest-message-util@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" - integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^27.5.1" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^27.5.1" - slash "^3.0.0" - stack-utils "^2.0.3" - jest-message-util@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" @@ -16110,14 +15766,6 @@ jest-message-util@^29.7.0: slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" - integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== - dependencies: - "@jest/types" "^27.5.1" - "@types/node" "*" - jest-mock@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" @@ -16142,30 +15790,13 @@ jest-regex-util@^29.6.3: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52" integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== -jest-resolve-dependencies@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" - integrity sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg== - dependencies: - "@jest/types" "^27.5.1" - jest-regex-util "^27.5.1" - jest-snapshot "^27.5.1" - -jest-resolve@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" - integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw== +jest-resolve-dependencies@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428" + integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA== dependencies: - "@jest/types" "^27.5.1" - chalk "^4.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-pnp-resolver "^1.2.2" - jest-util "^27.5.1" - jest-validate "^27.5.1" - resolve "^1.20.0" - resolve.exports "^1.1.0" - slash "^3.0.0" + jest-regex-util "^29.6.3" + jest-snapshot "^29.7.0" jest-resolve@^29.4.1, jest-resolve@^29.7.0: version "29.7.0" @@ -16182,33 +15813,6 @@ jest-resolve@^29.4.1, jest-resolve@^29.7.0: resolve.exports "^2.0.0" slash "^3.0.0" -jest-runner@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.5.1.tgz#071b27c1fa30d90540805c5645a0ec167c7b62e5" - integrity sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ== - dependencies: - "@jest/console" "^27.5.1" - "@jest/environment" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - emittery "^0.8.1" - graceful-fs "^4.2.9" - jest-docblock "^27.5.1" - jest-environment-jsdom "^27.5.1" - jest-environment-node "^27.5.1" - jest-haste-map "^27.5.1" - jest-leak-detector "^27.5.1" - jest-message-util "^27.5.1" - jest-resolve "^27.5.1" - jest-runtime "^27.5.1" - jest-util "^27.5.1" - jest-worker "^27.5.1" - source-map-support "^0.5.6" - throat "^6.0.1" - jest-runner@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e" @@ -16236,34 +15840,6 @@ jest-runner@^29.7.0: p-limit "^3.1.0" source-map-support "0.5.13" -jest-runtime@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.5.1.tgz#4896003d7a334f7e8e4a53ba93fb9bcd3db0a1af" - integrity sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/fake-timers" "^27.5.1" - "@jest/globals" "^27.5.1" - "@jest/source-map" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - chalk "^4.0.0" - cjs-module-lexer "^1.0.0" - collect-v8-coverage "^1.0.0" - execa "^5.0.0" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-message-util "^27.5.1" - jest-mock "^27.5.1" - jest-regex-util "^27.5.1" - jest-resolve "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - slash "^3.0.0" - strip-bom "^4.0.0" - jest-runtime@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817" @@ -16300,34 +15876,6 @@ jest-serializer@^27.5.1: "@types/node" "*" graceful-fs "^4.2.9" -jest-snapshot@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz#b668d50d23d38054a51b42c4039cab59ae6eb6a1" - integrity sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA== - dependencies: - "@babel/core" "^7.7.2" - "@babel/generator" "^7.7.2" - "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/traverse" "^7.7.2" - "@babel/types" "^7.0.0" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/babel__traverse" "^7.0.4" - "@types/prettier" "^2.1.5" - babel-preset-current-node-syntax "^1.0.0" - chalk "^4.0.0" - expect "^27.5.1" - graceful-fs "^4.2.9" - jest-diff "^27.5.1" - jest-get-type "^27.5.1" - jest-haste-map "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - jest-util "^27.5.1" - natural-compare "^1.4.0" - pretty-format "^27.5.1" - semver "^7.3.2" - jest-snapshot@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5" @@ -16378,18 +15926,6 @@ jest-util@^29.0.0, jest-util@^29.4.1, jest-util@^29.7.0: graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" - integrity sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ== - dependencies: - "@jest/types" "^27.5.1" - camelcase "^6.2.0" - chalk "^4.0.0" - jest-get-type "^27.5.1" - leven "^3.1.0" - pretty-format "^27.5.1" - jest-validate@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" @@ -16402,19 +15938,6 @@ jest-validate@^29.7.0: leven "^3.1.0" pretty-format "^29.7.0" -jest-watcher@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" - integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== - dependencies: - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - jest-util "^27.5.1" - string-length "^4.0.1" - jest-watcher@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2" @@ -16448,14 +15971,15 @@ jest-worker@^29.7.0: merge-stream "^2.0.0" supports-color "^8.0.0" -jest@27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" - integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ== +jest@29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613" + integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== dependencies: - "@jest/core" "^27.5.1" + "@jest/core" "^29.7.0" + "@jest/types" "^29.6.3" import-local "^3.0.2" - jest-cli "^27.5.1" + jest-cli "^29.7.0" jiti@^1.21.0: version "1.21.6" @@ -16537,39 +16061,6 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== -jsdom@^16.6.0: - version "16.7.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" - integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== - dependencies: - abab "^2.0.5" - acorn "^8.2.4" - acorn-globals "^6.0.0" - cssom "^0.4.4" - cssstyle "^2.3.0" - data-urls "^2.0.0" - decimal.js "^10.2.1" - domexception "^2.0.1" - escodegen "^2.0.0" - form-data "^3.0.0" - html-encoding-sniffer "^2.0.1" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-potential-custom-element-name "^1.0.1" - nwsapi "^2.2.0" - parse5 "6.0.1" - saxes "^5.0.1" - symbol-tree "^3.2.4" - tough-cookie "^4.0.0" - w3c-hr-time "^1.0.2" - w3c-xmlserializer "^2.0.0" - webidl-conversions "^6.1.0" - whatwg-encoding "^1.0.5" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.5.0" - ws "^7.4.6" - xml-name-validator "^3.0.0" - jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" @@ -17477,7 +16968,7 @@ lodash@4.17.19: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== -lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.7.0: +lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.17.5: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -19022,11 +18513,6 @@ number-to-bn@1.7.0: bn.js "4.11.6" strip-hex-prefix "1.0.0" -nwsapi@^2.2.0: - version "2.2.12" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.12.tgz#fb6af5c0ec35b27b4581eb3bbad34ec9e5c696f8" - integrity sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w== - nx@15.9.7, "nx@>=14.8.1 < 16": version "15.9.7" resolved "https://registry.yarnpkg.com/nx/-/nx-15.9.7.tgz#f0e713cedb8637a517d9c4795c99afec4959a1b6" @@ -19826,11 +19312,6 @@ parse5-htmlparser2-tree-adapter@^7.0.0: domhandler "^5.0.2" parse5 "^7.0.0" -parse5@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" - integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== - parse5@^7.0.0: version "7.1.2" resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" @@ -21227,11 +20708,6 @@ resolve.exports@1.1.0: resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== -resolve.exports@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.1.tgz#05cfd5b3edf641571fd46fa608b610dda9ead999" - integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ== - resolve.exports@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" @@ -21467,13 +20943,6 @@ safe-stable-stringify@^2.1.0, safe-stable-stringify@^2.3.1: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -saxes@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" - integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== - dependencies: - xmlchars "^2.2.0" - scheduler@^0.21.0: version "0.21.0" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.21.0.tgz#6fd2532ff5a6d877b6edb12f00d8ab7e8f308820" @@ -22126,14 +21595,6 @@ source-map-support@^0.4.15: dependencies: source-map "^0.5.6" -source-map-support@^0.5.6: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - source-map-url@^0.4.0: version "0.4.1" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" @@ -22144,16 +21605,11 @@ source-map@^0.5.6, source-map@^0.5.7: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: +source-map@^0.6.0, source-map@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.7.3: - version "0.7.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" - integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== - sparse-array@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/sparse-array/-/sparse-array-1.3.2.tgz#0e1a8b71706d356bc916fe754ff496d450ec20b0" @@ -22774,7 +22230,7 @@ supports-color@^8.0.0, supports-color@^8.1.1: dependencies: has-flag "^4.0.0" -supports-hyperlinks@^2.0.0, supports-hyperlinks@^2.1.0: +supports-hyperlinks@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz#3943544347c1ff90b15effb03fc14ae45ec10624" integrity sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA== @@ -22835,11 +22291,6 @@ symbol-observable@^2.0.3: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-2.0.3.tgz#5b521d3d07a43c351055fa43b8355b62d33fd16a" integrity sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA== -symbol-tree@^3.2.4: - version "3.2.4" - resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" - integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== - synthetix-js@^2.74.1: version "2.101.2" resolved "https://registry.yarnpkg.com/synthetix-js/-/synthetix-js-2.101.2.tgz#9394967368fcf8183743a4b05d49889fd7fdbd21" @@ -23013,14 +22464,6 @@ term-size@^2.1.0: resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54" integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg== -terminal-link@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" - integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== - dependencies: - ansi-escapes "^4.2.1" - supports-hyperlinks "^2.0.0" - test-exclude@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" @@ -23062,11 +22505,6 @@ thread-stream@^0.15.1: dependencies: real-require "^0.1.0" -throat@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.2.tgz#51a3fbb5e11ae72e2cf74861ed5c8020f89f29fe" - integrity sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ== - throttleit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.1.tgz#304ec51631c3b770c65c6c6f76938b384000f4d5" @@ -23196,7 +22634,7 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -tough-cookie@^4.0.0, tough-cookie@^4.1.3: +tough-cookie@^4.1.3: version "4.1.4" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36" integrity sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag== @@ -23221,13 +22659,6 @@ toxic@^1.0.0: dependencies: lodash "^4.17.10" -tr46@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" - integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== - dependencies: - punycode "^2.1.1" - tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -24025,15 +23456,6 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz#cdada8bec61e15865f05d097c5f4fd30e94dc128" integrity sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw== -v8-to-istanbul@^8.1.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed" - integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^1.6.0" - source-map "^0.7.3" - v8-to-istanbul@^9.0.1: version "9.3.0" resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz#b9572abfa62bd556c16d75fdebc1a411d5ff3175" @@ -24124,20 +23546,6 @@ vscode-textmate@^8.0.0: resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d" integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg== -w3c-hr-time@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" - integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== - dependencies: - browser-process-hrtime "^1.0.0" - -w3c-xmlserializer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" - integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== - dependencies: - xml-name-validator "^3.0.0" - wait-on@7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-7.0.1.tgz#5cff9f8427e94f4deacbc2762e6b0a489b19eae9" @@ -24491,16 +23899,6 @@ webidl-conversions@^3.0.0: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== -webidl-conversions@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" - integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== - -webidl-conversions@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" - integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== - webpack-merge@^5.8.0: version "5.10.0" resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.10.0.tgz#a3ad5d773241e9c682803abf628d4cd62b8a4177" @@ -24536,13 +23934,6 @@ websocket@^1.0.32: utf-8-validate "^5.0.2" yaeti "^0.0.6" -whatwg-encoding@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" - integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== - dependencies: - iconv-lite "0.4.24" - whatwg-encoding@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53" @@ -24560,11 +23951,6 @@ whatwg-fetch@^3.0.0, whatwg-fetch@^3.4.1: resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz#580ce6d791facec91d37c72890995a0b48d31c70" integrity sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg== -whatwg-mimetype@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" - integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== - whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" @@ -24573,15 +23959,6 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" -whatwg-url@^8.0.0, whatwg-url@^8.5.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" - integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== - dependencies: - lodash "^4.7.0" - tr46 "^2.1.0" - webidl-conversions "^6.1.0" - which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" @@ -24875,7 +24252,12 @@ ws@^5.1.1: dependencies: async-limiter "~1.0.0" -ws@^7, ws@^7.0.0, ws@^7.2.3, ws@^7.4.6, ws@^7.5.1, ws@^7.5.10: +ws@^7, ws@^7.0.0, ws@^7.2.3, ws@^7.5.1: + version "7.5.9" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" + integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== + +ws@^7.5.10: version "7.5.10" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== @@ -24927,16 +24309,6 @@ xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3: parse-headers "^2.0.0" xtend "^4.0.0" -xml-name-validator@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" - integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== - -xmlchars@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" - integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== - xmlhttprequest@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" @@ -25089,7 +24461,7 @@ yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" -yargs@^17.6.2: +yargs@^17.3.1, yargs@^17.6.2: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==