diff --git a/README.md b/README.md index a01b3f8fc1..dcd2b144cb 100644 --- a/README.md +++ b/README.md @@ -67,39 +67,37 @@ For usage directly in the browser with a script tag -Package | Category | Version | Download ---- | --- | --- | --- -| [@lit-protocol/lit-node-client-nodejs](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/lit-node-client-nodejs) | ![lit-node-client-nodejs](https://img.shields.io/badge/-nodejs-2E8B57 "lit-node-client-nodejs") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/lit-node-client](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/lit-node-client) | ![lit-node-client](https://img.shields.io/badge/-universal-8A6496 "lit-node-client") | 3.0.0 | npm
Vanilla JS (UMD) - +| Package | Category | Version | Download | +| -------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [@lit-protocol/lit-node-client-nodejs](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/lit-node-client-nodejs) | ![lit-node-client-nodejs](https://img.shields.io/badge/-nodejs-2E8B57 'lit-node-client-nodejs') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/lit-node-client](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/lit-node-client) | ![lit-node-client](https://img.shields.io/badge/-universal-8A6496 'lit-node-client') | 3.0.0 | npm
Vanilla JS (UMD) | If you're a tech-savvy user and wish to utilize only specific submodules that our main module relies upon, you can find individual packages listed below. This way, you can import only the necessary packages that cater to your specific use case:: - -Package | Category | Version | Download ---- | --- | --- | --- -| [@lit-protocol/access-control-conditions](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/access-control-conditions) | ![access-control-conditions](https://img.shields.io/badge/-universal-8A6496 "access-control-conditions") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/auth-helpers](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/auth-helpers) | ![auth-helpers](https://img.shields.io/badge/-universal-8A6496 "auth-helpers") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/bls-sdk](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/bls-sdk) | ![bls-sdk](https://img.shields.io/badge/-universal-8A6496 "bls-sdk") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/constants](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/constants) | ![constants](https://img.shields.io/badge/-universal-8A6496 "constants") | 3.0.0 | npm
Vanilla JS (UMD) -| [@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") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/core](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/core) | ![core](https://img.shields.io/badge/-universal-8A6496 "core") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/crypto](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/crypto) | ![crypto](https://img.shields.io/badge/-universal-8A6496 "crypto") | 3.0.0 | npm
Vanilla JS (UMD) -| [@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") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/encryption](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/encryption) | ![encryption](https://img.shields.io/badge/-universal-8A6496 "encryption") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/lit-third-party-libs](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/lit-third-party-libs) | ![lit-third-party-libs](https://img.shields.io/badge/-universal-8A6496 "lit-third-party-libs") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/misc](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/misc) | ![misc](https://img.shields.io/badge/-universal-8A6496 "misc") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/nacl](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/nacl) | ![nacl](https://img.shields.io/badge/-universal-8A6496 "nacl") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/pkp-base](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/pkp-base) | ![pkp-base](https://img.shields.io/badge/-universal-8A6496 "pkp-base") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/pkp-client](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/pkp-client) | ![pkp-client](https://img.shields.io/badge/-universal-8A6496 "pkp-client") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/pkp-cosmos](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/pkp-cosmos) | ![pkp-cosmos](https://img.shields.io/badge/-universal-8A6496 "pkp-cosmos") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/pkp-ethers](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/pkp-ethers) | ![pkp-ethers](https://img.shields.io/badge/-universal-8A6496 "pkp-ethers") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/pkp-sui](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/pkp-sui) | ![pkp-sui](https://img.shields.io/badge/-universal-8A6496 "pkp-sui") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/pkp-walletconnect](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/pkp-walletconnect) | ![pkp-walletconnect](https://img.shields.io/badge/-universal-8A6496 "pkp-walletconnect") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/types](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/types) | ![types](https://img.shields.io/badge/-universal-8A6496 "types") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/uint8arrays](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/uint8arrays) | ![uint8arrays](https://img.shields.io/badge/-universal-8A6496 "uint8arrays") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/auth-browser](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/auth-browser) | ![auth-browser](https://img.shields.io/badge/-browser-E98869 "auth-browser") | 3.0.0 | npm
Vanilla JS (UMD) -| [@lit-protocol/misc-browser](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/misc-browser) | ![misc-browser](https://img.shields.io/badge/-browser-E98869 "misc-browser") | 3.0.0 | npm
Vanilla JS (UMD) +| Package | Category | Version | Download | +| -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [@lit-protocol/access-control-conditions](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/access-control-conditions) | ![access-control-conditions](https://img.shields.io/badge/-universal-8A6496 'access-control-conditions') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/auth-helpers](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/auth-helpers) | ![auth-helpers](https://img.shields.io/badge/-universal-8A6496 'auth-helpers') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/bls-sdk](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/bls-sdk) | ![bls-sdk](https://img.shields.io/badge/-universal-8A6496 'bls-sdk') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/constants](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/constants) | ![constants](https://img.shields.io/badge/-universal-8A6496 'constants') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@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') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/core](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/core) | ![core](https://img.shields.io/badge/-universal-8A6496 'core') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/crypto](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/crypto) | ![crypto](https://img.shields.io/badge/-universal-8A6496 'crypto') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@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') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/encryption](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/encryption) | ![encryption](https://img.shields.io/badge/-universal-8A6496 'encryption') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/lit-third-party-libs](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/lit-third-party-libs) | ![lit-third-party-libs](https://img.shields.io/badge/-universal-8A6496 'lit-third-party-libs') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/misc](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/misc) | ![misc](https://img.shields.io/badge/-universal-8A6496 'misc') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/nacl](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/nacl) | ![nacl](https://img.shields.io/badge/-universal-8A6496 'nacl') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/pkp-base](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/pkp-base) | ![pkp-base](https://img.shields.io/badge/-universal-8A6496 'pkp-base') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/pkp-client](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/pkp-client) | ![pkp-client](https://img.shields.io/badge/-universal-8A6496 'pkp-client') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/pkp-cosmos](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/pkp-cosmos) | ![pkp-cosmos](https://img.shields.io/badge/-universal-8A6496 'pkp-cosmos') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/pkp-ethers](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/pkp-ethers) | ![pkp-ethers](https://img.shields.io/badge/-universal-8A6496 'pkp-ethers') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/pkp-sui](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/pkp-sui) | ![pkp-sui](https://img.shields.io/badge/-universal-8A6496 'pkp-sui') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/pkp-walletconnect](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/pkp-walletconnect) | ![pkp-walletconnect](https://img.shields.io/badge/-universal-8A6496 'pkp-walletconnect') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/types](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/types) | ![types](https://img.shields.io/badge/-universal-8A6496 'types') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/uint8arrays](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/uint8arrays) | ![uint8arrays](https://img.shields.io/badge/-universal-8A6496 'uint8arrays') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/auth-browser](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/auth-browser) | ![auth-browser](https://img.shields.io/badge/-browser-E98869 'auth-browser') | 3.0.0 | npm
Vanilla JS (UMD) | +| [@lit-protocol/misc-browser](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/misc-browser) | ![misc-browser](https://img.shields.io/badge/-browser-E98869 'misc-browser') | 3.0.0 | npm
Vanilla JS (UMD) | @@ -130,7 +128,7 @@ http://docs.lit-js-sdk-v2.litprotocol.com/
- NX Console: https://nx.dev/core-features/integrate-with-editors -# Quick Start +# Quick Start The following commands will help you start developing with this repository. @@ -212,7 +210,6 @@ yarn delete:app yarn delete:package ``` - ## Building ```jsx @@ -247,13 +244,13 @@ Run `yarn bump` to bump the version. You must have at least nodejs v18 to do thi ### to npm -``` +```sh yarn publish:packages ``` ### clone & publish to npm -```jsx +```sh yarn tools --clone <(?) --publish> <(?) --remove-after> // eg @@ -262,7 +259,7 @@ yarn tools --clone lit-node-client @litprotocol/dev --publish --remove-after ## bump, build, test, gen docs, publish, git push -``` +```sh yarn bump yarn build yarn test:unit @@ -280,7 +277,7 @@ git push The following will serve the react testing app and launch the cypress e2e testing after -``` +```sh yarn test:e2e ``` @@ -318,6 +315,37 @@ yarn tools --test --e2e html yarn tools --test --e2e react ``` +## Testing with a Local Lit Node + +First, deploy your Lit Node Contracts, since the correct addresses will be pulled from the `../lit-assets/blockchain/contracts/deployed-lit-node-contracts-temp.json` file. + +Set these two env vars: + +```sh +export LIT_JS_SDK_LOCAL_NODE_DEV="true" +export LIT_JS_SDK_FUNDED_WALLET_PRIVATE_KEY="putAFundedPrivateKeyOnChronicleHere" +``` + +Run: + +```sh +yarn update:contracts-sdk --fetch +yarn update:contracts-sdk --gen +yarn build:packages +``` + +To run manual tests: + +```sh + yarn nx run nodejs:serve +``` + +## ENV Vars + +- LIT_JS_SDK_GITHUB_ACCESS_TOKEN - a github access token to get the contract ABIs from a private repo +- LIT_JS_SDK_LOCAL_NODE_DEV - set to true to use a local node +- LIT_JS_SDK_FUNDED_WALLET_PRIVATE_KEY - set to a funded wallet on Chronicle Testnet + ## Other Commands ### Interactive graph dependencies using NX diff --git a/apps/html/index.html b/apps/html/index.html index 72cad85cfe..fd358c8e9d 100644 --- a/apps/html/index.html +++ b/apps/html/index.html @@ -1,4 +1,4 @@ - + @@ -62,7 +62,7 @@ - (HTML) THIS FILE IS AUTOMATICALLY GENERATED FROM tools/scripts/gen-html.mjs Wed, 13 Sep 2023 21:10:08 GMT + (HTML) THIS FILE IS AUTOMATICALLY GENERATED FROM tools/scripts/gen-html.mjs Thu, 14 Sep 2023 05:53:44 GMT diff --git a/apps/nodejs/manual-test.ts b/apps/nodejs/manual-test.ts index a6c1082cc7..6db6365b30 100644 --- a/apps/nodejs/manual-test.ts +++ b/apps/nodejs/manual-test.ts @@ -1,96 +1,98 @@ -import * as litNodeClient from '@lit-protocol/lit-node-client'; +import { LitContracts } from '@lit-protocol/contracts-sdk'; +import * as LitJsSdk from '@lit-protocol/lit-node-client'; // import { LitContracts } from '@lit-protocol/contracts-sdk'; -// import { ethers } from 'ethers'; - -// // *********************************************** -// // Configuration for this test -// // *********************************************** -// const TEST_FUNDED_PRIVATE_KEY = -// '3dfb4f70b15b6fccc786347aaea445f439a7f10fd10c55dd50cafc3d5a0abac1'; -// const PKP_PUBKEY = -// '0x0447972cdf33b1b0329c3ddeea661c023e6b251d8b1aeaa92da881cc6d0d1eff22c2cbd6a5fead8ba860064881cdaabd7176ca2cade0d50829460d729bd13514f3'; -// const CONTROLLER_AUTHSIG = { -// sig: '0x694a3ff6e16ab7d7189b7507df9b73ec118d1966abad7f0e3984df19991ddc2d558abca2fcc5b4acfb710d455c63ca2ad538f4d603d64bd93a1f124b119eac031b', -// derivedVia: 'web3.eth.personal.sign', -// signedMessage: -// 'demo-encrypt-decrypt-react.vercel.app wants you to sign in with your Ethereum account:\n0x1cD4147AF045AdCADe6eAC4883b9310FD286d95a\n\n\nURI: https://demo-encrypt-decrypt-react.vercel.app/\nVersion: 1\nChain ID: 1\nNonce: MrgYgnIW5yHCTKetV\nIssued At: 2022-12-14T02:29:48.420Z\nExpiration Time: 2022-12-21T02:29:48.401Z', -// address: '0x1cd4147af045adcade6eac4883b9310fd286d95a', -// }; - -// console.log( -// '------------------------------ litNodeClientTest ------------------------------' -// ); -// // globalThis.crypto = require('crypto').webcrypto; -// // globalThis.Blob = require('node:buffer').Blob; - -// // ================================== -// // Business Logic -// // ================================== -// const runLogic = async (contract: LitContracts) => { -// let mintCost; -// let tx; - -// await contract.connect(); - -// // ------------------------------------------------------ -// // only run this if it's a pkp wallet -// // ------------------------------------------------------ -// if ('rpcProvider' in contract.signer) { -// console.log("It's a PKP Wallet"); -// const pkpWallet = await setupPKP(); - -// mintCost = await contract.pkpNftContract.read.mintCost(); -// console.log('mintCost:', mintCost.toString()); - -// tx = await contract.pkpNftContract.write.populateTransaction.mintNext(2, { -// value: mintCost, -// }); -// console.log('tx:', tx); - -// const signedTx = await pkpWallet.signTransaction(tx); -// console.log('signedTx:', signedTx); - -// const sentTx = await pkpWallet.sendTransaction(signedTx as any); -// console.log('sentTx:', sentTx); - -// const res = await sentTx.wait(); -// console.log('res:', res); -// return; -// } - -// // ------------------------------------------- -// // regular minting process -// // ------------------------------------------- -// try { -// mintCost = await contract.pkpNftContract.read.mintCost(); -// console.log('mintCost:', mintCost.toString()); -// } catch (e) { -// console.error('Failed to get mint cost'); -// console.log(e); -// } -// try { -// tx = await contract.pkpNftContract.write.mintNext(2, { -// value: mintCost, -// }); -// console.log('tx:', tx); - -// const res = await tx.wait(); -// console.log('res:', res); -// } catch (e: any) { -// console.error('Failed to mintNext:', e.message); -// } -// // wait 1 second -// await new Promise((resolve) => setTimeout(resolve, 1000)); -// }; +import { ethers } from 'ethers'; +import { PKPEthersWallet } from '@lit-protocol/pkp-ethers'; +import { SiweMessage } from 'lit-siwe'; +import { LIT_EVM_CHAINS } from '@lit-protocol/constants'; + + + +// *********************************************** +// Configuration for this test +// *********************************************** +const TEST_FUNDED_PRIVATE_KEY = + process.env.LIT_JS_SDK_FUNDED_WALLET_PRIVATE_KEY; + +console.log( + '------------------------------ litNodeClientTest ------------------------------' +); +// globalThis.crypto = require('crypto').webcrypto; +// globalThis.Blob = require('node:buffer').Blob; + +// ================================== +// Business Logic +// ================================== +const runLogic = async (contract: LitContracts) => { + let mintCost; + let tx; + + await contract.connect(); + + // ------------------------------------------------------ + // only run this if it's a pkp wallet + // ------------------------------------------------------ + // if ('rpcProvider' in contract.signer) { + // console.log("It's a PKP Wallet"); + // const pkpWallet = await setupPKP(); + + // mintCost = await contract.pkpNftContract.read.mintCost(); + // console.log('mintCost:', mintCost.toString()); + + // tx = await contract.pkpNftContract.write.mintNext(2, { + // value: mintCost, + // }); + // console.log('tx:', tx); + + // const signedTx = await pkpWallet.signTransaction(tx); + // console.log('signedTx:', signedTx); + + // const sentTx = await pkpWallet.sendTransaction(signedTx as any); + // console.log('sentTx:', sentTx); + + // const res = await sentTx.wait(); + // console.log('res:', res); + // return; + // } + + // ------------------------------------------- + // regular minting process + // ------------------------------------------- + try { + mintCost = await contract.pkpNftContract.read.mintCost(); + console.log('mintCost:', mintCost.toString()); + } catch (e) { + console.error('Failed to get mint cost'); + console.log(e); + } + + let pkpPubkey; + try { + tx = await contract.pkpNftContract.write.mintNext(2, { + value: mintCost, + }); + console.log('tx:', tx); + + const res = await tx.wait(); + console.log('res:', res); + let pkpMintedEvent = res.events.find(event => event.event === "PKPMinted"); + console.log('pkpMintedEvent:', pkpMintedEvent); + pkpPubkey = pkpMintedEvent.args.pubkey; + } catch (e: any) { + console.error('Failed to mintNext:', e.message); + } + // wait 1 second + await new Promise((resolve) => setTimeout(resolve, 1000)); + return pkpPubkey; +}; -// // ============================= -// // PKP Setup -// // ============================= +// ============================= +// PKP Setup +// ============================= // const setupPKP = async () => { -// const pkpWallet = new PKPWallet({ +// const pkpWallet = new PKPEthersWallet({ // pkpPubKey: PKP_PUBKEY, // controllerAuthSig: CONTROLLER_AUTHSIG, -// provider: 'https://rpc-mumbai.maticvigil.com', // }); // await pkpWallet.init(); @@ -101,9 +103,9 @@ import * as litNodeClient from '@lit-protocol/lit-node-client'; // return pkpSigner; // }; -// // =========================================== -// // random private key test -// // =========================================== +// =========================================== +// random private key test +// =========================================== // const useRandomPrivateKey = async () => { // console.warn('\n\n1. Testing random private key\n\n\n'); // const litContracts = new LitContracts({ randomPrivatekey: true }); @@ -195,7 +197,7 @@ import * as litNodeClient from '@lit-protocol/lit-node-client'; // const privateKey = TEST_FUNDED_PRIVATE_KEY; // const provider = new ethers.providers.JsonRpcProvider( -// 'https://matic-mumbai.chainstacklabs.com' +// LIT_EVM_CHAINS['chronicleTestnet'].rpcUrls[0] // ); // const signer = new ethers.Wallet(privateKey, provider); @@ -203,27 +205,175 @@ import * as litNodeClient from '@lit-protocol/lit-node-client'; // await runLogic(litContracts); // }; -// // ========================================================================= -// // Enable/Disable the function you want to test manually -// // ========================================================================= -export const manualTest = async () => { - console.log('Manual Test Here!'); - const client = new litNodeClient.LitNodeClient({ +const pkpSign = async (client, pkpPubkey, authSig) => { + // try and sign something + let sig = await client.pkpSign({ + toSign: [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100], // hello world in Uint8Array + pubKey: pkpPubkey, + authSig, + }); + + // console.log("sig: ", sig); + + const recoveredPk = ethers.utils.recoverPublicKey("0x" + sig.dataSigned, sig.signature); + const addr = ethers.utils.computeAddress('0x' + sig.publicKey); + const recoveredAddr = ethers.utils.computeAddress(recoveredPk); + const claimedAddr = ethers.utils.computeAddress(pkpPubkey); + + const allGood = addr === recoveredAddr && addr === claimedAddr; + + console.log('all addresses match: ', allGood); + return allGood; +} + +const litActionSign = async(client, pkpPubkey, authSig) => { + console.log('testing sig with lit actions...'); + // this code will be run on the node + const litActionCode = ` + const go = async () => { + // this requests a signature share from the Lit Node + // the signature share will be automatically returned in the HTTP response from the node + // all the params (toSign, publicKey, sigName) are passed in from the LitJsSdk.executeJs() function + await Lit.Actions.signEcdsa({ toSign, publicKey , sigName }); + await Lit.Actions.signEcdsa({ toSign, publicKey , sigName: 'sig2' }); + }; + + go(); + `; + + const signatures = await client.executeJs({ + code: litActionCode, + authSig, + // all jsParams can be used anywhere in your litActionCode + jsParams: { + // this is the string "Hello World" for testing + toSign: [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100], + publicKey: pkpPubkey, + sigName: "sig1", + }, + }); + // console.log("signatures: ", signatures); + const { sig1, sig2 } = signatures.signatures + const sigKeys = { + sig1: { + recovered: ethers.utils.computeAddress(ethers.utils.recoverPublicKey("0x" + sig1.dataSigned, sig1.signature)), + reported: ethers.utils.computeAddress('0x' + sig1.publicKey) + }, + sig2: { + recovered: ethers.utils.computeAddress(ethers.utils.recoverPublicKey("0x" + sig2.dataSigned, sig2.signature)), + reported: ethers.utils.computeAddress('0x' + sig2.publicKey) + }, + } + + // console.log(`sigKeys: ${JSON.stringify(sigKeys, null, 2)}`) + + const pkpAddr = ethers.utils.computeAddress(pkpPubkey); + // console.log('pkpAddr:', pkpAddr) + + + let allGood = sigKeys.sig1.recovered == sigKeys.sig1.reported && sigKeys.sig2.recovered == sigKeys.sig2.reported && sigKeys.sig1.recovered == sigKeys.sig2.recovered && sigKeys.sig1.recovered == pkpAddr; + console.log('all addresses match: ', allGood); + return allGood; + } + +const mintPkpAndSign = async () => { + let client; + if (process.env.LIT_JS_SDK_LOCAL_NODE_DEV === "true") { + // use local node + client = new LitJsSdk.LitNodeClient({ + litNetwork: 'custom', + "minNodeCount": 2, + "bootstrapUrls": [ + "http://localhost:7470", + "http://localhost:7471", + "http://localhost:7472", + ], + debug: false + }); + } else { + // use cayenne + client = new LitJsSdk.LitNodeClient({ + litNetwork: 'cayenne', + debug: false + }); + } + + await client.connect(); + + const litContracts = new LitContracts({ + privateKey: TEST_FUNDED_PRIVATE_KEY, + }); + const pkpPubkey = await runLogic(litContracts); + console.log('pkpPubkey:', pkpPubkey); + + const privateKey = TEST_FUNDED_PRIVATE_KEY; + const provider = new ethers.providers.JsonRpcProvider( + LIT_EVM_CHAINS['chronicleTestnet'].rpcUrls[0] + ); + const wallet = new ethers.Wallet(privateKey, provider); + const authSig = await getAuthSig(wallet); + + let startTime = Date.now(); + let allGood = true; + const testCount = 100; + for(let i = 0; i < testCount; i++){ + console.log(`testing ${i + 1} of ${testCount}`); + let result = await pkpSign(client, pkpPubkey, authSig); + if (!result) { + allGood = false; + } + } + console.log(`it took ${(Date.now() - startTime) / 1000}s to run ${testCount} tests`) + console.log('all tests were good', allGood); + // await litActionSign(client, pkpPubkey, authSig); +} + +const getAuthSig = async (wallet) => { + const address = wallet.address; + + // Craft the SIWE message + const domain = 'localhost'; + const origin = 'https://localhost/login'; + const statement = + 'This is a test statement. You can put anything you want here.'; + const siweMessage = new SiweMessage({ + domain, + address, + statement, + uri: origin, + version: '1', + chainId: 1, + }); + const messageToSign = siweMessage.prepareMessage(); + + // Sign the message and format the authSig + const signature = await wallet.signMessage(messageToSign); + + const authSig = { + sig: signature, + derivedVia: 'web3.eth.personal.sign', + signedMessage: messageToSign, + address: address, + }; + return authSig +} + +const testLitActionJsExecution = async () => { + const client = new LitJsSdk.LitNodeClient({ litNetwork: 'cayenne', }); await client.connect(); + // generate a random wallet using ethers + let wallet = ethers.Wallet.createRandom(); + console.log('Wallet Address:', wallet.address); + const address = wallet.address; + const authSig = await getAuthSig(wallet); + const res = await client.executeJs({ targetNodeRange: 1, - authSig: { - sig: '0x721a354498677a1024fb48a78e56c68fd11ad705565933dd9ac770501cecad8811e8591453e21ab50d2579c3d2fe7b0dcbcb1b6436c67e9c6263169c182f50bd1b', - derivedVia: 'web3.eth.personal.sign', - signedMessage: - 'demo-encrypt-decrypt-react.vercel.app wants you to sign in with your Ethereum account:\n0xEDA4f4A8AbCecB28bf1663df9257Ec6F188B8107\n\n\nURI: https://demo-encrypt-decrypt-react.vercel.app/\nVersion: 1\nChain ID: 1\nNonce: hwrDnUCFsiR10S2lX\nIssued At: 2023-01-25T14:26:44.497Z\nExpiration Time: 2023-02-01T14:26:44.480Z', - address: '0xeda4f4a8abcecb28bf1663df9257ec6f188b8107', - }, - + authSig, jsParams: {}, code: `(async() => { console.log("RUN TEST BABY!"); @@ -232,4 +382,12 @@ export const manualTest = async () => { }); console.log('res:', res); +} + +// // ========================================================================= +// // Enable/Disable the function you want to test manually +// // ========================================================================= +export const manualTest = async () => { + console.log('Manual Test Here!'); + await mintPkpAndSign(); }; diff --git a/apps/react/src/app/app.tsx b/apps/react/src/app/app.tsx index fe8ea4009f..3d93b90320 100644 --- a/apps/react/src/app/app.tsx +++ b/apps/react/src/app/app.tsx @@ -1802,7 +1802,7 @@ pre { `, }} /> - (REACT) THIS FILE IS AUTOMATICALLY GENERATED FROM tools/scripts/gen-react.mjs Wed, 13 Sep 2023 21:10:09 GMT + (REACT) THIS FILE IS AUTOMATICALLY GENERATED FROM tools/scripts/gen-react.mjs Thu, 14 Sep 2023 05:53:45 GMT
diff --git a/package.json b/package.json index 7e40f6dd61..9a1872ec32 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "test:e2e": "yarn tools --test --e2e run-react-and-test", "test:unit": "yarn test:packages", "test:custom": "yarn tools --test --custom", + "test:file": "bun ./tools/scripts/test-script.mjs", "publish:packages": "yarn node ./tools/scripts/pub.mjs --prod", "publish:dev": "yarn node ./tools/scripts/pub.mjs --tag dev", "publish:test": "yarn node ./tools/scripts/pub.mjs --tag test", @@ -56,7 +57,9 @@ "txServer": "node tx-handler-server.mjs", "prettier": "nx format:write --all", "delete:merged-branches": "git branch --merged | egrep -v '(^\\*|master|main|develop)' | xargs git branch -d", - "delete:no-merged-branches": "git branch --no-merged | egrep -v '(^\\*|master|main|develop)' | xargs git branch -d" + "delete:no-merged-branches": "git branch --no-merged | egrep -v '(^\\*|master|main|develop)' | xargs git branch -d", + "cache:enable": "node ./tools/scripts/endisable-cache.mjs --enable=true", + "cache:disable": "node ./tools/scripts/endisable-cache.mjs --enable=false" }, "private": true, "dependencies": { @@ -190,4 +193,4 @@ "workspaces": [ "packages/*" ] -} +} \ No newline at end of file diff --git a/packages/contracts-sdk/fetch-contracts.mjs b/packages/contracts-sdk/fetch-contracts.mjs index f0ff452390..63ecf5463e 100644 --- a/packages/contracts-sdk/fetch-contracts.mjs +++ b/packages/contracts-sdk/fetch-contracts.mjs @@ -103,15 +103,16 @@ export const asyncForEach = async (array, callback) => { */ export const getContractAddresses = async (LitConfig) => { // get deployed contract addresses - const contractAddresses = JSON.parse( - await fetch(LitConfig.contracts, { - headers: LitConfig.abis.isPrivate - ? { - Authorization: `token ${LitConfig.abis.token}`, - } - : {}, - }).then((res) => res.text()) - ); + let contractAddresses; + if (process.env.LIT_JS_SDK_LOCAL_NODE_DEV === 'true') { + // get contracts from local filesystem + contractAddresses = await readJsonFile(LitConfig.contractsLocal); + } else { + // get contracts from remote + contractAddresses = JSON.parse( + await fetch(LitConfig.contracts).then((res) => res.text()) + ); + } Object.entries(contractAddresses).forEach(([key, value]) => { if (key.includes('ContractAddress')) return; @@ -133,7 +134,8 @@ export const getContractAddresses = async (LitConfig) => { correctedName = correctedName.replace('Nft', 'NFT'); correctedName = correctedName.replace('Lit', 'LIT'); correctedName = correctedName.replace('Resolver', 'ContractResolver'); - if (correctedName == "HdKeyDeriver"){ // dont process the contract with name as it is internally used wihtin `PubkeyRouter` + if (correctedName == 'HdKeyDeriver') { + // dont process the contract with name as it is internally used wihtin `PubkeyRouter` return; } if (correctedName === 'ContractResolver') { @@ -142,7 +144,12 @@ export const getContractAddresses = async (LitConfig) => { // append .json // correctedName = correctedName - let abiPath = LitConfig.root + LitConfig.abis.dir + correctedName + '.json'; + let abiPath; + if (process.env.LIT_JS_SDK_LOCAL_NODE_DEV === 'true') { + abiPath = LitConfig.abis.dirLocal + correctedName + '.json'; + } else { + abiPath = LitConfig.root + LitConfig.abis.dir + correctedName + '.json'; + } contracts.push({ name: item[0], @@ -169,14 +176,20 @@ await asyncForEach(deployedContracts, async (contract) => { let json; try { - json = await fetch(contract.abiPath, { - headers: LitConfig.abis.isPrivate - ? { - Authorization: `token ${LitConfig.abis.token}`, - } - : {}, - }).then((res) => res.text()); - json = JSON.parse(json); + if (process.env.LIT_JS_SDK_LOCAL_NODE_DEV === 'true') { + // get from local filesystem + json = await readJsonFile(contract.abiPath); + } else { + // get from remote + json = await fetch(contract.abiPath, { + headers: LitConfig.abis.isPrivate + ? { + Authorization: `token ${process.env.LIT_JS_SDK_GITHUB_ACCESS_TOKEN}`, + } + : {}, + }).then((res) => res.text()); + json = JSON.parse(json); + } } catch (e) { redLog(`Failed to fetch ${contract.abiPath}`); } diff --git a/packages/contracts-sdk/lit-contracts.config.json b/packages/contracts-sdk/lit-contracts.config.json index fc3b7f86bb..d402e1b8bb 100644 --- a/packages/contracts-sdk/lit-contracts.config.json +++ b/packages/contracts-sdk/lit-contracts.config.json @@ -4,7 +4,8 @@ "abis": { "dir": "abis/", "ignoreProperties": ["metadata", "bytecode", "deployedBytecode"], - "token": "", - "isPrivate": true - } + "isPrivate": true, + "dirLocal": "../lit-assets/rust/lit-core/lit-blockchain/abis/" + }, + "contractsLocal": "../lit-assets/blockchain/contracts/deployed-lit-node-contracts-temp.json" } diff --git a/packages/contracts-sdk/src/abis/Allowlist.data.ts b/packages/contracts-sdk/src/abis/Allowlist.data.ts index ca6c61ca4f..1bfa7bf746 100644 --- a/packages/contracts-sdk/src/abis/Allowlist.data.ts +++ b/packages/contracts-sdk/src/abis/Allowlist.data.ts @@ -1,5 +1,5 @@ export const allowlist = { - "address": "0x01385531dF2397425acb2Dffd3fA5Fd76729504a", + "address": "0x9fb501502402Fe4A8CE44c8C39a5d63787ED653c", "abi": [ { "inputs": [], diff --git a/packages/contracts-sdk/src/abis/ContractResolver.data.ts b/packages/contracts-sdk/src/abis/ContractResolver.data.ts index bb34896e4a..4a4b1e3755 100644 --- a/packages/contracts-sdk/src/abis/ContractResolver.data.ts +++ b/packages/contracts-sdk/src/abis/ContractResolver.data.ts @@ -1,5 +1,5 @@ export const contractResolver = { - "address": "0x0bca885Cf322D0E478DC48Fb84b4f522144db9D7", + "address": "0x53Df74f2Ca020ab439002158e6De0A32b1AA66D1", "abi": [ { "inputs": [ diff --git a/packages/contracts-sdk/src/abis/Multisender.data.ts b/packages/contracts-sdk/src/abis/Multisender.data.ts index b1fc7b216a..fb4f0d4602 100644 --- a/packages/contracts-sdk/src/abis/Multisender.data.ts +++ b/packages/contracts-sdk/src/abis/Multisender.data.ts @@ -1,5 +1,5 @@ export const multisender = { - "address": "0x373195723448308d43a43989790C0b768Ef14853", + "address": "0xacAe3822240234d8Ebbb591787a2E2b6247Ce63e", "abi": [ { "anonymous": false, diff --git a/packages/contracts-sdk/src/abis/PKPHelper.data.ts b/packages/contracts-sdk/src/abis/PKPHelper.data.ts index 840a094d6a..38a296906c 100644 --- a/packages/contracts-sdk/src/abis/PKPHelper.data.ts +++ b/packages/contracts-sdk/src/abis/PKPHelper.data.ts @@ -1,5 +1,5 @@ export const pkpHelper = { - "address": "0xA8C519a051b85A2010C498145C698074782AB6DF", + "address": "0x0600cBB5dc983A970b165390Da00e699E5baeDD1", "abi": [ { "inputs": [ diff --git a/packages/contracts-sdk/src/abis/PKPNFT.data.ts b/packages/contracts-sdk/src/abis/PKPNFT.data.ts index 6cda8932e1..484a2c089e 100644 --- a/packages/contracts-sdk/src/abis/PKPNFT.data.ts +++ b/packages/contracts-sdk/src/abis/PKPNFT.data.ts @@ -1,5 +1,5 @@ export const pkpNft = { - "address": "0xBBaa35e9b4a38c8f639d25f49c529967Ffeb0C06", + "address": "0x0122829576DDd317c44364238f5DDe205d6da25F", "abi": [ { "inputs": [ diff --git a/packages/contracts-sdk/src/abis/PKPNFTMetadata.data.ts b/packages/contracts-sdk/src/abis/PKPNFTMetadata.data.ts index 834096c8cb..9479797b8b 100644 --- a/packages/contracts-sdk/src/abis/PKPNFTMetadata.data.ts +++ b/packages/contracts-sdk/src/abis/PKPNFTMetadata.data.ts @@ -1,5 +1,5 @@ export const pkpNftMetadata = { - "address": "0xa7F9bDf4fF1aEb9C1AB41E965610Df5699b09D68", + "address": "0xFB7eeE9859eA34D06962f4362FA7B4E294039B05", "abi": [ { "inputs": [ diff --git a/packages/contracts-sdk/src/abis/PKPPermissions.data.ts b/packages/contracts-sdk/src/abis/PKPPermissions.data.ts index 8344792ad5..cb8614285d 100644 --- a/packages/contracts-sdk/src/abis/PKPPermissions.data.ts +++ b/packages/contracts-sdk/src/abis/PKPPermissions.data.ts @@ -1,5 +1,5 @@ export const pkpPermissions = { - "address": "0x61Dc305F03cFF5Ba8f39D5F8F9BE2D3298e8aE38", + "address": "0x05A6d463c73adA7A0D3Af317Cd68271e5E34bCd4", "abi": [ { "inputs": [ diff --git a/packages/contracts-sdk/src/abis/PubkeyRouter.data.ts b/packages/contracts-sdk/src/abis/PubkeyRouter.data.ts index 83821d12ec..2a1972cf76 100644 --- a/packages/contracts-sdk/src/abis/PubkeyRouter.data.ts +++ b/packages/contracts-sdk/src/abis/PubkeyRouter.data.ts @@ -1,5 +1,5 @@ export const pubkeyRouter = { - "address": "0xb26b4DC365843cDaE996F526913D3D4F45343aE8", + "address": "0x9da98532bd3b7cDDA18ae34DFeCdeBBb75AC3F7D", "abi": [ { "inputs": [ diff --git a/packages/contracts-sdk/src/abis/RateLimitNFT.data.ts b/packages/contracts-sdk/src/abis/RateLimitNFT.data.ts index b4698b29a0..77e7d91070 100644 --- a/packages/contracts-sdk/src/abis/RateLimitNFT.data.ts +++ b/packages/contracts-sdk/src/abis/RateLimitNFT.data.ts @@ -1,5 +1,5 @@ export const rateLimitNft = { - "address": "0x8624EE1100B45DD3e55B7399446CbF01ab5Db333", + "address": "0x4B15DAC8f60fC2B5A691A13bD5eC26aaa0f50a0b", "abi": [ { "inputs": [], diff --git a/packages/contracts-sdk/src/abis/Staking.data.ts b/packages/contracts-sdk/src/abis/Staking.data.ts index 558f72ce28..084b7b1dd5 100644 --- a/packages/contracts-sdk/src/abis/Staking.data.ts +++ b/packages/contracts-sdk/src/abis/Staking.data.ts @@ -1,5 +1,5 @@ export const staking = { - "address": "0x07A5bE9e0Aa724563e904B5e7AF37921e193f801", + "address": "0x187e8770A9ad58a83b3A619ba9bb3629dA6E25B1", "abi": [ { "inputs": [ @@ -1195,13 +1195,6 @@ export const staking = { "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "pauseEpoch", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { diff --git a/packages/contracts-sdk/src/abis/Staking.json b/packages/contracts-sdk/src/abis/Staking.json index b9e185facf..eeb99b6152 100644 --- a/packages/contracts-sdk/src/abis/Staking.json +++ b/packages/contracts-sdk/src/abis/Staking.json @@ -1193,13 +1193,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "pauseEpoch", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { diff --git a/packages/contracts-sdk/src/abis/Staking.ts b/packages/contracts-sdk/src/abis/Staking.ts index 5443260f8e..2406bf4677 100755 --- a/packages/contracts-sdk/src/abis/Staking.ts +++ b/packages/contracts-sdk/src/abis/Staking.ts @@ -135,7 +135,6 @@ export type StakingMethodNames = | 'nextValidatorCountForConsensus' | 'nodeAddressToStakerAddress' | 'owner' - | 'pauseEpoch' | 'readyForNextEpoch' | 'renounceOwnership' | 'requestToJoin' @@ -608,15 +607,6 @@ export interface Staking { * Type: function */ owner(overrides?: ContractCallOverrides): Promise; - /** - * Payable: false - * Constant: false - * StateMutability: nonpayable - * Type: function - */ - pauseEpoch( - overrides?: ContractTransactionOverrides - ): Promise; /** * Payable: false * Constant: true diff --git a/packages/contracts-sdk/src/abis/StakingBalances.data.ts b/packages/contracts-sdk/src/abis/StakingBalances.data.ts index 5c93b5d5e3..6f6355dc70 100644 --- a/packages/contracts-sdk/src/abis/StakingBalances.data.ts +++ b/packages/contracts-sdk/src/abis/StakingBalances.data.ts @@ -1,5 +1,5 @@ export const stakingBalances = { - "address": "0xAB783F4B8ceD3f98Adc169d50F1063dD0517EEA8", + "address": "0x23Ab8F5cD37be7B6036a17fD75A842533d2D39d0", "abi": [ { "inputs": [ diff --git a/packages/contracts-sdk/src/deployed-contracts.json b/packages/contracts-sdk/src/deployed-contracts.json index 9ac2458a7b..bba63de850 100644 --- a/packages/contracts-sdk/src/deployed-contracts.json +++ b/packages/contracts-sdk/src/deployed-contracts.json @@ -3,84 +3,84 @@ "name": "stakingBalancesContractAddress", "correctedName": "StakingBalances", "exportName": "stakingBalances", - "abiPath": "https://raw.githubusercontent.com/LIT-Protocol/lit-assets/develop/rust/lit-core/lit-blockchain/abis/StakingBalances.json", - "address": "0xAB783F4B8ceD3f98Adc169d50F1063dD0517EEA8" + "abiPath": "../lit-assets/rust/lit-core/lit-blockchain/abis/StakingBalances.json", + "address": "0x23Ab8F5cD37be7B6036a17fD75A842533d2D39d0" }, { "name": "stakingContractAddress", "correctedName": "Staking", "exportName": "staking", - "abiPath": "https://raw.githubusercontent.com/LIT-Protocol/lit-assets/develop/rust/lit-core/lit-blockchain/abis/Staking.json", - "address": "0x07A5bE9e0Aa724563e904B5e7AF37921e193f801" + "abiPath": "../lit-assets/rust/lit-core/lit-blockchain/abis/Staking.json", + "address": "0x187e8770A9ad58a83b3A619ba9bb3629dA6E25B1" }, { "name": "multisenderContractAddress", "correctedName": "Multisender", "exportName": "multisender", - "abiPath": "https://raw.githubusercontent.com/LIT-Protocol/lit-assets/develop/rust/lit-core/lit-blockchain/abis/Multisender.json", - "address": "0x373195723448308d43a43989790C0b768Ef14853" + "abiPath": "../lit-assets/rust/lit-core/lit-blockchain/abis/Multisender.json", + "address": "0xacAe3822240234d8Ebbb591787a2E2b6247Ce63e" }, { "name": "litTokenContractAddress", "correctedName": "LITToken", "exportName": "litToken", - "abiPath": "https://raw.githubusercontent.com/LIT-Protocol/lit-assets/develop/rust/lit-core/lit-blockchain/abis/LITToken.json", + "abiPath": "../lit-assets/rust/lit-core/lit-blockchain/abis/LITToken.json", "address": "0x53695556f8a1a064EdFf91767f15652BbfaFaD04" }, { "name": "pubkeyRouterContractAddress", "correctedName": "PubkeyRouter", "exportName": "pubkeyRouter", - "abiPath": "https://raw.githubusercontent.com/LIT-Protocol/lit-assets/develop/rust/lit-core/lit-blockchain/abis/PubkeyRouter.json", - "address": "0xb26b4DC365843cDaE996F526913D3D4F45343aE8" + "abiPath": "../lit-assets/rust/lit-core/lit-blockchain/abis/PubkeyRouter.json", + "address": "0x9da98532bd3b7cDDA18ae34DFeCdeBBb75AC3F7D" }, { "name": "pkpNftContractAddress", "correctedName": "PKPNFT", "exportName": "pkpNft", - "abiPath": "https://raw.githubusercontent.com/LIT-Protocol/lit-assets/develop/rust/lit-core/lit-blockchain/abis/PKPNFT.json", - "address": "0xBBaa35e9b4a38c8f639d25f49c529967Ffeb0C06" + "abiPath": "../lit-assets/rust/lit-core/lit-blockchain/abis/PKPNFT.json", + "address": "0x0122829576DDd317c44364238f5DDe205d6da25F" }, { "name": "rateLimitNftContractAddress", "correctedName": "RateLimitNFT", "exportName": "rateLimitNft", - "abiPath": "https://raw.githubusercontent.com/LIT-Protocol/lit-assets/develop/rust/lit-core/lit-blockchain/abis/RateLimitNFT.json", - "address": "0x8624EE1100B45DD3e55B7399446CbF01ab5Db333" + "abiPath": "../lit-assets/rust/lit-core/lit-blockchain/abis/RateLimitNFT.json", + "address": "0x4B15DAC8f60fC2B5A691A13bD5eC26aaa0f50a0b" }, { "name": "pkpHelperContractAddress", "correctedName": "PKPHelper", "exportName": "pkpHelper", - "abiPath": "https://raw.githubusercontent.com/LIT-Protocol/lit-assets/develop/rust/lit-core/lit-blockchain/abis/PKPHelper.json", - "address": "0xA8C519a051b85A2010C498145C698074782AB6DF" + "abiPath": "../lit-assets/rust/lit-core/lit-blockchain/abis/PKPHelper.json", + "address": "0x0600cBB5dc983A970b165390Da00e699E5baeDD1" }, { "name": "pkpPermissionsContractAddress", "correctedName": "PKPPermissions", "exportName": "pkpPermissions", - "abiPath": "https://raw.githubusercontent.com/LIT-Protocol/lit-assets/develop/rust/lit-core/lit-blockchain/abis/PKPPermissions.json", - "address": "0x61Dc305F03cFF5Ba8f39D5F8F9BE2D3298e8aE38" + "abiPath": "../lit-assets/rust/lit-core/lit-blockchain/abis/PKPPermissions.json", + "address": "0x05A6d463c73adA7A0D3Af317Cd68271e5E34bCd4" }, { "name": "pkpNftMetadataContractAddress", "correctedName": "PKPNFTMetadata", "exportName": "pkpNftMetadata", - "abiPath": "https://raw.githubusercontent.com/LIT-Protocol/lit-assets/develop/rust/lit-core/lit-blockchain/abis/PKPNFTMetadata.json", - "address": "0xa7F9bDf4fF1aEb9C1AB41E965610Df5699b09D68" + "abiPath": "../lit-assets/rust/lit-core/lit-blockchain/abis/PKPNFTMetadata.json", + "address": "0xFB7eeE9859eA34D06962f4362FA7B4E294039B05" }, { "name": "allowlistContractAddress", "correctedName": "Allowlist", "exportName": "allowlist", - "abiPath": "https://raw.githubusercontent.com/LIT-Protocol/lit-assets/develop/rust/lit-core/lit-blockchain/abis/Allowlist.json", - "address": "0x01385531dF2397425acb2Dffd3fA5Fd76729504a" + "abiPath": "../lit-assets/rust/lit-core/lit-blockchain/abis/Allowlist.json", + "address": "0x9fb501502402Fe4A8CE44c8C39a5d63787ED653c" }, { "name": "resolverContractAddress", "correctedName": "ContractResolver", "exportName": "contractResolver", - "abiPath": "https://raw.githubusercontent.com/LIT-Protocol/lit-assets/develop/rust/lit-core/lit-blockchain/abis/ContractResolver.json", - "address": "0x0bca885Cf322D0E478DC48Fb84b4f522144db9D7" + "abiPath": "../lit-assets/rust/lit-core/lit-blockchain/abis/ContractResolver.json", + "address": "0x53Df74f2Ca020ab439002158e6De0A32b1AA66D1" } ] \ No newline at end of file diff --git a/packages/core/src/lib/lit-core.ts b/packages/core/src/lib/lit-core.ts index 5af1ec4e83..54407371dd 100644 --- a/packages/core/src/lib/lit-core.ts +++ b/packages/core/src/lib/lit-core.ts @@ -1,4 +1,6 @@ import { computeHDPubKey } from '@lit-protocol/crypto'; +import { keccak256 } from '@ethersproject/keccak256'; +import { toUtf8Bytes } from '@ethersproject/strings'; import { canonicalAccessControlConditionFormatter, canonicalEVMContractConditionFormatter, @@ -46,6 +48,7 @@ import { SuccessNodePromises, SupportedJsonRequests, } from '@lit-protocol/types'; +import { ethers } from 'ethers'; export class LitCore { config: LitNodeClientConfig; @@ -590,7 +593,10 @@ export class LitCore { * @param sigType * @returns {string} public key */ - computeHDPubKey = (keyId: string, sigType: SIGTYPE = SIGTYPE.EcdsaCaitSith) => { + computeHDPubKey = ( + keyId: string, + sigType: SIGTYPE = SIGTYPE.EcdsaCaitSith + ) => { if (!this.hdRootPubkeys) { throwError({ message: `root public keys not found, have you connected to the nodes?`, @@ -601,20 +607,23 @@ export class LitCore { return computeHDPubKey(this.hdRootPubkeys as string[], keyId, sigType); }; - /** - * Telem collector for function invokation counts - * @param date - * @param functionName - * @param executionTime + * Calculates a Key Id for claiming a pkp based on a user identifier and an app identifier. + * The key Identifier is an Auth Method Id which scopes the key uniquely to a specific application context. + * These identifiers are specific to each auth method and will derive the public key protion of a pkp which will be persited + * when a key is claimed. + * | Auth Method | User ID | App ID | + * |:------------|:-------|:-------| + * | Google OAuth | token `sub` | token `aud` | + * | Discord OAuth | user id | client app identifier | + * | Stytch OTP |token `sub` | token `aud`| + * @param userId {string} user identifier for the Key Identifier + * @param appId {string} app identifier for the Key Identifier + * @returns {String} public key of pkp when claimed */ - collectData = (date: string, functionName: string, executionTime: number) => { - fetch(TELEM_API_URL + '/collect', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ date, functionName, executionTime }), - }); - }; + computeHDKeyId(userId: string, appId: string): String { + return ethers.utils.keccak256( + ethers.utils.toUtf8Bytes(`${userId}:${appId}`) + ); + } } diff --git a/packages/lit-auth-client/src/lib/providers/BaseProvider.ts b/packages/lit-auth-client/src/lib/providers/BaseProvider.ts index 6cf450875e..55bec6112c 100644 --- a/packages/lit-auth-client/src/lib/providers/BaseProvider.ts +++ b/packages/lit-auth-client/src/lib/providers/BaseProvider.ts @@ -200,6 +200,29 @@ export abstract class BaseProvider { const res = await this.litNodeClient.claimKeyId(claimRequest); return res; } + /** + * Calculates a public key for a given `key identifier` which is an `Auth Method Identifier` + * the Auth Method Identifier is a hash of a user identifier and app idendtifer. + * These identifiers are specific to each auth method and will derive the public key protion of a pkp which will be persited + * when a key is claimed. + * | Auth Method | User ID | App ID | + * |:------------|:-------|:-------| + * | Google OAuth | token `sub` | token `aud` | + * | Discord OAuth | user id | client app identifier | + * | Stytch OTP |token `sub` | token `aud`| + * @param userId + * @param appId + * @returns + */ + computPublicKeyFromAuthMethod = async ( + authMethod: AuthMethod + ): Promise => { + const authMethodId = await this.getAuthMethodId(authMethod); + if (!this.litNodeClient) { + throw new Error('Lit Node Client is configured'); + } + return this.litNodeClient.computeHDPubKey(authMethodId); + }; /** * Generate request data for minting and fetching PKPs via relay server diff --git a/packages/lit-node-client-nodejs/src/lib/lit-node-client-nodejs.ts b/packages/lit-node-client-nodejs/src/lib/lit-node-client-nodejs.ts index 99caeaac2a..debec0f636 100644 --- a/packages/lit-node-client-nodejs/src/lib/lit-node-client-nodejs.ts +++ b/packages/lit-node-client-nodejs/src/lib/lit-node-client-nodejs.ts @@ -1004,7 +1004,6 @@ export class LitNodeClientNodeJs extends LitCore { const sigShares: Array = shares.map((s: any) => { const share = this._getFlattenShare(s); - console.log('YY share', share); return { sigType: share.sigType, @@ -1070,6 +1069,31 @@ export class LitNodeClientNodeJs extends LitCore { return signatures; }; + getClaims = (claims: any[]): Record => { + let keys: string[] = Object.keys(claims[0]); + let signatures: Record = {}; + let claimRes: Record = {}; + for (let i = 0; i < keys.length; i++) { + let claimSet: {signature: string, keyId: string}[] = claims.map(c => c[keys[i]]); + signatures[keys[i]] = []; + for (let j = 0; i < claimSet.length; i++) { + let sig = ethers.utils.splitSignature(`0x${claimSet[j].signature}`); + let convertedSig = { + r: sig.r, + s: sig.s, + v: sig.v, + }; + signatures[keys[i]].push(convertedSig); + } + claimRes[keys[i]] = { + signatures: signatures[keys[i]], + keyId: claimSet[0].keyId + }; + } + + return claimRes; + } + /** * * Get a single signature @@ -1184,8 +1208,12 @@ export class LitNodeClientNodeJs extends LitCore { log('responseData', JSON.stringify(responseData, null, 2)); // -- in the case where we are not signing anything on Lit action and using it as purely serverless function - if (Object.keys(responseData[0].signedData).length <= 0) { + if ( + Object.keys(responseData[0].signedData).length <= 0 && + Object.keys(responseData[0].claimData).length <= 0 + ) { return { + claims: {}, signatures: null, decryptions: [], response: responseData[0].response, @@ -1226,8 +1254,22 @@ export class LitNodeClientNodeJs extends LitCore { responseData.map((r: NodeLog) => r.logs) ); + // -- 4. combine claims + const claimsList = responseData.map((r) => { + const { claimData } = r; + for (const key of Object.keys(claimData)) { + for (const subkey of Object.keys(claimData[key])) { + if (typeof claimData[key][subkey] == 'string') { + claimData[key][subkey] = claimData[key][subkey].replaceAll('"', ''); + } + + } + } + }); + const claims = this.getClaims(claimsList); // ========== Result ========== let returnVal: ExecuteJsResponse = { + claims, signatures, decryptions: [], // FIXME: Fix if and when we enable decryptions from within a Lit Action. response, @@ -2117,8 +2159,8 @@ export class LitNodeClientNodeJs extends LitCore { errorCode: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.name, }); } + const requestId = this.getRequestId(); const nodePromises = await this.getNodePromises((url: string) => { - const requestId = this.getRequestId(); const nodeRequestParams = { authMethod: params.authMethod, }; @@ -2181,7 +2223,7 @@ export class LitNodeClientNodeJs extends LitCore { }; } else { return throwError({ - message: 'claim request has failed', + message: `Claim request has failed. Request trace id: lit_${requestId} `, errorKind: LIT_ERROR.UNKNOWN_ERROR.kind, errorCode: LIT_ERROR.UNKNOWN_ERROR.code, }); diff --git a/packages/lit-node-client/src/lib/lit-node-client.spec.ts b/packages/lit-node-client/src/lib/lit-node-client.spec.ts index c473e932bb..eb92026fd0 100644 --- a/packages/lit-node-client/src/lib/lit-node-client.spec.ts +++ b/packages/lit-node-client/src/lib/lit-node-client.spec.ts @@ -108,14 +108,14 @@ describe('Lit Actions', () => { it('should claim key id from auth method', async () => { - + const authMethod = { + authMethodType: 4, + accessToken: LITCONFIG.AUTH_METHOD_ACCESS_TOKEN + }; let res = await client.claimKeyId({ - authMethod: { - authMethodType: 4, - accessToken: "RTPcbUUguY7YtOjZhKeXtEPTYkXfgX" - } + authMethod }); - + const data = { // hello world in Uint8Array toSign: [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100], @@ -123,14 +123,10 @@ describe('Lit Actions', () => { sigName: 'hello-world-sig', }; - let authMethod = { - authMethodType: 4, - accessToken: "RTPcbUUguY7YtOjZhKeXtEPTYkXfgX" - } let sig = await client.pkpSign({ toSign: data.toSign, - pubKey: "0x044ec325db817193c3a01088d082ded81dc0a29ad615a67b87b9e295d9a1c91d955f8aeeec551d5d4930795f5c390e369f745e36e97893ead710354ee882ed60c0", + pubKey: res.pubkey, authMethods: [authMethod], authSig: LITCONFIG.CONTROLLER_AUTHSIG, }); diff --git a/packages/lit-node-client/src/lib/lit-node-client2.spec.ts b/packages/lit-node-client/src/lib/lit-node-client2.spec.ts new file mode 100644 index 0000000000..1d29d120a3 --- /dev/null +++ b/packages/lit-node-client/src/lib/lit-node-client2.spec.ts @@ -0,0 +1,70 @@ +import { LitNodeClient } from './lit-node-client'; +import * as LITCONFIG from 'lit.config.json'; + +let client: LitNodeClient; + +describe('Lit Actions', async () => { + client = new LitNodeClient({ + litNetwork: 'cayenne', + debug: true + }); + + await client.connect(); + + test('should be connected', async () => { + expect(client.ready).toBe(true); + }); + + test('lit action log should return hello world', async () => { + + const res = await client.executeJs({ + authSig: LITCONFIG.CONTROLLER_AUTHSIG, + code: `(async () => { + console.log('hello world') + })();`, + jsParams: { + publicKey: LITCONFIG.PKP_PUBKEY, + }, + }) + + expect(res.logs).toContain('hello world'); + }); + + it('lit action response should return json {hello: "world"}', async () => { + const res = await client.executeJs({ + authSig: LITCONFIG.CONTROLLER_AUTHSIG, + code: `(async () => { + LitActions.setResponse({ + response: JSON.stringify({hello: 'world'}) + }); + })();`, + jsParams: { + publicKey: LITCONFIG.PKP_PUBKEY, + }, + }) + expect(res.response).toEqual(JSON.stringify({ hello: 'world' })); + }); + + it('lit action should sign a message', async () => { + + const res = await client.executeJs({ + authSig: LITCONFIG.CONTROLLER_AUTHSIG, + code: `(async () => { + const sigShare = await LitActions.signEcdsa({ + toSign, + publicKey, + sigName + }); + })();`, + jsParams: { + // hello world in Uint8Array + toSign: [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100], + publicKey: LITCONFIG.PKP_PUBKEY, + sigName: 'hello-world-sig', + }, + }); + + expect(res).toBe(1); + + }); +}); diff --git a/packages/types/src/lib/interfaces.ts b/packages/types/src/lib/interfaces.ts index 467ed3bce4..108bb1881b 100644 --- a/packages/types/src/lib/interfaces.ts +++ b/packages/types/src/lib/interfaces.ts @@ -5,6 +5,7 @@ import { AccessControlConditions, Chain, ClaimProcessor, + ClaimResult, ConditionType, EncryptedSymmetricKey, EvmContractConditions, @@ -555,6 +556,7 @@ export interface ExecuteJsResponse { decryptions: any[]; response: string; logs: string; + claims: Record; debug?: { allNodeResponses: NodeResponse[]; allNodeLogs: NodeLog[]; @@ -571,6 +573,7 @@ export interface SendNodeCommand { } export interface NodeShare { + claimData: any; shareIndex: any; unsignedJwt: any; signedData: any; diff --git a/tools/scripts/endisable-cache.mjs b/tools/scripts/endisable-cache.mjs new file mode 100644 index 0000000000..d0d304f6f4 --- /dev/null +++ b/tools/scripts/endisable-cache.mjs @@ -0,0 +1,32 @@ +import fs from 'fs'; +import path from 'path'; +import { greenLog } from './utils.mjs'; + +/** + * This script enables or disables the cache in the nx.json file. + * Usage: node endisable-cache.mjs --enable=true + * --enable: Set to true to enable the cache, false to disable it. + */ + +const args = process.argv.slice(2); +const enableCache = + args.find((arg) => arg.startsWith('--enable'))?.split('=')[1] === 'true'; + +const nxConfigPath = path.join(process.cwd(), 'nx.json'); +const nxConfig = JSON.parse(fs.readFileSync(nxConfigPath, 'utf-8')); + +if (enableCache) { + nxConfig.tasksRunnerOptions.default.options = { + cacheableOperations: ['build'], + // cacheableDirectories: ['node_modules'], + }; +} else { + delete nxConfig.tasksRunnerOptions.default.options; +} + +fs.writeFileSync(nxConfigPath, JSON.stringify(nxConfig, null, 2)); + +greenLog('\nšŸ“ This script enables or disables the cache in the nx.json file.\n', true); +greenLog('--enable=true: Enable the cache', true); +greenLog('--enable=false: Disable the cache', true); +process.exit(); \ No newline at end of file diff --git a/tools/scripts/test-script.mjs b/tools/scripts/test-script.mjs new file mode 100644 index 0000000000..3b730222c7 --- /dev/null +++ b/tools/scripts/test-script.mjs @@ -0,0 +1,84 @@ +import fs from 'fs'; +import path from 'path'; + +import { bunSpawn, greenLog, redLog } from './utils.mjs'; + +/** + * This script recursively looks for files in the directory ./packages that ends with .spec.ts or .test.ts. + * When run with node ./tools/scripts/test-scripts.mjs , it runs the script with command 'bun test ' + * + * Arguments can be provided in the format "--=" + * + * Example: node ./tools/scripts/test-scripts.mjs --dir=./packages --ext=.spec.ts,.test.ts + */ + +const args = process.argv.slice(2); +const TEST_DIR = + args.find((arg) => arg.startsWith('--dir'))?.split('=')[1] || './packages'; +const TEST_FILE_EXTENSIONS = args + .find((arg) => arg.startsWith('--ext')) + ?.split('=')[1] + ?.split(',') || ['.spec.ts', '.test.ts']; + +/** + * Recursively find test files in the given directory + * @param {string} dir - The directory to search in + * @param {string[]} exts - The file extensions to look for + * @returns {string[]} - The paths of the found test files + */ +function findTestFiles(dir, exts) { + let testFiles = []; + const files = fs.readdirSync(dir); + + for (const file of files) { + const filePath = path.join(dir, file); + const stat = fs.statSync(filePath); + + // Extract the extension from the file name considering the possibility of multiple dots in the file name + const fileExtension = '.' + file.split('.').slice(1).join('.'); + + if (stat.isDirectory()) { + testFiles = testFiles.concat(findTestFiles(filePath, exts)); + } else if (exts.includes(fileExtension)) { + testFiles.push(filePath); + } + } + + return testFiles; +} + +/** + * Run the test command for the given test file + * @param {string} testFile - The path of the test file + */ +async function runTest(testFile) { + const command = `bun test ${testFile}`; + console.log('Running command: ', command); + await bunSpawn(command, { stdout: 'inherit' }); +} + +const testFiles = findTestFiles(TEST_DIR, TEST_FILE_EXTENSIONS); + +greenLog(`${testFiles.length} test files found!`, true); + +const testName = process.argv[2]; + +if (testName) { + const matchingTestFiles = testFiles.filter((file) => { + return file.includes(testName); + }); + + if (!matchingTestFiles.length) { + console.error(`No test files matching "${testName}" found.`); + process.exit(1); + } + + for (const filePath of matchingTestFiles) { + await runTest(filePath); + } +} else { + redLog('Please provide a test name. eg. bun test:file lit-node-client'); + process.exit(1); +} + +process.exit(0); \ No newline at end of file diff --git a/tools/scripts/utils.mjs b/tools/scripts/utils.mjs index 2263a90e49..069f490600 100644 --- a/tools/scripts/utils.mjs +++ b/tools/scripts/utils.mjs @@ -162,6 +162,19 @@ export const spawnCommand = ( }); }; +export const bunSpawn = async (commands, options = {}) => { + const defaultOptions = { stdout: 'inherit' }; + + let _commands = commands.split(' '); + + const proc = Bun.spawn(_commands, { + ...defaultOptions, + ...options, + }); + + await proc.exited; +}; + export const spawnListener = (commands, callback, prefix = '', color = 31) => { let _commands = commands.split(' '); // let eventName = _commands.join('-');