Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Feat/tinny standalone #722

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/out-tsc
**/dist
**/out-tsc
local-tests/**/*.js

# dependencies
node_modules
Expand Down
97 changes: 49 additions & 48 deletions local-tests/build.mjs
Original file line number Diff line number Diff line change
@@ -1,65 +1,66 @@
import * as esbuild from 'esbuild';
import { nodeExternalsPlugin } from 'esbuild-node-externals';
import fs from 'fs';
import { fileURLToPath } from 'url';

const TEST_DIR = 'local-tests';
const ALLOW_LIST = [
'ethers',
'@lit-protocol/accs-schemas',
'@lit-protocol/contracts',
'crypto',
'secp256k1',
];

const getPath = (relativePath) =>
fileURLToPath(new URL(relativePath, import.meta.url));

/**
* Builds the project using esbuild.
* @returns {Promise<void>} A promise that resolves when the build is complete.
* Common esbuild configuration options.
* @param {string} entry - Entry file path.
* @param {string} outfile - Output file path.
* @param {string} [globalName] - Optional global name for the bundle.
* @returns {esbuild.BuildOptions} Esbuild configuration object.
*/
const createBuildConfig = (entry, outfile, globalName) => ({
entryPoints: [getPath(entry)],
outfile: getPath(outfile),
bundle: true,
plugins: [
nodeExternalsPlugin({
allowList: ALLOW_LIST,
}),
],
platform: 'node',
target: 'esnext',
format: 'esm',
inject: [getPath('./shim.mjs')],
mainFields: ['module', 'main'],
...(globalName ? { globalName } : {}),
});

/**
* Builds the CLI-enabled version of Tinny.
*/
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'],
});
await esbuild.build(createBuildConfig('./test.ts', './build/test.mjs'));
};

