Skip to content
Closed
Show file tree
Hide file tree
Changes from 20 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