/**
* Inserts a polyfill at the beginning of a file.
* The polyfill ensures that the global `fetch` function is available.
* @returns {void}
* Bundles Tinny as a standalone package.
*/
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}`);
}
export const bundle = async () => {
await esbuild.build(
createBuildConfig('./index.ts', './index.js', 'tinnySdk')
);
};

// Go!
(async () => {
const start = Date.now();
await build();
postBuildPolyfill();
console.log(`[build.mjs] 🚀 Build time: ${Date.now() - start}ms`);
try {
await build();
await bundle();
console.log(`[build.mjs] 🚀 Build time: ${Date.now() - start}ms`);
} catch (error) {
console.error(`[build.mjs] ❌ Build failed:`, error);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will hide the error. We can add a process.exit(1) to notify caller

}
})();
33 changes: 33 additions & 0 deletions local-tests/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { TinnyEnvironment } from './setup/tinny-environment';
import { runInBand, runTestsParallel } from './setup/tinny-operations';
import * as tinnyTests from './tests';
import { getEoaSessionSigs } from './setup/session-sigs/get-eoa-session-sigs';
import { getLitActionSessionSigs } from './setup/session-sigs/get-lit-action-session-sigs';
import { getPkpSessionSigs } from './setup/session-sigs/get-pkp-session-sigs';
import { AccessControlConditions } from './setup/accs/accs';

export {
TinnyEnvironment,
runInBand,
runTestsParallel,
tinnyTests,
getEoaSessionSigs,
getLitActionSessionSigs,
getPkpSessionSigs,
AccessControlConditions,
};

// Usage
// const devEnv = new TinnyEnvironment();

// await devEnv.init();

// const testConfig = {
// tests: {
// testEthAuthSigToEncryptDecryptString,
// },
// devEnv,
// }

// const res = await runTestsParallel(testConfig);
// console.log("res:", res);
97 changes: 97 additions & 0 deletions local-tests/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
{
"name": "@lit-protocol/tinny",
"version": "0.0.5",
"description": "A package to run the test script for Lit Protocol with custom commands",
"type": "module",
"main": "./index.js",
"typings": "./index.ts",
"license": "MIT",
"author": "Anson (https://github.com/ansonhkg)",
"publishConfig": {
"access": "public",
"directory": "./"
},
"dependencies": {
"@cosmjs/amino": "0.30.1",
"@cosmjs/crypto": "0.30.1",
"@cosmjs/encoding": "0.30.1",
"@cosmjs/proto-signing": "0.30.1",
"@cosmjs/stargate": "0.30.1",
"@cypress/code-coverage": "^3.10.0",
"@cypress/react": "^6.2.0",
"@cypress/webpack-dev-server": "^2.3.0",
"@lit-protocol/accs-schemas": "0.0.7",
"@metamask/eth-sig-util": "5.0.2",
"@mysten/sui.js": "^0.37.1",
"@playwright/test": "^1.25.2",
"@simplewebauthn/browser": "^7.2.0",
"@simplewebauthn/typescript-types": "^7.0.0",
"@spruceid/siwe-parser": "2.0.0",
"@synthetixio/js": "^2.41.0",
"@testing-library/cypress": "^8.0.3",
"@testing-library/react": "^13.4.0",
"@types/testing-library__cypress": "^5.0.9",
"@walletconnect/core": "2.9.2",
"@walletconnect/ethereum-provider": "2.9.2",
"@walletconnect/jsonrpc-utils": "1.0.8",
"@walletconnect/modal": "2.6.1",
"@walletconnect/types": "2.9.2",
"@walletconnect/utils": "2.9.2",
"@walletconnect/web3wallet": "1.8.8",
"@websaam/nx-esbuild": "^0.0.1",
"ajv": "^8.12.0",
"axios": "^0.27.2",
"base64url": "^3.0.1",
"bitcoinjs-lib": "^6.1.0",
"blockstore-core": "^3.0.0",
"browserify-zlib": "^0.2.0",
"bs58": "^5.0.0",
"bytes32": "^0.0.3",
"cbor-web": "^9.0.1",
"commander": "^9.4.0",
"concurrently": "^7.4.0",
"core-js": "^3.6.5",
"cross-fetch": "3.1.4",
"crypto-browserify": "^3.12.0",
"cypress-wait-until": "^1.7.2",
"cypress-watch-and-reload": "^1.10.3",
"date-and-time": "^2.4.1",
"dotenv": "^16.0.2",
"dotenv-parse-variables": "^2.0.0",
"download": "^8.0.0",
"ethers": "^5.7.1",
"etherscan-api": "^10.2.0",
"find-config": "^1.0.0",
"g": "^2.0.1",
"https-browserify": "^1.0.0",
"jose": "^4.14.4",
"jszip": "^3.10.1",
"micromodal": "^0.4.10",
"multiformats": "^9.7.1",
"nanoid": "3.3.4",
"next": "13.3.0",
"react": "18.0.0",
"react-dom": "18.0.0",
"regenerator-runtime": "0.13.7",
"secp256k1": "^5.0.0",
"serve": "^14.0.1",
"siwe": "^2.0.5",
"siwe-recap": "0.0.2-alpha.0",
"stream-browserify": "^3.0.0",
"stream-http": "^3.2.0",
"synthetix-js": "^2.74.1",
"tslib": "^2.3.0",
"tweetnacl": "^1.0.3",
"tweetnacl-util": "^0.15.1",
"uint8arrays": "^4.0.3",
"@openagenda/verror": "^3.1.4",
"ipfs-unixfs-importer": "12.0.1",
"@solana/web3.js": "^1.95.3",
"bech32": "^2.0.0",
"pako": "^2.1.0",
"@lit-protocol/misc": "^7.0.0",
"@lit-protocol/lit-node-client": "^7.0.0",
"@lit-protocol/lit-auth-client": "^7.0.0",
"@lit-protocol/contracts": "^0.0.71"
}
}
5 changes: 0 additions & 5 deletions local-tests/setup/tinny-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,6 @@ export interface ProcessEnvs {
*/
LIT_RPC_URL: string;

/**
* This is usually used when you're running tests locally depending how many nodes you are running.
*/
BOOTSTRAP_URLS: string[];

/**
* The list of private keys to use for testing.
*/
Expand Down
44 changes: 30 additions & 14 deletions local-tests/setup/tinny-environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
console.log('checking env', process.env['DEBUG']);
export class TinnyEnvironment {
public network: LIT_NETWORK_VALUES;
public customNetworkContext: any;

/**
* Environment variables used in the process.
Expand All @@ -42,11 +43,6 @@ export class TinnyEnvironment {
LIT_RPC_URL: process.env['LIT_RPC_URL'],
WAIT_FOR_KEY_INTERVAL:
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,
RUN_IN_BAND: process.env['RUN_IN_BAND'] === 'true',
RUN_IN_BAND_INTERVAL: parseInt(process.env['RUN_IN_BAND_INTERVAL']) || 5000,
Expand Down Expand Up @@ -105,15 +101,33 @@ export class TinnyEnvironment {
private _shivaClient: ShivaClient = new ShivaClient();
private _contractContext: LitContractContext | LitContractResolverContext;

constructor(network?: LIT_NETWORK_VALUES) {
constructor(
override?: Partial<ProcessEnvs> & { customNetworkContext?: any }
) {
this.customNetworkContext = override?.customNetworkContext;

// Merge default processEnvs with custom overrides
this.processEnvs = {
...this.processEnvs,
...override,
};

// if there are only 1 private key, duplicate it to make it 10 cus we might not have enough
// for the setup process
if (this.processEnvs.PRIVATE_KEYS.length === 1) {
this.processEnvs.PRIVATE_KEYS = new Array(10).fill(
this.processEnvs.PRIVATE_KEYS[0]
);
}

// -- setup network
this.network = network || this.processEnvs.NETWORK;
this.network = override?.NETWORK || this.processEnvs.NETWORK;

if (Object.values(LIT_NETWORK).indexOf(this.network) === -1) {
throw new Error(
`Invalid network environment. Please use one of ${Object.values(
LIT_NETWORK
)}`
`Invalid network environment ${
this.network
}. Please use one of ${Object.values(LIT_NETWORK)}`
);
}

Expand Down Expand Up @@ -235,7 +249,8 @@ export class TinnyEnvironment {

if (this.network === LIT_NETWORK.Custom || centralisation === 'unknown') {
const networkContext =
this?.testnet?.ContractContext ?? this._contractContext;
this.customNetworkContext ||
(this?.testnet?.ContractContext ?? this._contractContext);
this.litNodeClient = new LitNodeClient({
litNetwork: LIT_NETWORK.Custom,
rpcUrl: this.rpc,
Expand Down Expand Up @@ -341,8 +356,8 @@ export class TinnyEnvironment {
* Creates a random person.
* @returns A promise that resolves to the created person.
*/
async createRandomPerson() {
return await this.createNewPerson('Alice');
async createRandomPerson(name?: string) {
return await this.createNewPerson(name || 'Alice');
}

setUnavailable = (network: LIT_NETWORK_VALUES) => {
Expand Down Expand Up @@ -373,7 +388,8 @@ export class TinnyEnvironment {

await this.testnet.getTestnetConfig();
} else if (this.network === LIT_NETWORK.Custom) {
const context = await import('./networkContext.json');
const context =
this.customNetworkContext || (await import('./networkContext.json'));
this._contractContext = context;
}

Expand Down
3 changes: 2 additions & 1 deletion local-tests/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ import { testBatchGeneratePrivateKeys } from './tests/wrapped-keys/testBatchGene
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();
Expand Down Expand Up @@ -316,7 +315,9 @@ setLitActionsCodeToLocal();
},
devEnv,
};

let res;

if (devEnv.processEnvs.RUN_IN_BAND) {
res = await runInBand(testConfig);
} else {
Expand Down
Loading
Loading