diff --git a/.eslintignore b/.eslintignore index 36682a0d..16d7f861 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,4 +3,5 @@ node_modules/ executor/ vendor/ lib/ +dist/ chopsticks.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 42514fb6..0da4d5d5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,3 +42,42 @@ jobs: - name: Test substrate-api-sidecard with chopsticks node if: ${{ github.ref_name == 'master' }} run: yarn workspace @acala-network/chopsticks-e2e run sidecar + + playwright: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + - uses: actions/cache@v3 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + executor/target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + - name: Install toolchain + uses: dtolnay/rust-toolchain@nightly + with: + toolchain: nightly-2022-10-30 + components: rustfmt + target: wasm32-unknown-unknown + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.x + cache: 'yarn' + - run: yarn --immutable + - run: yarn build-wasm + - name: Install Playwright Browsers + run: npx playwright install --with-deps + - name: Run Playwright tests + run: yarn workspace @acala-network/web-test test + - uses: actions/upload-artifact@v3 + if: always() + with: + name: playwright-report + path: packages/web-test/playwright-report/ + retention-days: 30 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 976b18ec..bd6b4764 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -34,12 +34,8 @@ jobs: registry-url: https://registry.npmjs.org/ - run: yarn --immutable - run: yarn check - - run: yarn build-wasm - run: yarn build - # Make sure chopsticks and executor version are the same - - run: node -e "assert(require('./packages/chopsticks/package.json').version === require('./executor/pkg/package.json').version, 'Chopsticks and executor version not the same. Please update Cargo.toml version')" - # version containing a hyphen, publish as beta, i.e: 1.0.0-1 - run: | if npm pkg get version --workspace @acala-network/chopsticks | jq '."@acala-network/chopsticks"' | grep '-'; then TAG='--tag beta'; fi @@ -54,10 +50,10 @@ jobs: env: NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} - # - name: Publish @acala-network/chopsticks-core - # run: yarn workspace @acala-network/chopsticks-core npm publish --tolerate-republish --access public ${{ env.NPM_TAG }} - # env: - # NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} + - name: Publish @acala-network/chopsticks-core + run: yarn workspace @acala-network/chopsticks-core npm publish --tolerate-republish --access public ${{ env.NPM_TAG }} + env: + NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} - name: Publish @acala-network/chopsticks-executor run: yarn workspace @acala-network/chopsticks-executor npm publish --tolerate-republish --access public ${{ env.NPM_TAG }} diff --git a/.gitignore b/.gitignore index 35acc13e..d4d40044 100644 --- a/.gitignore +++ b/.gitignore @@ -128,3 +128,4 @@ dist preview/ lib +.parcel-cache diff --git a/executor/.gitignore b/executor/.gitignore new file mode 100644 index 00000000..4022d9e0 --- /dev/null +++ b/executor/.gitignore @@ -0,0 +1,2 @@ +browser +node diff --git a/executor/package.json b/executor/package.json new file mode 100644 index 00000000..c3db3838 --- /dev/null +++ b/executor/package.json @@ -0,0 +1,22 @@ +{ + "name": "@acala-network/chopsticks-executor", + "description": "Chopsticks executor", + "version": "0.8.0-0", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/AcalaNetwork/chopsticks" + }, + "scripts": { + "clean": "rm -rf web node", + "build": "wasm-pack build --target web --out-dir browser; wasm-pack build --target nodejs --out-dir node" + }, + "files": [ + "browser/chopsticks_*", + "node/chopsticks_*" + ], + "main": "node/chopsticks_executor.js", + "types": "browser/chopsticks_executor.d.ts", + "browser": "browser/chopsticks_executor.js", + "stableVersion": "0.7.3" +} diff --git a/executor/pkg/package.json b/executor/pkg/package.json deleted file mode 100644 index 6e48dec9..00000000 --- a/executor/pkg/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "@acala-network/chopsticks-executor", - "description": "Chopsticks executor", - "version": "0.7.3", - "license": "Apache-2.0", - "repository": { - "type": "git", - "url": "https://github.com/AcalaNetwork/chopsticks" - }, - "files": [ - "chopsticks_executor_bg.wasm", - "chopsticks_executor.js", - "chopsticks_executor.d.ts" - ], - "main": "chopsticks_executor.js", - "types": "chopsticks_executor.d.ts" -} diff --git a/executor/src/lib.rs b/executor/src/lib.rs index 1f11b028..4db121e9 100644 --- a/executor/src/lib.rs +++ b/executor/src/lib.rs @@ -26,7 +26,7 @@ export interface JsCallback { offchainGetStorage: (key: HexString) => Promise offchainTimestamp: () => Promise offchainRandomSeed: () => Promise - offchainSubmitTransaction: (tx: HexString) => Promise + offchainSubmitTransaction: (tx: HexString) => Promise } "#; diff --git a/package.json b/package.json index 9f625bc9..f3ea28af 100644 --- a/package.json +++ b/package.json @@ -6,15 +6,15 @@ "private": true, "workspaces": [ "packages/*", - "executor/pkg" + "executor" ], "scripts": { - "lint": "tsc --noEmit --project tsconfig.json && eslint . --ext .js,.ts && prettier --check .", + "lint": "tsc --noEmit --project tsconfig.lint.json && eslint . --ext .js,.ts && prettier --check .", "fix": "eslint . --ext .js,.ts --fix && prettier -w .", "prepare": "husky install", "clean": "yarn workspaces foreach -pvit run clean", "build": "yarn workspaces foreach -pvit run build", - "build-wasm": "wasm-pack build executor --target nodejs --scope acala-network && echo '' >> executor/pkg/package.json", + "build-wasm": "yarn workspace @acala-network/chopsticks-executor build", "check": "cd executor && cargo check --locked", "test": "vitest run", "test:watch": "vitest", @@ -51,10 +51,5 @@ "vite-tsconfig-paths": "^4.2.0", "vitest": "^0.33.0", "wasm-pack": "^0.12.1" - }, - "exports": { - ".": "./lib/index.js", - "./*": "./lib/*.js", - "./package.json": "./package.json" } } diff --git a/packages/chopsticks/package.json b/packages/chopsticks/package.json index e461484d..78f90f7d 100644 --- a/packages/chopsticks/package.json +++ b/packages/chopsticks/package.json @@ -1,34 +1,30 @@ { "name": "@acala-network/chopsticks", - "version": "0.7.3", + "version": "0.8.0-0", "author": "Bryan Chen ", "license": "Apache-2.0", "bin": "./chopsticks.js", "scripts": { "clean": "rm -rf lib tsconfig.tsbuildinfo", "build": "tsc -p ./tsconfig.json", - "script:start": "cd ../..; ts-node --transpile-only packages/chopsticks/src/cli.ts", - "script:run": "cd ../..; LOG_LEVEL=trace ts-node-dev --transpile-only --inspect --notify=false packages/chopsticks/src/cli.ts -- --config=configs/dev.yml", - "dev:karura": "cd ../..; ts-node-dev --transpile-only --inspect --notify=false packages/chopsticks/src/cli.ts -- --config=configs/karura.yml", - "dev:acala": "cd ../..; ts-node-dev --transpile-only --inspect --notify=false packages/chopsticks/src/cli.ts -- --config=configs/acala.yml", - "dev:polkadot": "cd ../..; ts-node-dev --transpile-only --inspect --notify=false packages/chopsticks/src/cli.ts -- --config=configs/polkadot.yml", - "dev:moonriver": "cd ../..; ts-node-dev --transpile-only --inspect --notify=false packages/chopsticks/src/cli.ts -- --config=configs/moonriver.yml", - "dev:moonbeam": "cd ../..; ts-node-dev --transpile-only --inspect --notify=false packages/chopsticks/src/cli.ts -- --config=configs/moonbeam.yml" + "script:start": "cd ../..; ts-node --transpile-only -r tsconfig-paths/register packages/chopsticks/src/cli.ts", + "script:run": "cd ../..; LOG_LEVEL=trace ts-node-dev --transpile-only -r tsconfig-paths/register --inspect --notify=false packages/chopsticks/src/cli.ts -- --config=configs/dev.yml", + "dev:karura": "cd ../..; ts-node-dev --transpile-only --inspect -r tsconfig-paths/register --notify=false packages/chopsticks/src/cli.ts -- --config=configs/karura.yml", + "dev:acala": "cd ../..; ts-node-dev --transpile-only --inspect -r tsconfig-paths/register --notify=false packages/chopsticks/src/cli.ts -- --config=configs/acala.yml", + "dev:polkadot": "cd ../..; ts-node-dev --transpile-only --inspect -r tsconfig-paths/register --notify=false packages/chopsticks/src/cli.ts -- --config=configs/polkadot.yml", + "dev:moonriver": "cd ../..; ts-node-dev --transpile-only --inspect -r tsconfig-paths/register --notify=false packages/chopsticks/src/cli.ts -- --config=configs/moonriver.yml", + "dev:moonbeam": "cd ../..; ts-node-dev --transpile-only --inspect -r tsconfig-paths/register --notify=false packages/chopsticks/src/cli.ts -- --config=configs/moonbeam.yml" }, "dependencies": { - "@acala-network/chopsticks-executor": "workspace:*", + "@acala-network/chopsticks-core": "workspace:*", "@pnpm/npm-conf": "^2.2.2", "@polkadot/api": "^10.9.1", "axios": "^1.4.0", + "dotenv": "^16.3.1", "global-agent": "^3.0.0", "js-yaml": "^4.1.0", "jsondiffpatch": "^0.4.1", "lodash": "^4.17.21", - "pino": "^8.14.2", - "pino-pretty": "^10.2.0", - "reflect-metadata": "^0.1.13", - "sqlite3": "^5.1.6", - "typeorm": "^0.3.17", "ws": "^8.13.0", "yargs": "^17.7.2", "zod": "^3.21.4" @@ -61,5 +57,6 @@ "default": "./lib/*.js" }, "./package.json": "./package.json" - } + }, + "stableVersion": "0.7.3" } diff --git a/packages/chopsticks/src/cli.ts b/packages/chopsticks/src/cli.ts index 017c354c..50d18ab1 100644 --- a/packages/chopsticks/src/cli.ts +++ b/packages/chopsticks/src/cli.ts @@ -3,10 +3,11 @@ import { hideBin } from 'yargs/helpers' import _ from 'lodash' import yargs from 'yargs' -import { Blockchain, BuildBlockMode, connectParachains, connectVertical, setupWithServer } from '.' +import { Blockchain, BuildBlockMode, connectParachains, connectVertical } from '@acala-network/chopsticks-core' import { Config, fetchConfig } from './schema' import { defaultOptions, mockOptions } from './cli-options' import { pluginExtendCli } from './plugins' +import { setupWithServer } from '.' dotenvConfig() diff --git a/packages/chopsticks/src/context.ts b/packages/chopsticks/src/context.ts new file mode 100644 index 00000000..6bedd962 --- /dev/null +++ b/packages/chopsticks/src/context.ts @@ -0,0 +1,38 @@ +import './utils/tunnel' +import { Config } from './schema' +import { HexString } from '@polkadot/util/types' +import { overrideStorage, overrideWasm } from './utils/override' +import { setup, timeTravel } from '@acala-network/chopsticks-core' + +export const setupContext = async (argv: Config, overrideParent = false) => { + const chain = await setup({ + endpoint: argv.endpoint, + block: argv.block, + genesis: argv.genesis, + buildBlockMode: argv['build-block-mode'], + db: argv.db, + mockSignatureHost: argv['mock-signature-host'], + allowUnresolvedImports: argv['allow-unresolved-imports'], + runtimeLogLevel: argv['runtime-log-level'], + registeredTypes: argv['registered-types'], + offchainWorker: argv['offchain-worker'], + maxMemoryBlockCount: argv['max-memory-block-count'], + }) + + if (argv.timestamp) await timeTravel(chain, argv.timestamp) + + let at: HexString | undefined + if (overrideParent) { + // in case of run block we need to apply wasm-override and import-storage to parent block + const block = await chain.head.parentBlock + if (!block) throw new Error('Cannot find parent block') + at = block.hash + } + + // override wasm before importing storage, in case new pallets have been + // added that have storage imports + await overrideStorage(chain, argv['import-storage'], at) + await overrideWasm(chain, argv['wasm-override'], at) + + return { chain } +} diff --git a/packages/chopsticks/src/db/entities.ts b/packages/chopsticks/src/db/entities.ts deleted file mode 100644 index 89bc5c84..00000000 --- a/packages/chopsticks/src/db/entities.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Column, Entity, PrimaryColumn } from 'typeorm' -import type { Header } from '@polkadot/types/interfaces' -import type { HexString } from '@polkadot/util/types' - -@Entity() -export class KeyValuePair { - @PrimaryColumn() - blockHash!: string - - @PrimaryColumn() - key!: string - - @Column({ nullable: true }) - value!: string -} - -@Entity() -export class Block { - @PrimaryColumn({ type: 'varchar' }) - hash!: HexString - - @Column() - number!: number - - @Column({ type: 'simple-json', nullable: true }) - header!: Header - - @Column({ type: 'varchar', nullable: true }) - parentHash!: HexString - - @Column('simple-array', { nullable: true }) - extrinsics!: HexString[] - - @Column({ type: 'simple-json', nullable: true }) - storageDiff!: Record -} diff --git a/packages/chopsticks/src/index.ts b/packages/chopsticks/src/index.ts index f3fccdb7..255e401f 100644 --- a/packages/chopsticks/src/index.ts +++ b/packages/chopsticks/src/index.ts @@ -1,8 +1,3 @@ -export { Api } from './api' -export { Blockchain } from './blockchain' -export { BuildBlockMode } from './blockchain/txpool' -export { connectParachains, connectVertical } from './xcm' -export { setup } from './setup' +export * from '@acala-network/chopsticks-core' export { setupWithServer } from './setup-with-server' -export { Config, fetchConfig } from './schema' -export * from './blockchain/inherent' +export { fetchConfig } from './schema' diff --git a/packages/chopsticks/src/logger.ts b/packages/chopsticks/src/logger.ts index 99ba8dc2..16046098 100644 --- a/packages/chopsticks/src/logger.ts +++ b/packages/chopsticks/src/logger.ts @@ -1,40 +1 @@ -import createLogger from 'pino' - -export const defaultLogger = createLogger({ - level: process.env.LOG_LEVEL || 'info', - transport: { - target: 'pino-pretty', - }, -}) - -const innerTruncate = - (level = 0) => - (val: any) => { - const verboseLog = !!process.env.VERBOSE_LOG - const levelLimit = verboseLog ? 10 : 5 - if (val == null) { - return val - } - if (level > levelLimit) { - return '( Too Deep )' - } - switch (typeof val) { - case 'string': - if (val.length > 66 && !verboseLog) { - return val.slice(0, 34) + '…' + val.slice(-32) - } else { - return val - } - case 'object': - if (Array.isArray(val)) { - return val.map(innerTruncate(level + 1)) - } - return Object.fromEntries( - Object.entries(val.toJSON ? val.toJSON() : val).map(([k, v]) => [k, innerTruncate(level + 1)(v)]), - ) - default: - return val - } - } - -export const truncate = (val: any) => innerTruncate(0)(val) +export { defaultLogger, truncate } from '@acala-network/chopsticks-core' diff --git a/packages/chopsticks/src/plugins/decode-key/index.ts b/packages/chopsticks/src/plugins/decode-key/index.ts index b417e014..bf399cbf 100644 --- a/packages/chopsticks/src/plugins/decode-key/index.ts +++ b/packages/chopsticks/src/plugins/decode-key/index.ts @@ -1,8 +1,8 @@ -import { Config } from '../..' +import { Config } from '../../schema' import { HexString } from '@polkadot/util/types' import { decodeKey } from '../../utils/decoder' import { defaultOptions } from '../../cli-options' -import { setup } from '../../setup' +import { setupContext } from '../../context' import type yargs from 'yargs' export const cli = (y: yargs.Argv) => { @@ -19,7 +19,7 @@ export const cli = (y: yargs.Argv) => { ...defaultOptions, }), async (argv) => { - const context = await setup(argv as Config) + const context = await setupContext(argv as Config) const { storage, decodedKey } = decodeKey( await context.chain.head.meta, context.chain.head, diff --git a/packages/chopsticks/src/plugins/dry-run/cli.ts b/packages/chopsticks/src/plugins/dry-run/cli.ts index ae76b60d..7c21b3d5 100644 --- a/packages/chopsticks/src/plugins/dry-run/cli.ts +++ b/packages/chopsticks/src/plugins/dry-run/cli.ts @@ -1,5 +1,5 @@ -import { Config } from '../..' -import { defaultOptions } from '../../cli-options' +import { Config } from '../../schema' +import { defaultOptions, mockOptions } from '../../cli-options' import { dryRunExtrinsic } from './dry-run-extrinsic' import { dryRunPreimage } from './dry-run-preimage' import type yargs from 'yargs' @@ -11,6 +11,7 @@ export const cli = (y: yargs.Argv) => { (yargs) => yargs.options({ ...defaultOptions, + ...mockOptions, extrinsic: { desc: 'Extrinsic or call to dry run. If you pass call here then address is required to fake signature', string: true, diff --git a/packages/chopsticks/src/plugins/dry-run/dry-run-extrinsic.ts b/packages/chopsticks/src/plugins/dry-run/dry-run-extrinsic.ts index c31dfb9f..0e36b75c 100644 --- a/packages/chopsticks/src/plugins/dry-run/dry-run-extrinsic.ts +++ b/packages/chopsticks/src/plugins/dry-run/dry-run-extrinsic.ts @@ -5,10 +5,10 @@ import { Config } from '../../schema' import { defaultLogger } from '../../logger' import { generateHtmlDiffPreviewFile } from '../../utils/generate-html-diff' import { openHtml } from '../../utils/open-html' -import { setup } from '../../setup' +import { setupContext } from '../../context' export const dryRunExtrinsic = async (argv: Config) => { - const context = await setup(argv) + const context = await setupContext(argv) const input = argv['address'] ? { call: argv['extrinsic'], address: argv['address'] } : argv['extrinsic'] const { outcome, storageDiff } = await context.chain.dryRunExtrinsic(input, argv['at']) diff --git a/packages/chopsticks/src/plugins/dry-run/dry-run-preimage.ts b/packages/chopsticks/src/plugins/dry-run/dry-run-preimage.ts index a00be2bd..d0b2d469 100644 --- a/packages/chopsticks/src/plugins/dry-run/dry-run-preimage.ts +++ b/packages/chopsticks/src/plugins/dry-run/dry-run-preimage.ts @@ -5,14 +5,12 @@ import { hexToU8a } from '@polkadot/util' import { Config } from '../../schema' import { defaultLogger } from '../../logger' import { generateHtmlDiffPreviewFile } from '../../utils/generate-html-diff' -import { newHeader } from '../../blockchain/block-builder' +import { newHeader, runTask, setStorage, taskHandler } from '@acala-network/chopsticks-core' import { openHtml } from '../../utils/open-html' -import { runTask, taskHandler } from '../../executor' -import { setStorage } from '../../utils/set-storage' -import { setup } from '../../setup' +import { setupContext } from '../../context' export const dryRunPreimage = async (argv: Config) => { - const context = await setup(argv) + const context = await setupContext(argv) const extrinsic = argv['preimage'] diff --git a/packages/chopsticks/src/plugins/run-block/index.ts b/packages/chopsticks/src/plugins/run-block/index.ts index 9951ba66..98c96d6a 100644 --- a/packages/chopsticks/src/plugins/run-block/index.ts +++ b/packages/chopsticks/src/plugins/run-block/index.ts @@ -8,8 +8,8 @@ import { Config } from '../../schema' import { defaultLogger } from '../../logger' import { generateHtmlDiffPreviewFile } from '../../utils/generate-html-diff' import { openHtml } from '../../utils/open-html' -import { runTask, taskHandler } from '../../executor' -import { setup } from '../../setup' +import { runTask, taskHandler } from '@acala-network/chopsticks-core' +import { setupContext } from '../../context' export const cli = (y: yargs.Argv) => { y.command( @@ -31,7 +31,7 @@ export const cli = (y: yargs.Argv) => { }, }), async (argv) => { - const context = await setup(argv as Config, true) + const context = await setupContext(argv as Config, true) const header = await context.chain.head.header const block = context.chain.head diff --git a/packages/chopsticks/src/plugins/set-block-build-mode/index.ts b/packages/chopsticks/src/plugins/set-block-build-mode/index.ts index 03716b02..e469ce3e 100644 --- a/packages/chopsticks/src/plugins/set-block-build-mode/index.ts +++ b/packages/chopsticks/src/plugins/set-block-build-mode/index.ts @@ -1,4 +1,4 @@ -import { BuildBlockMode } from '../../blockchain/txpool' +import { BuildBlockMode } from '@acala-network/chopsticks-core' import { Handler, ResponseError } from '../../rpc/shared' import { defaultLogger } from '../../logger' diff --git a/packages/chopsticks/src/plugins/set-head/index.ts b/packages/chopsticks/src/plugins/set-head/index.ts index eed9ba20..387b2749 100644 --- a/packages/chopsticks/src/plugins/set-head/index.ts +++ b/packages/chopsticks/src/plugins/set-head/index.ts @@ -1,4 +1,4 @@ -import { Block } from '../../blockchain/block' +import { Block } from '@acala-network/chopsticks-core' import { Handler, ResponseError } from '../../rpc/shared' export const rpc: Handler = async (context, [hashOrNumber]) => { diff --git a/packages/chopsticks/src/plugins/set-storage/index.ts b/packages/chopsticks/src/plugins/set-storage/index.ts index 9387e83a..d8ed4355 100644 --- a/packages/chopsticks/src/plugins/set-storage/index.ts +++ b/packages/chopsticks/src/plugins/set-storage/index.ts @@ -1,7 +1,7 @@ import { HexString } from '@polkadot/util/types' import { Handler, ResponseError } from '../../rpc/shared' -import { StorageValues, setStorage } from '../../utils/set-storage' +import { StorageValues, setStorage } from '@acala-network/chopsticks-core' import { defaultLogger } from '../../logger' export const rpc: Handler = async (context, params) => { diff --git a/packages/chopsticks/src/plugins/time-travel/index.ts b/packages/chopsticks/src/plugins/time-travel/index.ts index 7610f613..768bbb3d 100644 --- a/packages/chopsticks/src/plugins/time-travel/index.ts +++ b/packages/chopsticks/src/plugins/time-travel/index.ts @@ -1,5 +1,5 @@ import { Handler, ResponseError } from '../../rpc/shared' -import { timeTravel } from '../../utils/time-travel' +import { timeTravel } from '@acala-network/chopsticks-core' export const rpc: Handler = async (context, [date]) => { const timestamp = typeof date === 'string' ? Date.parse(date) : date diff --git a/packages/chopsticks/src/plugins/try-runtime/index.ts b/packages/chopsticks/src/plugins/try-runtime/index.ts index 58994174..f87b0310 100644 --- a/packages/chopsticks/src/plugins/try-runtime/index.ts +++ b/packages/chopsticks/src/plugins/try-runtime/index.ts @@ -1,11 +1,11 @@ import { writeFileSync } from 'node:fs' import type yargs from 'yargs' -import { Config } from '../..' +import { Config } from '../../schema' import { defaultOptions } from '../../cli-options' import { generateHtmlDiffPreviewFile } from '../../utils/generate-html-diff' import { openHtml } from '../../utils/open-html' -import { setup } from '../../setup' +import { setupContext } from '../../context' export const cli = (y: yargs.Argv) => { y.command( @@ -33,7 +33,7 @@ export const cli = (y: yargs.Argv) => { }, }), async (argv) => { - const context = await setup(argv as Config) + const context = await setupContext(argv as Config) const block = context.chain.head const registry = await block.registry registry.register({ diff --git a/packages/chopsticks/src/rpc/shared.ts b/packages/chopsticks/src/rpc/shared.ts index 1e6c71f7..bd7f95a1 100644 --- a/packages/chopsticks/src/rpc/shared.ts +++ b/packages/chopsticks/src/rpc/shared.ts @@ -1,4 +1,4 @@ -import { Blockchain } from '../blockchain' +import { Blockchain } from '@acala-network/chopsticks-core' import { defaultLogger } from '../logger' export const logger = defaultLogger.child({ name: 'rpc' }) diff --git a/packages/chopsticks/src/rpc/substrate/author.ts b/packages/chopsticks/src/rpc/substrate/author.ts index dbaae461..8e5f3b43 100644 --- a/packages/chopsticks/src/rpc/substrate/author.ts +++ b/packages/chopsticks/src/rpc/substrate/author.ts @@ -1,5 +1,4 @@ -import { APPLY_EXTRINSIC_ERROR } from '../../blockchain/txpool' -import { Block } from '../../blockchain/block' +import { APPLY_EXTRINSIC_ERROR, Block } from '@acala-network/chopsticks-core' import { Handlers, ResponseError } from '../shared' import { TransactionValidityError } from '@polkadot/types/interfaces' import { defaultLogger } from '../../logger' diff --git a/packages/chopsticks/src/rpc/substrate/state.ts b/packages/chopsticks/src/rpc/substrate/state.ts index 1d6826b1..d0eed165 100644 --- a/packages/chopsticks/src/rpc/substrate/state.ts +++ b/packages/chopsticks/src/rpc/substrate/state.ts @@ -1,4 +1,4 @@ -import { Block } from '../../blockchain/block' +import { Block } from '@acala-network/chopsticks-core' import { Handlers, ResponseError } from '../shared' import { defaultLogger } from '../../logger' diff --git a/packages/chopsticks/src/schema/index.ts b/packages/chopsticks/src/schema/index.ts index a7c8fddd..f2536df1 100644 --- a/packages/chopsticks/src/schema/index.ts +++ b/packages/chopsticks/src/schema/index.ts @@ -1,3 +1,4 @@ +import { BuildBlockMode, defaultLogger, genesisSchema, isUrl } from '@acala-network/chopsticks-core' import { basename, extname } from 'node:path' import { readFileSync } from 'node:fs' import { z } from 'zod' @@ -5,23 +6,6 @@ import _ from 'lodash' import axios from 'axios' import yaml from 'js-yaml' -import { BuildBlockMode } from '../blockchain/txpool' -import { isUrl } from '../utils' -import { logger } from '../rpc/shared' - -export const genesisSchema = z.object({ - id: z.string(), - name: z.string(), - properties: z.object({ - ss58Format: z.number().optional(), - tokenDecimals: z.union([z.number(), z.array(z.number())]).optional(), - tokenSymbol: z.union([z.string(), z.array(z.string())]).optional(), - }), - genesis: z.object({ raw: z.object({ top: z.record(z.string()) }) }), -}) - -export type Genesis = z.infer - export const configSchema = z .object({ port: z.number().optional(), @@ -58,7 +42,7 @@ export const fetchConfig = async (path: string): Promise => { path += '.yml' } const url = CONFIGS_BASE_URL + path - logger.info(`Loading config file ${url}`) + defaultLogger.info(`Loading config file ${url}`) file = await axios.get(url).then((x) => x.data) } else { throw err diff --git a/packages/chopsticks/src/setup-with-server.ts b/packages/chopsticks/src/setup-with-server.ts index 233726ab..2a2438f7 100644 --- a/packages/chopsticks/src/setup-with-server.ts +++ b/packages/chopsticks/src/setup-with-server.ts @@ -2,10 +2,11 @@ import { Config } from './schema' import { createServer } from './server' import { handler } from './rpc' import { logger } from './rpc/shared' -import { setup } from './setup' +import { setupContext } from './context' +import _ from 'lodash' export const setupWithServer = async (argv: Config) => { - const context = await setup(argv) + const context = await setupContext(argv) const port = argv.port ?? 8000 if (argv.genesis) { diff --git a/packages/chopsticks/src/setup.ts b/packages/chopsticks/src/setup.ts deleted file mode 100644 index 96477075..00000000 --- a/packages/chopsticks/src/setup.ts +++ /dev/null @@ -1,100 +0,0 @@ -import './utils/tunnel' - -import '@polkadot/types-codec' -import { DataSource } from 'typeorm' -import { HexString } from '@polkadot/util/types' -import { ProviderInterface } from '@polkadot/rpc-provider/types' -import { WsProvider } from '@polkadot/api' - -import { Api } from './api' -import { Blockchain } from './blockchain' -import { Config } from './schema' -import { GenesisProvider } from './genesis-provider' -import { - InherentProviders, - ParaInherentEnter, - SetBabeRandomness, - SetNimbusAuthorInherent, - SetTimestamp, - SetValidationData, -} from './blockchain/inherent' -import { defaultLogger } from './logger' -import { importStorage, overrideWasm } from './utils/import-storage' -import { openDb } from './db' -import { timeTravel } from './utils/time-travel' - -export const setup = async (argv: Config, runBlock = false) => { - let provider: ProviderInterface - if (argv.genesis) { - if (typeof argv.genesis === 'string') { - provider = await GenesisProvider.fromUrl(argv.genesis) - } else { - provider = new GenesisProvider(argv.genesis) - } - } else { - provider = new WsProvider(argv.endpoint) - } - const api = new Api(provider) - await api.isReady - - let blockHash: string - if (argv.block == null) { - blockHash = await api.getBlockHash() - } else if (typeof argv.block === 'string' && argv.block.startsWith('0x')) { - blockHash = argv.block as string - } else if (Number.isInteger(+argv.block)) { - blockHash = await api.getBlockHash(Number(argv.block)) - } else { - throw new Error(`Invalid block number or hash: ${argv.block}`) - } - - defaultLogger.debug({ ...argv, blockHash }, 'Args') - - let db: DataSource | undefined - if (argv.db) { - db = await openDb(argv.db) - } - - const header = await api.getHeader(blockHash) - - const inherents = new InherentProviders(new SetTimestamp(), [ - new SetValidationData(), - new ParaInherentEnter(), - new SetNimbusAuthorInherent(), - new SetBabeRandomness(), - ]) - - const chain = new Blockchain({ - api, - buildBlockMode: argv['build-block-mode'], - inherentProvider: inherents, - db, - header: { - hash: blockHash as HexString, - number: Number(header.number), - }, - mockSignatureHost: argv['mock-signature-host'], - allowUnresolvedImports: argv['allow-unresolved-imports'], - runtimeLogLevel: argv['runtime-log-level'], - registeredTypes: argv['registered-types'], - offchainWorker: argv['offchain-worker'], - maxMemoryBlockCount: argv['max-memory-block-count'], - }) - - if (argv.timestamp) await timeTravel(chain, argv.timestamp) - - let at: HexString | undefined - if (runBlock) { - // in case of run block we need to apply wasm-override and import-storage to parent block - const block = await chain.head.parentBlock - if (!block) throw new Error('Cannot find parent block') - at = block.hash - } - - // override wasm before importing storage, in case new pallets have been - // added that have storage imports - await overrideWasm(chain, argv['wasm-override'], at) - await importStorage(chain, argv['import-storage'], at) - - return { chain, api, ws: provider } -} diff --git a/packages/chopsticks/src/utils/decoder.ts b/packages/chopsticks/src/utils/decoder.ts index ae6c7ee7..c71a5fec 100644 --- a/packages/chopsticks/src/utils/decoder.ts +++ b/packages/chopsticks/src/utils/decoder.ts @@ -1,5 +1,5 @@ import '@polkadot/types-codec' -import { Block } from '../blockchain/block' +import { Block } from '@acala-network/chopsticks-core' import { DecoratedMeta } from '@polkadot/types/metadata/decorate/types' import { HexString } from '@polkadot/util/types' import { StorageEntry } from '@polkadot/types/primitive/types' diff --git a/packages/chopsticks/src/utils/generate-html-diff.ts b/packages/chopsticks/src/utils/generate-html-diff.ts index 051d887e..839032a7 100644 --- a/packages/chopsticks/src/utils/generate-html-diff.ts +++ b/packages/chopsticks/src/utils/generate-html-diff.ts @@ -1,4 +1,4 @@ -import { Block } from '../blockchain/block' +import { Block } from '@acala-network/chopsticks-core' import { HexString } from '@polkadot/util/types' import { decodeStorageDiff } from './decoder' import { mkdirSync, readFileSync, writeFileSync } from 'node:fs' diff --git a/packages/chopsticks/src/utils/import-storage.ts b/packages/chopsticks/src/utils/override.ts similarity index 80% rename from packages/chopsticks/src/utils/import-storage.ts rename to packages/chopsticks/src/utils/override.ts index 5a4584fe..3e06be06 100644 --- a/packages/chopsticks/src/utils/import-storage.ts +++ b/packages/chopsticks/src/utils/override.ts @@ -1,12 +1,11 @@ +import { Blockchain, StorageValues, setStorage } from '@acala-network/chopsticks-core' import { HexString } from '@polkadot/util/types' import { existsSync, readFileSync } from 'node:fs' import yaml from 'js-yaml' -import { Blockchain } from '../blockchain' -import { StorageValues, setStorage } from './set-storage' import { defaultLogger } from '../logger' -export const importStorage = async (chain: Blockchain, storage?: string | StorageValues, at?: HexString) => { +export const overrideStorage = async (chain: Blockchain, storage?: string | StorageValues, at?: HexString) => { if (storage == null) { return } @@ -18,7 +17,7 @@ export const importStorage = async (chain: Blockchain, storage?: string | Storag storageValue = storage } const blockHash = await setStorage(chain, storageValue, at) - defaultLogger.trace({ blockHash, storage }, 'ImportStorage') + defaultLogger.trace({ blockHash, storage }, 'OverrideStorage') } export const overrideWasm = async (chain: Blockchain, wasmPath?: string, at?: HexString) => { diff --git a/packages/chopsticks/tsconfig.json b/packages/chopsticks/tsconfig.json index 6d2b3da9..18d3c939 100644 --- a/packages/chopsticks/tsconfig.json +++ b/packages/chopsticks/tsconfig.json @@ -5,5 +5,8 @@ "rootDir": "src" }, "include": ["src/**/*"], - "exclude": ["src/**/*.test.ts"] + "exclude": ["src/**/*.test.ts"], + "references": [ + { "path": "../core" }, + ] } diff --git a/packages/core/package.json b/packages/core/package.json index 182f8c6d..18940d78 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,18 +1,46 @@ { "name": "@acala-network/chopsticks-core", - "version": "0.7.3", - "main": "./lib/index.js", - "types": "./lib/index.d.ts", + "version": "0.8.0-0", "author": "Bryan Chen ", "license": "Apache-2.0", "scripts": { "clean": "rm -rf lib tsconfig.tsbuildinfo", "build": "tsc -p ./tsconfig.json" }, + "dependencies": { + "@acala-network/chopsticks-executor": "workspace:*", + "@polkadot/api": "^10.9.1", + "axios": "^1.4.0", + "eventemitter3": "^5.0.1", + "localforage": "^1.10.0", + "lodash": "^4.17.21", + "pino": "^8.14.1", + "pino-pretty": "^10.0.1", + "sql.js": "^1.8.0", + "sqlite3": "^5.1.6", + "typeorm": "^0.3.17", + "zod": "^3.21.4" + }, "devDependencies": { + "@types/lodash": "^4.14.195", + "@types/sql.js": "^1", "typescript": "^5.1.6" }, "files": [ "lib" - ] + ], + "main": "./lib/index.js", + "types": "./lib/index.d.ts", + "exports": { + ".": { + "types": "./lib/index.d.ts", + "default": "./lib/index.js" + }, + "./*": { + "types": "./lib/*.d.ts", + "default": "./lib/*.js" + }, + "./package.json": "./package.json" + }, + "stableVersion": "0.7.3" } diff --git a/packages/chopsticks/src/__snapshots__/executor.test.ts.snap b/packages/core/src/__snapshots__/executor.test.ts.snap similarity index 100% rename from packages/chopsticks/src/__snapshots__/executor.test.ts.snap rename to packages/core/src/__snapshots__/executor.test.ts.snap diff --git a/packages/chopsticks/src/api.ts b/packages/core/src/api.ts similarity index 100% rename from packages/chopsticks/src/api.ts rename to packages/core/src/api.ts diff --git a/packages/chopsticks/src/blockchain/block-builder.ts b/packages/core/src/blockchain/block-builder.ts similarity index 100% rename from packages/chopsticks/src/blockchain/block-builder.ts rename to packages/core/src/blockchain/block-builder.ts diff --git a/packages/chopsticks/src/blockchain/block.ts b/packages/core/src/blockchain/block.ts similarity index 100% rename from packages/chopsticks/src/blockchain/block.ts rename to packages/core/src/blockchain/block.ts diff --git a/packages/chopsticks/src/blockchain/head-state.ts b/packages/core/src/blockchain/head-state.ts similarity index 100% rename from packages/chopsticks/src/blockchain/head-state.ts rename to packages/core/src/blockchain/head-state.ts diff --git a/packages/chopsticks/src/blockchain/index.ts b/packages/core/src/blockchain/index.ts similarity index 99% rename from packages/chopsticks/src/blockchain/index.ts rename to packages/core/src/blockchain/index.ts index 478c1770..46ed8a19 100644 --- a/packages/chopsticks/src/blockchain/index.ts +++ b/packages/core/src/blockchain/index.ts @@ -8,7 +8,7 @@ import type { TransactionValidity } from '@polkadot/types/interfaces/txqueue' import { Api } from '../api' import { Block } from './block' -import { Block as BlockEntity } from '../db/entities' +import { BlockEntity } from '../db/entities' import { BuildBlockMode, BuildBlockParams, DownwardMessage, HorizontalMessage, TxPool } from './txpool' import { HeadState } from './head-state' import { InherentProvider } from './inherent' @@ -119,7 +119,7 @@ export class Blockchain { { hash, number, - header, + header: await header, extrinsics: await extrinsics, parentHash: (await block.parentBlock)?.hash, storageDiff: await block.storageDiff(), diff --git a/packages/chopsticks/src/blockchain/inherent/index.ts b/packages/core/src/blockchain/inherent/index.ts similarity index 100% rename from packages/chopsticks/src/blockchain/inherent/index.ts rename to packages/core/src/blockchain/inherent/index.ts diff --git a/packages/chopsticks/src/blockchain/inherent/para-enter.ts b/packages/core/src/blockchain/inherent/para-enter.ts similarity index 100% rename from packages/chopsticks/src/blockchain/inherent/para-enter.ts rename to packages/core/src/blockchain/inherent/para-enter.ts diff --git a/packages/chopsticks/src/blockchain/inherent/parachain/babe-randomness.ts b/packages/core/src/blockchain/inherent/parachain/babe-randomness.ts similarity index 100% rename from packages/chopsticks/src/blockchain/inherent/parachain/babe-randomness.ts rename to packages/core/src/blockchain/inherent/parachain/babe-randomness.ts diff --git a/packages/chopsticks/src/blockchain/inherent/parachain/nimbus-author-inherent.ts b/packages/core/src/blockchain/inherent/parachain/nimbus-author-inherent.ts similarity index 100% rename from packages/chopsticks/src/blockchain/inherent/parachain/nimbus-author-inherent.ts rename to packages/core/src/blockchain/inherent/parachain/nimbus-author-inherent.ts diff --git a/packages/chopsticks/src/blockchain/inherent/parachain/validation-data.ts b/packages/core/src/blockchain/inherent/parachain/validation-data.ts similarity index 100% rename from packages/chopsticks/src/blockchain/inherent/parachain/validation-data.ts rename to packages/core/src/blockchain/inherent/parachain/validation-data.ts diff --git a/packages/chopsticks/src/blockchain/storage-layer.ts b/packages/core/src/blockchain/storage-layer.ts similarity index 95% rename from packages/chopsticks/src/blockchain/storage-layer.ts rename to packages/core/src/blockchain/storage-layer.ts index dc400515..841e18b5 100644 --- a/packages/chopsticks/src/blockchain/storage-layer.ts +++ b/packages/core/src/blockchain/storage-layer.ts @@ -2,6 +2,7 @@ import { DataSource } from 'typeorm' import _ from 'lodash' import { Api } from '../api' +import { KeyValuePair } from '../db/entities' import { defaultLogger } from '../logger' import KeyCache from '../utils/key-cache' @@ -37,15 +38,16 @@ export class RemoteStorageLayer implements StorageLayerProvider { } async get(key: string): Promise { + const keyValuePair = this.#db?.getRepository(KeyValuePair) if (this.#db) { - const res = await this.#db.getRepository('KeyValuePair').findOne({ where: { key, blockHash: this.#at } }) + const res = await keyValuePair?.findOne({ where: { key, blockHash: this.#at } }) if (res) { return res.value } } logger.trace({ at: this.#at, key }, 'RemoteStorageLayer get') const data = await this.#api.getStorage(key, this.#at) - this.#db?.getRepository('KeyValuePair').upsert({ key, blockHash: this.#at, value: data }, ['key', 'blockHash']) + keyValuePair?.upsert({ key, blockHash: this.#at, value: data }, ['key', 'blockHash']) return data } diff --git a/packages/chopsticks/src/blockchain/txpool.ts b/packages/core/src/blockchain/txpool.ts similarity index 99% rename from packages/chopsticks/src/blockchain/txpool.ts rename to packages/core/src/blockchain/txpool.ts index 9d2051d4..d0bb3924 100644 --- a/packages/chopsticks/src/blockchain/txpool.ts +++ b/packages/core/src/blockchain/txpool.ts @@ -1,4 +1,4 @@ -import { EventEmitter } from 'node:stream' +import { EventEmitter } from 'eventemitter3' import { GenericExtrinsic } from '@polkadot/types' import { HexString } from '@polkadot/util/types' import _ from 'lodash' diff --git a/packages/core/src/db/browser.ts b/packages/core/src/db/browser.ts new file mode 100644 index 00000000..9565a1ee --- /dev/null +++ b/packages/core/src/db/browser.ts @@ -0,0 +1,29 @@ +import { DataSource } from 'typeorm' +import { createInstance } from 'localforage' +import initSqlJs from 'sql.js' + +globalThis.localforage = createInstance({ name: 'chopsticks' }) + +import * as entities from './entities' + +export const openDb = async (dbPath: string): Promise => { + const wasmUrl = new URL('../../../../node_modules/sql.js/dist/sql-wasm.wasm', import.meta.url) + const wasmBinary = await fetch(wasmUrl).then((response) => response.arrayBuffer()) + const source = new DataSource({ + type: 'sqljs', + location: dbPath, + entities: Object.values(entities), + synchronize: true, + autoSave: true, + logging: false, + useLocalForage: true, + driver: initSqlJs, + sqlJsConfig: { + wasmBinary, + }, + }) + + await source.initialize() + + return source +} diff --git a/packages/core/src/db/entities.ts b/packages/core/src/db/entities.ts new file mode 100644 index 00000000..1ecced6e --- /dev/null +++ b/packages/core/src/db/entities.ts @@ -0,0 +1,65 @@ +import { EntitySchema } from 'typeorm' +import { Header } from '@polkadot/types/interfaces' +import { HexString } from '@polkadot/util/types' + +export const KeyValuePair = new EntitySchema<{ + blockHash: string + key: string + value?: string +}>({ + name: 'KeyValuePair', + columns: { + blockHash: { + primary: true, + type: 'varchar', + nullable: false, + }, + key: { + primary: true, + type: 'varchar', + nullable: false, + }, + value: { + type: 'text', + nullable: true, + }, + }, +}) + +export const BlockEntity = new EntitySchema<{ + hash: HexString + number: number + header: Header + parentHash?: HexString + extrinsics: HexString[] + storageDiff?: Record +}>({ + name: 'Block', + columns: { + hash: { + primary: true, + type: 'varchar', + nullable: false, + }, + number: { + type: 'int', + nullable: false, + }, + header: { + type: 'simple-json', + nullable: false, + }, + parentHash: { + type: 'varchar', + nullable: true, + }, + extrinsics: { + type: 'simple-array', + nullable: false, + }, + storageDiff: { + type: 'simple-json', + nullable: true, + }, + }, +}) diff --git a/packages/core/src/db/index.ts b/packages/core/src/db/index.ts new file mode 100644 index 00000000..320b4665 --- /dev/null +++ b/packages/core/src/db/index.ts @@ -0,0 +1,7 @@ +export const openDb = async (dbPath: string) => { + if (typeof window === 'undefined') { + return (await import('./node')).openDb(dbPath) + } else { + return (await import('./browser')).openDb(dbPath) + } +} diff --git a/packages/chopsticks/src/db/index.ts b/packages/core/src/db/node.ts similarity index 93% rename from packages/chopsticks/src/db/index.ts rename to packages/core/src/db/node.ts index 044d44c9..7b9c764f 100644 --- a/packages/chopsticks/src/db/index.ts +++ b/packages/core/src/db/node.ts @@ -1,4 +1,3 @@ -import 'reflect-metadata' import { DataSource } from 'typeorm' import * as entities from './entities' diff --git a/packages/chopsticks/src/executor.test.ts b/packages/core/src/executor.test.ts similarity index 100% rename from packages/chopsticks/src/executor.test.ts rename to packages/core/src/executor.test.ts diff --git a/packages/chopsticks/src/executor.ts b/packages/core/src/executor.ts similarity index 94% rename from packages/chopsticks/src/executor.ts rename to packages/core/src/executor.ts index 18782862..0e3be2a9 100644 --- a/packages/chopsticks/src/executor.ts +++ b/packages/core/src/executor.ts @@ -3,18 +3,20 @@ import { hexToString, hexToU8a } from '@polkadot/util' import { randomAsHex } from '@polkadot/util-crypto' import { Block } from './blockchain/block' -import { - JsCallback, +import { PREFIX_LENGTH } from './utils/key-cache' +import { Registry } from '@polkadot/types-codec/types' +import { defaultLogger, truncate } from './logger' +import _ from 'lodash' +import wasmSetup, { calculate_state_root, create_proof, decode_proof, get_runtime_version, run_task, } from '@acala-network/chopsticks-executor' -import { PREFIX_LENGTH } from './utils/key-cache' -import { Registry } from '@polkadot/types-codec/types' -import { defaultLogger, truncate } from './logger' -import _ from 'lodash' +import type { JsCallback } from '@acala-network/chopsticks-executor' + +export { JsCallback } export type RuntimeVersion = { specName: string @@ -29,6 +31,11 @@ export type RuntimeVersion = { const logger = defaultLogger.child({ name: 'executor' }) +// init wasm on browser +if (typeof wasmSetup === 'function') { + wasmSetup() +} + export const getRuntimeVersion = async (code: HexString): Promise => { return get_runtime_version(code).then((version) => { version.specName = hexToString(version.specName) @@ -72,7 +79,7 @@ export const runTask = async ( callback: JsCallback = emptyTaskHandler, ) => { logger.trace(truncate(task), 'taskRun') - const response = await run_task(task, callback, process.env.RUST_LOG) + const response = await run_task(task, callback, typeof process === 'object' ? process.env.RUST_LOG : 'info') if (response.Call) { logger.trace(truncate(response.Call), 'taskResponse') } else { diff --git a/packages/chopsticks/src/genesis-provider.ts b/packages/core/src/genesis-provider.ts similarity index 89% rename from packages/chopsticks/src/genesis-provider.ts rename to packages/core/src/genesis-provider.ts index e788e3b5..2541a6ec 100644 --- a/packages/chopsticks/src/genesis-provider.ts +++ b/packages/core/src/genesis-provider.ts @@ -1,6 +1,5 @@ -import { EventEmitter } from 'node:events' +import { EventEmitter } from 'eventemitter3' import { HexString } from '@polkadot/util/types' -import { JsCallback } from '@acala-network/chopsticks-executor' import { ProviderInterface, ProviderInterfaceCallback, @@ -8,12 +7,11 @@ import { ProviderInterfaceEmitted, ProviderStats, } from '@polkadot/rpc-provider/types' -import { lstatSync, readFileSync } from 'node:fs' import { stringToHex } from '@polkadot/util' import axios from 'axios' import { Genesis, genesisSchema } from './schema' -import { calculateStateRoot, emptyTaskHandler, runTask } from './executor' +import { JsCallback, calculateStateRoot, emptyTaskHandler, runTask } from './executor' import { isUrl } from './utils' export class GenesisProvider implements ProviderInterface { @@ -51,15 +49,19 @@ export class GenesisProvider implements ProviderInterface { } static fromUrl = async (url: string) => { - let file: any - if (isUrl(url)) { - file = await axios.get(url).then((x) => x.data) - } else if (lstatSync(url).isFile()) { - file = JSON.parse(String(readFileSync(url))) - } else { + const getFile = async (url: string) => { + if (isUrl(url)) { + return axios.get(url).then((x) => x.data) + } else if (typeof process === 'object') { + const { lstatSync, readFileSync } = await import('node:fs') + if (lstatSync(url).isFile()) { + return JSON.parse(String(readFileSync(url))) + } + } throw Error(`invalid genesis path or url ${url}`) } - return new GenesisProvider(genesisSchema.parse(file)) + + return new GenesisProvider(genesisSchema.parse(await getFile(url))) } get isClonable(): boolean { diff --git a/packages/core/src/index.test.ts b/packages/core/src/index.test.ts deleted file mode 100644 index 72245a25..00000000 --- a/packages/core/src/index.test.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { describe, expect, it } from 'vitest' -import core from './index' - -describe('@acala-network/chopsticks-core', () => { - it('@acala-network/chopsticks-core', () => { - expect(core).toBe('@acala-network/chopsticks-core') - }) -}) diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 28aae1cc..14f3b3d5 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1 +1,13 @@ -export default '@acala-network/chopsticks-core' +export * from './api' +export * from './blockchain' +export * from './blockchain/block' +export * from './blockchain/block-builder' +export * from './blockchain/txpool' +export * from './blockchain/storage-layer' +export * from './utils' +export * from './executor' +export * from './schema' +export * from './xcm' +export * from './setup' +export * from './blockchain/inherent' +export * from './logger' diff --git a/packages/core/src/logger.ts b/packages/core/src/logger.ts new file mode 100644 index 00000000..b531e4f6 --- /dev/null +++ b/packages/core/src/logger.ts @@ -0,0 +1,40 @@ +import createLogger from 'pino' + +export const defaultLogger = createLogger({ + level: (typeof process === 'object' && process.env.LOG_LEVEL) || 'info', + transport: { + target: 'pino-pretty', + }, +}) + +const innerTruncate = + (level = 0) => + (val: any) => { + const verboseLog = typeof process === 'object' ? !!process.env.VERBOSE_LOG : false + const levelLimit = verboseLog ? 10 : 5 + if (val == null) { + return val + } + if (level > levelLimit) { + return '( Too Deep )' + } + switch (typeof val) { + case 'string': + if (val.length > 66 && !verboseLog) { + return val.slice(0, 34) + '…' + val.slice(-32) + } else { + return val + } + case 'object': + if (Array.isArray(val)) { + return val.map(innerTruncate(level + 1)) + } + return Object.fromEntries( + Object.entries(val.toJSON ? val.toJSON() : val).map(([k, v]) => [k, innerTruncate(level + 1)(v)]), + ) + default: + return val + } + } + +export const truncate = (val: any) => innerTruncate(0)(val) diff --git a/packages/chopsticks/src/offchain.ts b/packages/core/src/offchain.ts similarity index 93% rename from packages/chopsticks/src/offchain.ts rename to packages/core/src/offchain.ts index 95269a2d..65af3c2f 100644 --- a/packages/chopsticks/src/offchain.ts +++ b/packages/core/src/offchain.ts @@ -1,9 +1,11 @@ import { Block } from './blockchain/block' import { HexString } from '@polkadot/util/types' import { blake2AsHex } from '@polkadot/util-crypto' -import { logger } from './rpc/shared' +import { defaultLogger } from './logger' import { queueScheduler } from 'rxjs' +const logger = defaultLogger.child({ name: 'offchain' }) + export class OffchainWorker { readonly pendingExtrinsics: HexString[] = [] readonly offchainStorage: Map = new Map() diff --git a/packages/core/src/schema/index.ts b/packages/core/src/schema/index.ts new file mode 100644 index 00000000..61a61df5 --- /dev/null +++ b/packages/core/src/schema/index.ts @@ -0,0 +1,15 @@ +import { z } from 'zod' +import _ from 'lodash' + +export const genesisSchema = z.object({ + id: z.string(), + name: z.string(), + properties: z.object({ + ss58Format: z.number().optional(), + tokenDecimals: z.union([z.number(), z.array(z.number())]).optional(), + tokenSymbol: z.union([z.string(), z.array(z.string())]).optional(), + }), + genesis: z.object({ raw: z.object({ top: z.record(z.string()) }) }), +}) + +export type Genesis = z.infer diff --git a/packages/core/src/setup.ts b/packages/core/src/setup.ts new file mode 100644 index 00000000..30008463 --- /dev/null +++ b/packages/core/src/setup.ts @@ -0,0 +1,95 @@ +import '@polkadot/types-codec' +import { DataSource } from 'typeorm' +import { HexString } from '@polkadot/util/types' +import { ProviderInterface } from '@polkadot/rpc-provider/types' +import { RegisteredTypes } from '@polkadot/types/types' +import { WsProvider } from '@polkadot/api' + +import { Api } from './api' +import { Blockchain } from './blockchain' +import { BuildBlockMode } from './blockchain/txpool' +import { Genesis } from './schema' +import { GenesisProvider } from './genesis-provider' +import { + InherentProviders, + ParaInherentEnter, + SetBabeRandomness, + SetNimbusAuthorInherent, + SetTimestamp, + SetValidationData, +} from './blockchain/inherent' +import { defaultLogger } from './logger' +import { openDb } from './db' + +type Options = { + endpoint?: string + block?: string | number | null + genesis?: string | Genesis + buildBlockMode?: BuildBlockMode + db?: string + mockSignatureHost?: boolean + allowUnresolvedImports?: boolean + runtimeLogLevel?: number + registeredTypes?: RegisteredTypes + offchainWorker?: boolean + maxMemoryBlockCount?: number +} + +export const setup = async (options: Options) => { + let provider: ProviderInterface + if (options.genesis) { + if (typeof options.genesis === 'string') { + provider = await GenesisProvider.fromUrl(options.genesis) + } else { + provider = new GenesisProvider(options.genesis) + } + } else { + provider = new WsProvider(options.endpoint) + } + const api = new Api(provider) + await api.isReady + + let blockHash: string + if (options.block == null) { + blockHash = await api.getBlockHash() + } else if (typeof options.block === 'string' && options.block.startsWith('0x')) { + blockHash = options.block as string + } else if (Number.isInteger(+options.block)) { + blockHash = await api.getBlockHash(Number(options.block)) + } else { + throw new Error(`Invalid block number or hash: ${options.block}`) + } + + defaultLogger.debug({ ...options, blockHash }, 'Args') + + let db: DataSource | undefined + if (options.db) { + db = await openDb(options.db) + } + + const header = await api.getHeader(blockHash) + + const inherents = new InherentProviders(new SetTimestamp(), [ + new SetValidationData(), + new ParaInherentEnter(), + new SetNimbusAuthorInherent(), + new SetBabeRandomness(), + ]) + + return new Blockchain({ + api, + buildBlockMode: options.buildBlockMode, + inherentProvider: inherents, + db, + header: { + hash: blockHash as HexString, + number: Number(header.number), + }, + mockSignatureHost: options.mockSignatureHost, + allowUnresolvedImports: options.allowUnresolvedImports, + runtimeLogLevel: options.runtimeLogLevel, + registeredTypes: options.registeredTypes || {}, + offchainWorker: options.offchainWorker, + maxMemoryBlockCount: options.maxMemoryBlockCount, + }) +} diff --git a/packages/chopsticks/src/utils/index.ts b/packages/core/src/utils/index.ts similarity index 96% rename from packages/chopsticks/src/utils/index.ts rename to packages/core/src/utils/index.ts index 54f83654..67cdcfd6 100644 --- a/packages/chopsticks/src/utils/index.ts +++ b/packages/core/src/utils/index.ts @@ -4,6 +4,9 @@ import { compactStripLength, hexToU8a, u8aToHex } from '@polkadot/util' import { Blockchain } from '../blockchain' +export * from './set-storage' +export * from './time-travel' + export type GetKeys = (startKey?: string) => Promise[]> export type ProcessKey = (key: StorageKey) => any diff --git a/packages/chopsticks/src/utils/key-cache.test.ts b/packages/core/src/utils/key-cache.test.ts similarity index 100% rename from packages/chopsticks/src/utils/key-cache.test.ts rename to packages/core/src/utils/key-cache.test.ts diff --git a/packages/chopsticks/src/utils/key-cache.ts b/packages/core/src/utils/key-cache.ts similarity index 100% rename from packages/chopsticks/src/utils/key-cache.ts rename to packages/core/src/utils/key-cache.ts diff --git a/packages/chopsticks/src/utils/proof.ts b/packages/core/src/utils/proof.ts similarity index 100% rename from packages/chopsticks/src/utils/proof.ts rename to packages/core/src/utils/proof.ts diff --git a/packages/chopsticks/src/utils/set-storage.ts b/packages/core/src/utils/set-storage.ts similarity index 100% rename from packages/chopsticks/src/utils/set-storage.ts rename to packages/core/src/utils/set-storage.ts diff --git a/packages/chopsticks/src/utils/time-travel.ts b/packages/core/src/utils/time-travel.ts similarity index 100% rename from packages/chopsticks/src/utils/time-travel.ts rename to packages/core/src/utils/time-travel.ts diff --git a/packages/chopsticks/src/xcm/downward.ts b/packages/core/src/xcm/downward.ts similarity index 100% rename from packages/chopsticks/src/xcm/downward.ts rename to packages/core/src/xcm/downward.ts diff --git a/packages/chopsticks/src/xcm/horizontal.ts b/packages/core/src/xcm/horizontal.ts similarity index 100% rename from packages/chopsticks/src/xcm/horizontal.ts rename to packages/core/src/xcm/horizontal.ts diff --git a/packages/chopsticks/src/xcm/index.ts b/packages/core/src/xcm/index.ts similarity index 100% rename from packages/chopsticks/src/xcm/index.ts rename to packages/core/src/xcm/index.ts diff --git a/packages/chopsticks/src/xcm/upward.ts b/packages/core/src/xcm/upward.ts similarity index 100% rename from packages/chopsticks/src/xcm/upward.ts rename to packages/core/src/xcm/upward.ts diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 0b5f9472..a9745a13 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -2,7 +2,11 @@ "extends": "../../tsconfig.base.json", "compilerOptions": { "outDir": "lib", - "rootDir": "src" + "rootDir": "src", + "target": "es2015", + "lib": ["es5", "dom", "dom.iterable"], + "module": "es2020", + "isolatedModules": true }, "include": ["src/**/*"], "exclude": ["src/**/*.test.ts"], diff --git a/packages/e2e/src/helper.ts b/packages/e2e/src/helper.ts index d9f76e34..b7ea1b7f 100644 --- a/packages/e2e/src/helper.ts +++ b/packages/e2e/src/helper.ts @@ -4,9 +4,9 @@ import { HexString } from '@polkadot/util/types' import { beforeAll, beforeEach, expect, vi } from 'vitest' import { Api } from '@acala-network/chopsticks' -import { Blockchain } from '@acala-network/chopsticks/blockchain' -import { BuildBlockMode } from '@acala-network/chopsticks/blockchain/txpool' -import { GenesisProvider } from '@acala-network/chopsticks/genesis-provider' +import { Blockchain } from '@acala-network/chopsticks-core/blockchain' +import { BuildBlockMode } from '@acala-network/chopsticks-core/blockchain/txpool' +import { GenesisProvider } from '@acala-network/chopsticks-core/genesis-provider' import { InherentProviders, ParaInherentEnter, @@ -14,10 +14,10 @@ import { SetNimbusAuthorInherent, SetTimestamp, SetValidationData, -} from '@acala-network/chopsticks/blockchain/inherent' -import { StorageValues } from '@acala-network/chopsticks/utils/set-storage' +} from '@acala-network/chopsticks-core/blockchain/inherent' +import { StorageValues } from '@acala-network/chopsticks-core/utils/set-storage' import { createServer } from '@acala-network/chopsticks/server' -import { defer } from '@acala-network/chopsticks/utils' +import { defer } from '@acala-network/chopsticks-core/utils' import { handler } from '@acala-network/chopsticks/rpc' export { expectJson, expectHex, testingPairs } from '@acala-network/chopsticks-testing' diff --git a/packages/e2e/src/import-storage/index.test.ts b/packages/e2e/src/import-storage/index.test.ts index 530708f6..a4b414d0 100644 --- a/packages/e2e/src/import-storage/index.test.ts +++ b/packages/e2e/src/import-storage/index.test.ts @@ -2,7 +2,7 @@ import { describe, expect, it } from 'vitest' import path from 'path' import { api, chain, setupApi } from '../helper' -import { importStorage, overrideWasm } from '@acala-network/chopsticks/utils/import-storage' +import { overrideStorage, overrideWasm } from '@acala-network/chopsticks/utils/override' setupApi({ endpoint: 'wss://acala-rpc-1.aca-api.network', @@ -17,18 +17,18 @@ describe('import-storage', () => { expect(await block?.get(sudoKey)).toBe('0x6d6f646c6163612f747273790000000000000000000000000000000000000000') - await importStorage(chain, path.join(__dirname, './storage.ok.yml')) + await overrideStorage(chain, path.join(__dirname, './storage.ok.yml')) expect(await block?.get(sudoKey)).toBeUndefined() }) it('handle errors', async () => { const notExist = path.join(__dirname, 'does_not_exist.yml') - await expect(importStorage(chain, notExist)).rejects.toThrowError(`File ${notExist} does not exist`) - await expect(importStorage(chain, path.join(__dirname, 'storage.error.pallet.yml'))).rejects.toThrowError( + await expect(overrideStorage(chain, notExist)).rejects.toThrowError(`File ${notExist} does not exist`) + await expect(overrideStorage(chain, path.join(__dirname, 'storage.error.pallet.yml'))).rejects.toThrowError( 'Cannot find pallet TTechnicalCommittee', ) - await expect(importStorage(chain, path.join(__dirname, 'storage.error.storage.yml'))).rejects.toThrowError( + await expect(overrideStorage(chain, path.join(__dirname, 'storage.error.storage.yml'))).rejects.toThrowError( 'Cannot find storage MMembers in pallet TechnicalCommittee', ) }) @@ -45,7 +45,7 @@ describe('import-storage', () => { }) it('able to reset storage map', async () => { - await importStorage(chain, { + await overrideStorage(chain, { Tokens: { $removePrefix: ['Accounts'], Accounts: [ diff --git a/packages/e2e/src/time-travel.test.ts b/packages/e2e/src/time-travel.test.ts index 6e1c580f..b359f1f9 100644 --- a/packages/e2e/src/time-travel.test.ts +++ b/packages/e2e/src/time-travel.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { getCurrentTimestamp, getSlotDuration, timeTravel } from '@acala-network/chopsticks/utils/time-travel' +import { getCurrentTimestamp, getSlotDuration, timeTravel } from '@acala-network/chopsticks-core/utils/time-travel' import networks from './networks' diff --git a/packages/e2e/src/xcm.test.ts b/packages/e2e/src/xcm.test.ts index 2c8e28ee..b3844651 100644 --- a/packages/e2e/src/xcm.test.ts +++ b/packages/e2e/src/xcm.test.ts @@ -1,10 +1,10 @@ import { beforeEach, describe, it } from 'vitest' -import { DownwardMessage, HorizontalMessage } from '@acala-network/chopsticks/blockchain/txpool' -import { connectDownward } from '@acala-network/chopsticks/xcm/downward' -import { connectUpward } from '@acala-network/chopsticks/xcm/upward' +import { DownwardMessage, HorizontalMessage } from '@acala-network/chopsticks-core/blockchain/txpool' +import { connectDownward } from '@acala-network/chopsticks-core/xcm/downward' +import { connectUpward } from '@acala-network/chopsticks-core/xcm/upward' import { matchSystemEvents, testingPairs } from '@acala-network/chopsticks-testing' -import { setStorage } from '@acala-network/chopsticks/utils/set-storage' +import { setStorage } from '@acala-network/chopsticks-core/utils/set-storage' import { matchSnapshot } from './helper' import networks, { Network } from './networks' diff --git a/packages/e2e/tsconfig.json b/packages/e2e/tsconfig.json index 6ad806be..1deb8fcd 100644 --- a/packages/e2e/tsconfig.json +++ b/packages/e2e/tsconfig.json @@ -6,6 +6,7 @@ }, "include": ["src/**/*"], "references": [ + { "path": "../core" }, { "path": "../chopsticks" }, { "path": "../testing" }, ], diff --git a/packages/testing/package.json b/packages/testing/package.json index 8bf810bf..58a83310 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -1,6 +1,6 @@ { "name": "@acala-network/chopsticks-testing", - "version": "0.7.3", + "version": "0.8.0-0", "author": "Bryan Chen ", "license": "Apache-2.0", "scripts": { @@ -32,5 +32,6 @@ "default": "./lib/*.js" }, "./package.json": "./package.json" - } + }, + "stableVersion": "0.7.3" } diff --git a/packages/testing/src/index.ts b/packages/testing/src/index.ts index 94bdfe2b..735af431 100644 --- a/packages/testing/src/index.ts +++ b/packages/testing/src/index.ts @@ -1,6 +1,7 @@ import { ApiPromise, WsProvider } from '@polkadot/api' import { BuildBlockMode, + StorageValues, connectParachains, connectVertical, fetchConfig, @@ -10,7 +11,6 @@ import { Codec } from '@polkadot/types/types' import { Config } from '@acala-network/chopsticks/schema' import { HexString } from '@polkadot/util/types' import { Keyring, createTestKeyring } from '@polkadot/keyring' -import { StorageValues } from '@acala-network/chopsticks/utils/set-storage' import { SubmittableExtrinsic } from '@polkadot/api-base/types' import { expect } from 'vitest' diff --git a/packages/web-test/.gitignore b/packages/web-test/.gitignore new file mode 100644 index 00000000..75e854d8 --- /dev/null +++ b/packages/web-test/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +/test-results/ +/playwright-report/ +/playwright/.cache/ diff --git a/packages/web-test/index.html b/packages/web-test/index.html new file mode 100644 index 00000000..915ba92d --- /dev/null +++ b/packages/web-test/index.html @@ -0,0 +1,18 @@ + + + +
Open console to access chain
+
Loading...
+
+
Caller 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
+ + +

+		
+ + + + diff --git a/packages/web-test/package.json b/packages/web-test/package.json new file mode 100644 index 00000000..e7875a65 --- /dev/null +++ b/packages/web-test/package.json @@ -0,0 +1,22 @@ +{ + "name": "@acala-network/web-test", + "author": "Acala Network ", + "license": "Apache-2.0", + "private": true, + "scripts": { + "vite:serve": "npx vite --port 3000 --host", + "parcel:serve": "npx parcel serve index.html --port 3000", + "test": "npx playwright test" + }, + "dependencies": { + "@acala-network/chopsticks-core": "workspace:*" + }, + "devDependencies": { + "@playwright/test": "^1.36.2", + "crypto-browserify": "^3.12.0", + "path-browserify": "^1.0.0", + "stream-browserify": "^3.0.0", + "typescript": "^5.1.6" + }, + "stableVersion": "0.7.3" +} diff --git a/packages/web-test/playwright.config.ts b/packages/web-test/playwright.config.ts new file mode 100644 index 00000000..668382e2 --- /dev/null +++ b/packages/web-test/playwright.config.ts @@ -0,0 +1,34 @@ +import { defineConfig, devices } from '@playwright/test' + +export default defineConfig({ + testDir: './tests', + fullyParallel: true, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 2 : 0, + workers: process.env.CI ? 1 : 4, + reporter: 'html', + use: { + baseURL: 'http://localhost:3000', + }, + + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + { + name: 'firefox', + use: { ...devices['Desktop Firefox'] }, + }, + { + name: 'webkit', + use: { ...devices['Desktop Safari'] }, + }, + ], + + webServer: { + command: 'yarn vite:serve', + url: 'http://localhost:3000', + reuseExistingServer: true, + }, +}) diff --git a/packages/web-test/src/index.ts b/packages/web-test/src/index.ts new file mode 100644 index 00000000..e65f7fdf --- /dev/null +++ b/packages/web-test/src/index.ts @@ -0,0 +1,55 @@ +/// +/// + +const app = document.getElementById('app') as HTMLDivElement +const extrinsic = document.getElementById('extrinsic') as HTMLTextAreaElement +const submit = document.getElementById('submit') as HTMLInputElement +const result = document.getElementById('result') as HTMLPreElement + +import { setStorage, setup } from '@acala-network/chopsticks-core' +;(async () => { + const chain = await setup({ + endpoint: 'wss://acala-rpc-0.aca-api.network', + block: 4_000_000, + mockSignatureHost: true, + db: 'cache', + }) + globalThis.chain = chain + + await setStorage(chain, { + System: { + Account: [ + [ + ['5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'], + { + providers: 1, + data: { + free: '1000000000000000000', + }, + }, + ], + ], + }, + }) + + submit.onclick = async () => { + result.innerHTML = 'Running...' + submit.disabled = true + const call = extrinsic.value.trim() as any + extrinsic.value = '' + try { + const { outcome, storageDiff } = await chain.dryRunExtrinsic({ + call, + address: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY', + }) + result.innerHTML = JSON.stringify({ outcome: outcome.toHuman(), storageDiff }, null, 2) + } catch (e: any) { + result.innerHTML = e.toString() + } + submit.disabled = false + } + + app.innerHTML = chain.head.number + ' ' + chain.head.hash + '
' + await chain.newBlock().catch(console.error) + app.innerHTML += chain.head.number + ' ' + chain.head.hash +})() diff --git a/packages/web-test/tests/index.spec.ts b/packages/web-test/tests/index.spec.ts new file mode 100644 index 00000000..7dc59ff6 --- /dev/null +++ b/packages/web-test/tests/index.spec.ts @@ -0,0 +1,22 @@ +import { expect, test } from '@playwright/test' + +test('build blocks successfully', async ({ page }) => { + test.setTimeout(5 * 60 * 1000) // 5 minutes timeout + + page.on('console', async (msg) => { + const args = await Promise.all(msg.args().map((arg) => arg.jsonValue())) + console.log(...args) + }) + + await page.goto('/') + await page.waitForLoadState() + + // starts with Loading... + await expect(page.locator('div#app')).toHaveText(/Loading.../) + + // chain is ready + await expect(page.locator('div#app')).toHaveText(/4000000/, { timeout: 60_000 }) + + // wait for new block + await expect(page.locator('div#app')).toHaveText(/4000001/, { timeout: 200_000 }) +}) diff --git a/packages/web-test/tsconfig.json b/packages/web-test/tsconfig.json new file mode 100644 index 00000000..8271c7a6 --- /dev/null +++ b/packages/web-test/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "lib", + "rootDir": "src", + "target": "es2016", + "lib": ["es6", "dom", "dom.iterable"], + "sourceMap": true + }, + "include": ["src/**/*"], + "references": [ + { "path": "../core" } + ] +} diff --git a/packages/web-test/vite.config.js b/packages/web-test/vite.config.js new file mode 100644 index 00000000..908f5f08 --- /dev/null +++ b/packages/web-test/vite.config.js @@ -0,0 +1,6 @@ +import { defineConfig } from 'vite' +import tsconfigPaths from 'vite-tsconfig-paths' + +export default defineConfig({ + plugins: [tsconfigPaths()], +}) diff --git a/tsconfig.base.json b/tsconfig.base.json index 60186226..b93c0897 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -11,8 +11,6 @@ "target": "esnext", "skipLibCheck": true, "strict": true, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, "declaration": true, "resolveJsonModule": true, "baseUrl": ".", @@ -20,8 +18,12 @@ "paths": { "@acala-network/chopsticks": ["packages/chopsticks/src"], "@acala-network/chopsticks/*": ["packages/chopsticks/src/*"], + "@acala-network/chopsticks-core": ["packages/core/src"], + "@acala-network/chopsticks-core/*": ["packages/core/src/*"], "@acala-network/chopsticks-testing": ["packages/testing/src"], - "@acala-network/chopsticks-testing/*": ["packages/testing/src/*"] + "@acala-network/chopsticks-testing/*": ["packages/testing/src/*"], + "@acala-network/web-test": ["packages/web/src"], + "@acala-network/web-test/*": ["packages/web/src/*"] } } } diff --git a/tsconfig.lint.json b/tsconfig.lint.json new file mode 100644 index 00000000..24199a6a --- /dev/null +++ b/tsconfig.lint.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "es2020" + } +} diff --git a/yarn.lock b/yarn.lock index 16dd80f2..f8c53f52 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,11 +12,25 @@ __metadata: languageName: node linkType: hard -"@acala-network/chopsticks-core@workspace:packages/core": +"@acala-network/chopsticks-core@workspace:*, @acala-network/chopsticks-core@workspace:packages/core": version: 0.0.0-use.local resolution: "@acala-network/chopsticks-core@workspace:packages/core" dependencies: + "@acala-network/chopsticks-executor": "workspace:*" + "@polkadot/api": ^10.9.1 + "@types/lodash": ^4.14.195 + "@types/sql.js": ^1 + axios: ^1.4.0 + eventemitter3: ^5.0.1 + localforage: ^1.10.0 + lodash: ^4.17.21 + pino: ^8.14.1 + pino-pretty: ^10.0.1 + sql.js: ^1.8.0 + sqlite3: ^5.1.6 + typeorm: ^0.3.17 typescript: ^5.1.6 + zod: ^3.21.4 languageName: unknown linkType: soft @@ -32,9 +46,9 @@ __metadata: languageName: unknown linkType: soft -"@acala-network/chopsticks-executor@workspace:*, @acala-network/chopsticks-executor@workspace:executor/pkg": +"@acala-network/chopsticks-executor@workspace:*, @acala-network/chopsticks-executor@workspace:executor": version: 0.0.0-use.local - resolution: "@acala-network/chopsticks-executor@workspace:executor/pkg" + resolution: "@acala-network/chopsticks-executor@workspace:executor" languageName: unknown linkType: soft @@ -54,7 +68,7 @@ __metadata: version: 0.0.0-use.local resolution: "@acala-network/chopsticks@workspace:packages/chopsticks" dependencies: - "@acala-network/chopsticks-executor": "workspace:*" + "@acala-network/chopsticks-core": "workspace:*" "@pnpm/npm-conf": ^2.2.2 "@polkadot/api": ^10.9.1 "@types/global-agent": ^2.1.1 @@ -64,17 +78,13 @@ __metadata: "@types/ws": ^8.5.5 "@types/yargs": ^17.0.24 axios: ^1.4.0 + dotenv: ^16.3.1 global-agent: ^3.0.0 js-yaml: ^4.1.0 jsondiffpatch: ^0.4.1 lodash: ^4.17.21 - pino: ^8.14.2 - pino-pretty: ^10.2.0 - reflect-metadata: ^0.1.13 - sqlite3: ^5.1.6 ts-node: ^10.9.1 ts-node-dev: ^2.0.0 - typeorm: ^0.3.17 typescript: ^5.1.6 ws: ^8.13.0 yargs: ^17.7.2 @@ -84,6 +94,19 @@ __metadata: languageName: unknown linkType: soft +"@acala-network/web-test@workspace:packages/web-test": + version: 0.0.0-use.local + resolution: "@acala-network/web-test@workspace:packages/web-test" + dependencies: + "@acala-network/chopsticks-core": "workspace:*" + "@playwright/test": ^1.36.2 + crypto-browserify: ^3.12.0 + path-browserify: ^1.0.0 + stream-browserify: ^3.0.0 + typescript: ^5.1.6 + languageName: unknown + linkType: soft + "@babel/runtime@npm:^7.21.0": version: 7.22.6 resolution: "@babel/runtime@npm:7.22.6" @@ -378,8 +401,8 @@ __metadata: linkType: hard "@mapbox/node-pre-gyp@npm:^1.0.0": - version: 1.0.10 - resolution: "@mapbox/node-pre-gyp@npm:1.0.10" + version: 1.0.11 + resolution: "@mapbox/node-pre-gyp@npm:1.0.11" dependencies: detect-libc: ^2.0.0 https-proxy-agent: ^5.0.0 @@ -392,7 +415,7 @@ __metadata: tar: ^6.1.11 bin: node-pre-gyp: bin/node-pre-gyp - checksum: 1a98db05d955b74dad3814679593df293b9194853698f3f5f1ed00ecd93128cdd4b14fb8767fe44ac6981ef05c23effcfdc88710e7c1de99ccb6f647890597c8 + checksum: b848f6abc531a11961d780db813cc510ca5a5b6bf3184d72134089c6875a91c44d571ba6c1879470020803f7803609e7b2e6e429651c026fe202facd11d444b8 languageName: node linkType: hard @@ -489,6 +512,22 @@ __metadata: languageName: node linkType: hard +"@playwright/test@npm:^1.36.2": + version: 1.36.2 + resolution: "@playwright/test@npm:1.36.2" + dependencies: + "@types/node": "*" + fsevents: 2.3.2 + playwright-core: 1.36.2 + dependenciesMeta: + fsevents: + optional: true + bin: + playwright: cli.js + checksum: 659304e0bbbafb2fa36395fbd8bd2c5db2b7791bbb55fa62409946ec7ec726cf8fff89f2b8a1a74fe831bf50a8780a37a5322a1251a6f7db2a9220a57ac408f0 + languageName: node + linkType: hard + "@pnpm/config.env-replace@npm:^1.1.0": version: 1.1.0 resolution: "@pnpm/config.env-replace@npm:1.1.0" @@ -1153,6 +1192,13 @@ __metadata: languageName: node linkType: hard +"@types/emscripten@npm:*": + version: 1.39.7 + resolution: "@types/emscripten@npm:1.39.7" + checksum: 9871e4495358cc06cc45b2798022cd097d8ac2eb5b2fae7c276c6c5cadea05507150fad053c73ed346d4cbd844c50a3438604e5d7c3c2a7446b703cacb1ce172 + languageName: node + linkType: hard + "@types/global-agent@npm:^2.1.1": version: 2.1.1 resolution: "@types/global-agent@npm:2.1.1" @@ -1188,14 +1234,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*": - version: 20.4.2 - resolution: "@types/node@npm:20.4.2" - checksum: 99e544ea7560d51f01f95627fc40394c24a13da8f041121a0da13e4ef0a2aa332932eaf9a5e8d0e30d1c07106e96a183be392cbba62e8cf0bf6a085d5c0f4149 - languageName: node - linkType: hard - -"@types/node@npm:^20.4.5": +"@types/node@npm:*, @types/node@npm:^20.4.5": version: 20.4.5 resolution: "@types/node@npm:20.4.5" checksum: 36a0304a8dc346a1b2d2edac4c4633eecf70875793d61a5274d0df052d7a7af7a8e34f29884eac4fbd094c4f0201477dcb39c0ecd3307ca141688806538d1138 @@ -1218,6 +1257,16 @@ __metadata: languageName: node linkType: hard +"@types/sql.js@npm:^1": + version: 1.4.4 + resolution: "@types/sql.js@npm:1.4.4" + dependencies: + "@types/emscripten": "*" + "@types/node": "*" + checksum: c71928d76b59e4899da4b137a4f1bbf8cc0cf198928efa183bba90880ae69331da23a99175b88a7f5eaa34ce9ebef8f94dd1dcca8e4abdac2abb560d860e6636 + languageName: node + linkType: hard + "@types/strip-bom@npm:^3.0.0": version: 3.0.0 resolution: "@types/strip-bom@npm:3.0.0" @@ -1710,6 +1759,18 @@ __metadata: languageName: node linkType: hard +"asn1.js@npm:^5.2.0": + version: 5.4.1 + resolution: "asn1.js@npm:5.4.1" + dependencies: + bn.js: ^4.0.0 + inherits: ^2.0.1 + minimalistic-assert: ^1.0.0 + safer-buffer: ^2.1.0 + checksum: 3786a101ac6f304bd4e9a7df79549a7561950a13d4bcaec0c7790d44c80d147c1a94ba3d4e663673406064642a40b23fcd6c82a9952468e386c1a1376d747f9a + languageName: node + linkType: hard + "assertion-error@npm:^1.1.0": version: 1.1.0 resolution: "assertion-error@npm:1.1.0" @@ -1797,7 +1858,14 @@ __metadata: languageName: node linkType: hard -"bn.js@npm:^5.2.1": +"bn.js@npm:^4.0.0, bn.js@npm:^4.1.0, bn.js@npm:^4.11.9": + version: 4.12.0 + resolution: "bn.js@npm:4.12.0" + checksum: 39afb4f15f4ea537b55eaf1446c896af28ac948fdcf47171961475724d1bb65118cca49fa6e3d67706e4790955ec0e74de584e45c8f1ef89f46c812bee5b5a12 + languageName: node + linkType: hard + +"bn.js@npm:^5.0.0, bn.js@npm:^5.1.1, bn.js@npm:^5.2.1": version: 5.2.1 resolution: "bn.js@npm:5.2.1" checksum: 3dd8c8d38055fedfa95c1d5fc3c99f8dd547b36287b37768db0abab3c239711f88ff58d18d155dd8ad902b0b0cee973747b7ae20ea12a09473272b0201c9edd3 @@ -1848,6 +1916,77 @@ __metadata: languageName: node linkType: hard +"brorand@npm:^1.0.1, brorand@npm:^1.1.0": + version: 1.1.0 + resolution: "brorand@npm:1.1.0" + checksum: 8a05c9f3c4b46572dec6ef71012b1946db6cae8c7bb60ccd4b7dd5a84655db49fe043ecc6272e7ef1f69dc53d6730b9e2a3a03a8310509a3d797a618cbee52be + languageName: node + linkType: hard + +"browserify-aes@npm:^1.0.0, browserify-aes@npm:^1.0.4": + version: 1.2.0 + resolution: "browserify-aes@npm:1.2.0" + dependencies: + buffer-xor: ^1.0.3 + cipher-base: ^1.0.0 + create-hash: ^1.1.0 + evp_bytestokey: ^1.0.3 + inherits: ^2.0.1 + safe-buffer: ^5.0.1 + checksum: 4a17c3eb55a2aa61c934c286f34921933086bf6d67f02d4adb09fcc6f2fc93977b47d9d884c25619144fccd47b3b3a399e1ad8b3ff5a346be47270114bcf7104 + languageName: node + linkType: hard + +"browserify-cipher@npm:^1.0.0": + version: 1.0.1 + resolution: "browserify-cipher@npm:1.0.1" + dependencies: + browserify-aes: ^1.0.4 + browserify-des: ^1.0.0 + evp_bytestokey: ^1.0.0 + checksum: 2d8500acf1ee535e6bebe808f7a20e4c3a9e2ed1a6885fff1facbfd201ac013ef030422bec65ca9ece8ffe82b03ca580421463f9c45af6c8415fd629f4118c13 + languageName: node + linkType: hard + +"browserify-des@npm:^1.0.0": + version: 1.0.2 + resolution: "browserify-des@npm:1.0.2" + dependencies: + cipher-base: ^1.0.1 + des.js: ^1.0.0 + inherits: ^2.0.1 + safe-buffer: ^5.1.2 + checksum: b15a3e358a1d78a3b62ddc06c845d02afde6fc826dab23f1b9c016e643e7b1fda41de628d2110b712f6a44fb10cbc1800bc6872a03ddd363fb50768e010395b7 + languageName: node + linkType: hard + +"browserify-rsa@npm:^4.0.0, browserify-rsa@npm:^4.0.1": + version: 4.1.0 + resolution: "browserify-rsa@npm:4.1.0" + dependencies: + bn.js: ^5.0.0 + randombytes: ^2.0.1 + checksum: 155f0c135873efc85620571a33d884aa8810e40176125ad424ec9d85016ff105a07f6231650914a760cca66f29af0494087947b7be34880dd4599a0cd3c38e54 + languageName: node + linkType: hard + +"browserify-sign@npm:^4.0.0": + version: 4.2.1 + resolution: "browserify-sign@npm:4.2.1" + dependencies: + bn.js: ^5.1.1 + browserify-rsa: ^4.0.1 + create-hash: ^1.2.0 + create-hmac: ^1.1.7 + elliptic: ^6.5.3 + inherits: ^2.0.4 + parse-asn1: ^5.1.5 + readable-stream: ^3.6.0 + safe-buffer: ^5.2.0 + checksum: 0221f190e3f5b2d40183fa51621be7e838d9caa329fe1ba773406b7637855f37b30f5d83e52ff8f244ed12ffe6278dd9983638609ed88c841ce547e603855707 + languageName: node + linkType: hard + "buffer-from@npm:^1.0.0": version: 1.1.2 resolution: "buffer-from@npm:1.1.2" @@ -1855,6 +1994,13 @@ __metadata: languageName: node linkType: hard +"buffer-xor@npm:^1.0.3": + version: 1.0.3 + resolution: "buffer-xor@npm:1.0.3" + checksum: 10c520df29d62fa6e785e2800e586a20fc4f6dfad84bcdbd12e1e8a83856de1cb75c7ebd7abe6d036bbfab738a6cf18a3ae9c8e5a2e2eb3167ca7399ce65373a + languageName: node + linkType: hard + "buffer@npm:^6.0.3": version: 6.0.3 resolution: "buffer@npm:6.0.3" @@ -2037,6 +2183,16 @@ __metadata: languageName: node linkType: hard +"cipher-base@npm:^1.0.0, cipher-base@npm:^1.0.1, cipher-base@npm:^1.0.3": + version: 1.0.4 + resolution: "cipher-base@npm:1.0.4" + dependencies: + inherits: ^2.0.1 + safe-buffer: ^5.0.1 + checksum: 47d3568dbc17431a339bad1fe7dff83ac0891be8206911ace3d3b818fc695f376df809bea406e759cdea07fff4b454fa25f1013e648851bec790c1d75763032e + languageName: node + linkType: hard + "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" @@ -2163,6 +2319,43 @@ __metadata: languageName: node linkType: hard +"create-ecdh@npm:^4.0.0": + version: 4.0.4 + resolution: "create-ecdh@npm:4.0.4" + dependencies: + bn.js: ^4.1.0 + elliptic: ^6.5.3 + checksum: 0dd7fca9711d09e152375b79acf1e3f306d1a25ba87b8ff14c2fd8e68b83aafe0a7dd6c4e540c9ffbdd227a5fa1ad9b81eca1f233c38bb47770597ba247e614b + languageName: node + linkType: hard + +"create-hash@npm:^1.1.0, create-hash@npm:^1.1.2, create-hash@npm:^1.2.0": + version: 1.2.0 + resolution: "create-hash@npm:1.2.0" + dependencies: + cipher-base: ^1.0.1 + inherits: ^2.0.1 + md5.js: ^1.3.4 + ripemd160: ^2.0.1 + sha.js: ^2.4.0 + checksum: 02a6ae3bb9cd4afee3fabd846c1d8426a0e6b495560a977ba46120c473cb283be6aa1cace76b5f927cf4e499c6146fb798253e48e83d522feba807d6b722eaa9 + languageName: node + linkType: hard + +"create-hmac@npm:^1.1.0, create-hmac@npm:^1.1.4, create-hmac@npm:^1.1.7": + version: 1.1.7 + resolution: "create-hmac@npm:1.1.7" + dependencies: + cipher-base: ^1.0.3 + create-hash: ^1.1.0 + inherits: ^2.0.1 + ripemd160: ^2.0.0 + safe-buffer: ^5.0.1 + sha.js: ^2.4.8 + checksum: ba12bb2257b585a0396108c72830e85f882ab659c3320c83584b1037f8ab72415095167ced80dc4ce8e446a8ecc4b2acf36d87befe0707d73b26cf9dc77440ed + languageName: node + linkType: hard + "create-require@npm:^1.1.0": version: 1.1.1 resolution: "create-require@npm:1.1.1" @@ -2181,6 +2374,25 @@ __metadata: languageName: node linkType: hard +"crypto-browserify@npm:^3.12.0": + version: 3.12.0 + resolution: "crypto-browserify@npm:3.12.0" + dependencies: + browserify-cipher: ^1.0.0 + browserify-sign: ^4.0.0 + create-ecdh: ^4.0.0 + create-hash: ^1.1.0 + create-hmac: ^1.1.0 + diffie-hellman: ^5.0.0 + inherits: ^2.0.1 + pbkdf2: ^3.0.3 + public-encrypt: ^4.0.0 + randombytes: ^2.0.0 + randomfill: ^1.0.3 + checksum: c1609af82605474262f3eaa07daa0b2140026bd264ab316d4bf1170272570dbe02f0c49e29407fe0d3634f96c507c27a19a6765fb856fed854a625f9d15618e2 + languageName: node + linkType: hard + "data-uri-to-buffer@npm:^4.0.0": version: 4.0.1 resolution: "data-uri-to-buffer@npm:4.0.1" @@ -2301,10 +2513,20 @@ __metadata: languageName: node linkType: hard +"des.js@npm:^1.0.0": + version: 1.1.0 + resolution: "des.js@npm:1.1.0" + dependencies: + inherits: ^2.0.1 + minimalistic-assert: ^1.0.0 + checksum: 0e9c1584b70d31e20f20a613fc9ef60fbc6a147dfec9e448a168794a4b97ac04d8dc47ea008f1fa93b0f8aaf7c1ead632a5e59ce1913a6079d2d244c9f5ebe33 + languageName: node + linkType: hard + "detect-libc@npm:^2.0.0": - version: 2.0.1 - resolution: "detect-libc@npm:2.0.1" - checksum: ccb05fcabbb555beb544d48080179c18523a343face9ee4e1a86605a8715b4169f94d663c21a03c310ac824592f2ba9a5270218819bb411ad7be578a527593d7 + version: 2.0.2 + resolution: "detect-libc@npm:2.0.2" + checksum: 2b2cd3649b83d576f4be7cc37eb3b1815c79969c8b1a03a40a4d55d83bc74d010753485753448eacb98784abf22f7dbd3911fd3b60e29fda28fed2d1a997944d languageName: node linkType: hard @@ -2336,6 +2558,17 @@ __metadata: languageName: node linkType: hard +"diffie-hellman@npm:^5.0.0": + version: 5.0.3 + resolution: "diffie-hellman@npm:5.0.3" + dependencies: + bn.js: ^4.1.0 + miller-rabin: ^4.0.0 + randombytes: ^2.0.0 + checksum: 0e620f322170c41076e70181dd1c24e23b08b47dbb92a22a644f3b89b6d3834b0f8ee19e37916164e5eb1ee26d2aa836d6129f92723995267250a0b541811065 + languageName: node + linkType: hard + "dir-glob@npm:^3.0.1": version: 3.0.1 resolution: "dir-glob@npm:3.0.1" @@ -2363,7 +2596,7 @@ __metadata: languageName: node linkType: hard -"dotenv@npm:^16.0.3": +"dotenv@npm:^16.0.3, dotenv@npm:^16.3.1": version: 16.3.1 resolution: "dotenv@npm:16.3.1" checksum: 15d75e7279018f4bafd0ee9706593dd14455ddb71b3bcba9c52574460b7ccaf67d5cf8b2c08a5af1a9da6db36c956a04a1192b101ee102a3e0cf8817bbcf3dfd @@ -2386,6 +2619,21 @@ __metadata: languageName: node linkType: hard +"elliptic@npm:^6.5.3": + version: 6.5.4 + resolution: "elliptic@npm:6.5.4" + dependencies: + bn.js: ^4.11.9 + brorand: ^1.1.0 + hash.js: ^1.0.0 + hmac-drbg: ^1.0.1 + inherits: ^2.0.4 + minimalistic-assert: ^1.0.1 + minimalistic-crypto-utils: ^1.0.1 + checksum: d56d21fd04e97869f7ffcc92e18903b9f67f2d4637a23c860492fbbff5a3155fd9ca0184ce0c865dd6eb2487d234ce9551335c021c376cd2d3b7cb749c7d10f4 + languageName: node + linkType: hard + "emoji-regex@npm:^8.0.0": version: 8.0.0 resolution: "emoji-regex@npm:8.0.0" @@ -2912,6 +3160,17 @@ __metadata: languageName: node linkType: hard +"evp_bytestokey@npm:^1.0.0, evp_bytestokey@npm:^1.0.3": + version: 1.0.3 + resolution: "evp_bytestokey@npm:1.0.3" + dependencies: + md5.js: ^1.3.4 + node-gyp: latest + safe-buffer: ^5.1.1 + checksum: ad4e1577f1a6b721c7800dcc7c733fe01f6c310732bb5bf2240245c2a5b45a38518b91d8be2c610611623160b9d1c0e91f1ce96d639f8b53e8894625cf20fa45 + languageName: node + linkType: hard + "execa@npm:^5.0.0": version: 5.1.1 resolution: "execa@npm:5.1.1" @@ -3146,7 +3405,7 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:~2.3.2": +"fsevents@npm:2.3.2, fsevents@npm:~2.3.2": version: 2.3.2 resolution: "fsevents@npm:2.3.2" dependencies: @@ -3156,7 +3415,7 @@ __metadata: languageName: node linkType: hard -"fsevents@patch:fsevents@~2.3.2#~builtin": +"fsevents@patch:fsevents@2.3.2#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin": version: 2.3.2 resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=df0bf1" dependencies: @@ -3508,6 +3767,27 @@ __metadata: languageName: node linkType: hard +"hash-base@npm:^3.0.0": + version: 3.1.0 + resolution: "hash-base@npm:3.1.0" + dependencies: + inherits: ^2.0.4 + readable-stream: ^3.6.0 + safe-buffer: ^5.2.0 + checksum: 26b7e97ac3de13cb23fc3145e7e3450b0530274a9562144fc2bf5c1e2983afd0e09ed7cc3b20974ba66039fad316db463da80eb452e7373e780cbee9a0d2f2dc + languageName: node + linkType: hard + +"hash.js@npm:^1.0.0, hash.js@npm:^1.0.3": + version: 1.1.7 + resolution: "hash.js@npm:1.1.7" + dependencies: + inherits: ^2.0.3 + minimalistic-assert: ^1.0.1 + checksum: e350096e659c62422b85fa508e4b3669017311aa4c49b74f19f8e1bc7f3a54a584fdfd45326d4964d6011f2b2d882e38bea775a96046f2a61b7779a979629d8f + languageName: node + linkType: hard + "help-me@npm:^4.0.1": version: 4.2.0 resolution: "help-me@npm:4.2.0" @@ -3525,6 +3805,17 @@ __metadata: languageName: node linkType: hard +"hmac-drbg@npm:^1.0.1": + version: 1.0.1 + resolution: "hmac-drbg@npm:1.0.1" + dependencies: + hash.js: ^1.0.3 + minimalistic-assert: ^1.0.0 + minimalistic-crypto-utils: ^1.0.1 + checksum: bd30b6a68d7f22d63f10e1888aee497d7c2c5c0bb469e66bbdac99f143904d1dfe95f8131f95b3e86c86dd239963c9d972fcbe147e7cffa00e55d18585c43fe0 + languageName: node + linkType: hard + "http-cache-semantics@npm:^4.1.0, http-cache-semantics@npm:^4.1.1": version: 4.1.1 resolution: "http-cache-semantics@npm:4.1.1" @@ -3619,6 +3910,13 @@ __metadata: languageName: node linkType: hard +"immediate@npm:~3.0.5": + version: 3.0.6 + resolution: "immediate@npm:3.0.6" + checksum: f9b3486477555997657f70318cc8d3416159f208bec4cca3ff3442fd266bc23f50f0c9bd8547e1371a6b5e82b821ec9a7044a4f7b944798b25aa3cc6d5e63e62 + languageName: node + linkType: hard + "import-fresh@npm:^3.0.0, import-fresh@npm:^3.2.1": version: 3.3.0 resolution: "import-fresh@npm:3.3.0" @@ -3660,7 +3958,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:^2.0.1, inherits@npm:^2.0.3": +"inherits@npm:2, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.4": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 @@ -4033,6 +4331,15 @@ __metadata: languageName: node linkType: hard +"lie@npm:3.1.1": + version: 3.1.1 + resolution: "lie@npm:3.1.1" + dependencies: + immediate: ~3.0.5 + checksum: 6da9f2121d2dbd15f1eca44c0c7e211e66a99c7b326ec8312645f3648935bc3a658cf0e9fa7b5f10144d9e2641500b4f55bd32754607c3de945b5f443e50ddd1 + languageName: node + linkType: hard + "local-pkg@npm:^0.4.3": version: 0.4.3 resolution: "local-pkg@npm:0.4.3" @@ -4040,6 +4347,15 @@ __metadata: languageName: node linkType: hard +"localforage@npm:^1.10.0": + version: 1.10.0 + resolution: "localforage@npm:1.10.0" + dependencies: + lie: 3.1.1 + checksum: f2978b434dafff9bcb0d9498de57d97eba165402419939c944412e179cab1854782830b5ec196212560b22712d1dd03918939f59cf1d4fc1d756fca7950086cf + languageName: node + linkType: hard + "locate-path@npm:^6.0.0": version: 6.0.0 resolution: "locate-path@npm:6.0.0" @@ -4176,6 +4492,17 @@ __metadata: languageName: node linkType: hard +"md5.js@npm:^1.3.4": + version: 1.3.5 + resolution: "md5.js@npm:1.3.5" + dependencies: + hash-base: ^3.0.0 + inherits: ^2.0.1 + safe-buffer: ^5.1.2 + checksum: 098494d885684bcc4f92294b18ba61b7bd353c23147fbc4688c75b45cb8590f5a95fd4584d742415dcc52487f7a1ef6ea611cfa1543b0dc4492fe026357f3f0c + languageName: node + linkType: hard + "merge-stream@npm:^2.0.0": version: 2.0.0 resolution: "merge-stream@npm:2.0.0" @@ -4200,6 +4527,18 @@ __metadata: languageName: node linkType: hard +"miller-rabin@npm:^4.0.0": + version: 4.0.1 + resolution: "miller-rabin@npm:4.0.1" + dependencies: + bn.js: ^4.0.0 + brorand: ^1.0.1 + bin: + miller-rabin: bin/miller-rabin + checksum: 00cd1ab838ac49b03f236cc32a14d29d7d28637a53096bf5c6246a032a37749c9bd9ce7360cbf55b41b89b7d649824949ff12bc8eee29ac77c6b38eada619ece + languageName: node + linkType: hard + "mime-db@npm:1.52.0": version: 1.52.0 resolution: "mime-db@npm:1.52.0" @@ -4230,6 +4569,20 @@ __metadata: languageName: node linkType: hard +"minimalistic-assert@npm:^1.0.0, minimalistic-assert@npm:^1.0.1": + version: 1.0.1 + resolution: "minimalistic-assert@npm:1.0.1" + checksum: cc7974a9268fbf130fb055aff76700d7e2d8be5f761fb5c60318d0ed010d839ab3661a533ad29a5d37653133385204c503bfac995aaa4236f4e847461ea32ba7 + languageName: node + linkType: hard + +"minimalistic-crypto-utils@npm:^1.0.1": + version: 1.0.1 + resolution: "minimalistic-crypto-utils@npm:1.0.1" + checksum: 6e8a0422b30039406efd4c440829ea8f988845db02a3299f372fceba56ffa94994a9c0f2fd70c17f9969eedfbd72f34b5070ead9656a34d3f71c0bd72583a0ed + languageName: node + linkType: hard + "minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" @@ -4799,6 +5152,19 @@ __metadata: languageName: node linkType: hard +"parse-asn1@npm:^5.0.0, parse-asn1@npm:^5.1.5": + version: 5.1.6 + resolution: "parse-asn1@npm:5.1.6" + dependencies: + asn1.js: ^5.2.0 + browserify-aes: ^1.0.0 + evp_bytestokey: ^1.0.0 + pbkdf2: ^3.0.3 + safe-buffer: ^5.1.1 + checksum: 9243311d1f88089bc9f2158972aa38d1abd5452f7b7cabf84954ed766048fe574d434d82c6f5a39b988683e96fb84cd933071dda38927e03469dc8c8d14463c7 + languageName: node + linkType: hard + "parse5-htmlparser2-tree-adapter@npm:^6.0.0": version: 6.0.1 resolution: "parse5-htmlparser2-tree-adapter@npm:6.0.1" @@ -4822,6 +5188,13 @@ __metadata: languageName: node linkType: hard +"path-browserify@npm:^1.0.0": + version: 1.0.1 + resolution: "path-browserify@npm:1.0.1" + checksum: c6d7fa376423fe35b95b2d67990060c3ee304fc815ff0a2dc1c6c3cfaff2bd0d572ee67e18f19d0ea3bbe32e8add2a05021132ac40509416459fffee35200699 + languageName: node + linkType: hard + "path-exists@npm:^4.0.0": version: 4.0.0 resolution: "path-exists@npm:4.0.0" @@ -4888,6 +5261,19 @@ __metadata: languageName: node linkType: hard +"pbkdf2@npm:^3.0.3": + version: 3.1.2 + resolution: "pbkdf2@npm:3.1.2" + dependencies: + create-hash: ^1.1.2 + create-hmac: ^1.1.4 + ripemd160: ^2.0.1 + safe-buffer: ^5.0.1 + sha.js: ^2.4.8 + checksum: 2c950a100b1da72123449208e231afc188d980177d021d7121e96a2de7f2abbc96ead2b87d03d8fe5c318face097f203270d7e27908af9f471c165a4e8e69c92 + languageName: node + linkType: hard + "picocolors@npm:^1.0.0": version: 1.0.0 resolution: "picocolors@npm:1.0.0" @@ -4912,9 +5298,9 @@ __metadata: languageName: node linkType: hard -"pino-pretty@npm:^10.2.0": - version: 10.2.0 - resolution: "pino-pretty@npm:10.2.0" +"pino-pretty@npm:^10.0.1": + version: 10.0.1 + resolution: "pino-pretty@npm:10.0.1" dependencies: colorette: ^2.0.7 dateformat: ^4.6.3 @@ -4932,7 +5318,7 @@ __metadata: strip-json-comments: ^3.1.1 bin: pino-pretty: bin.js - checksum: 8e8220ab647d11e05349adde37aac116dab1a96ce479297820475b7e2246ea5e56e3764b625c5877821ae66dcea62bdda563cc49eccbd4628c80952998068f48 + checksum: b156c066c106026cb6a555c1f6ebb6b15636ce5516917cc979a179dcb17fdaaf7361cbe6242ae8f3661e9cfa6c18c35906afde3f9511bd2ec80dc39b6693fdde languageName: node linkType: hard @@ -4943,9 +5329,9 @@ __metadata: languageName: node linkType: hard -"pino@npm:^8.14.2": - version: 8.14.2 - resolution: "pino@npm:8.14.2" +"pino@npm:^8.14.1": + version: 8.14.1 + resolution: "pino@npm:8.14.1" dependencies: atomic-sleep: ^1.0.0 fast-redact: ^3.1.1 @@ -4960,7 +5346,7 @@ __metadata: thread-stream: ^2.0.0 bin: pino: bin.js - checksum: 9b777472be2d57a3120f7fd39090d04eacd3af1b25d74ebf606defb9c34fd587820f91ca12bfe52e61330e5fd9f72f67db98293c0ff8c77893e855a65f1dadf0 + checksum: 72dcae8f550d375695bb8745f11b30c42aaa20d0bcab8f546ca5af0684d784453850949fe1b244206793e813a46d72cbbf0dda8aed2cee86e9491ba44a643e3e languageName: node linkType: hard @@ -4975,14 +5361,23 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.4.25": - version: 8.4.25 - resolution: "postcss@npm:8.4.25" +"playwright-core@npm:1.36.2": + version: 1.36.2 + resolution: "playwright-core@npm:1.36.2" + bin: + playwright-core: cli.js + checksum: 2193ce802ef93c28b9b5e11a0b1d7b60778c686015659978d1cbf0eb9cda2cdc85ec5575b887c1346e9d161cc2805bf27638d76a2f7f857dffeae968e6ceffcd + languageName: node + linkType: hard + +"postcss@npm:^8.4.26": + version: 8.4.27 + resolution: "postcss@npm:8.4.27" dependencies: nanoid: ^3.3.6 picocolors: ^1.0.0 source-map-js: ^1.0.2 - checksum: 9ed3ab8af43ad5210c28f56f916fd9b8c9f94fbeaebbf645dcf579bc28bdd8056c2a7ecc934668d399b81fedb6128f0c4b299f931e50454964bc911c25a3a0a2 + checksum: 1cdd0c298849df6cd65f7e646a3ba36870a37b65f55fd59d1a165539c263e9b4872a402bf4ed1ca1bc31f58b68b2835545e33ea1a23b161a1f8aa6d5ded81e78 languageName: node linkType: hard @@ -5065,6 +5460,20 @@ __metadata: languageName: node linkType: hard +"public-encrypt@npm:^4.0.0": + version: 4.0.3 + resolution: "public-encrypt@npm:4.0.3" + dependencies: + bn.js: ^4.1.0 + browserify-rsa: ^4.0.0 + create-hash: ^1.1.0 + parse-asn1: ^5.0.0 + randombytes: ^2.0.1 + safe-buffer: ^5.1.2 + checksum: 215d446e43cef021a20b67c1df455e5eea134af0b1f9b8a35f9e850abf32991b0c307327bc5b9bc07162c288d5cdb3d4a783ea6c6640979ed7b5017e3e0c9935 + languageName: node + linkType: hard + "pump@npm:^3.0.0": version: 3.0.0 resolution: "pump@npm:3.0.0" @@ -5096,6 +5505,25 @@ __metadata: languageName: node linkType: hard +"randombytes@npm:^2.0.0, randombytes@npm:^2.0.1, randombytes@npm:^2.0.5": + version: 2.1.0 + resolution: "randombytes@npm:2.1.0" + dependencies: + safe-buffer: ^5.1.0 + checksum: d779499376bd4cbb435ef3ab9a957006c8682f343f14089ed5f27764e4645114196e75b7f6abf1cbd84fd247c0cb0651698444df8c9bf30e62120fbbc52269d6 + languageName: node + linkType: hard + +"randomfill@npm:^1.0.3": + version: 1.0.4 + resolution: "randomfill@npm:1.0.4" + dependencies: + randombytes: ^2.0.5 + safe-buffer: ^5.1.0 + checksum: 33734bb578a868d29ee1b8555e21a36711db084065d94e019a6d03caa67debef8d6a1bfd06a2b597e32901ddc761ab483a85393f0d9a75838f1912461d4dbfc7 + languageName: node + linkType: hard + "react-is@npm:^18.0.0": version: 18.2.0 resolution: "react-is@npm:18.2.0" @@ -5103,7 +5531,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^3.6.0": +"readable-stream@npm:^3.5.0, readable-stream@npm:^3.6.0": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" dependencies: @@ -5251,6 +5679,16 @@ __metadata: languageName: node linkType: hard +"ripemd160@npm:^2.0.0, ripemd160@npm:^2.0.1": + version: 2.0.2 + resolution: "ripemd160@npm:2.0.2" + dependencies: + hash-base: ^3.0.0 + inherits: ^2.0.1 + checksum: 006accc40578ee2beae382757c4ce2908a826b27e2b079efdcd2959ee544ddf210b7b5d7d5e80467807604244e7388427330f5c6d4cd61e6edaddc5773ccc393 + languageName: node + linkType: hard + "roarr@npm:^2.15.3": version: 2.15.4 resolution: "roarr@npm:2.15.4" @@ -5318,7 +5756,7 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:^5.0.1, safe-buffer@npm:~5.2.0": +"safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.1.1, safe-buffer@npm:^5.1.2, safe-buffer@npm:^5.2.0, safe-buffer@npm:~5.2.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 @@ -5343,7 +5781,7 @@ __metadata: languageName: node linkType: hard -"safer-buffer@npm:>= 2.1.2 < 3.0.0": +"safer-buffer@npm:>= 2.1.2 < 3.0.0, safer-buffer@npm:^2.1.0": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" checksum: cab8f25ae6f1434abee8d80023d7e72b598cf1327164ddab31003c51215526801e40b66c5e65d658a0af1e9d6478cadcb4c745f4bd6751f97d8644786c0978b0 @@ -5400,7 +5838,7 @@ __metadata: languageName: node linkType: hard -"sha.js@npm:^2.4.11": +"sha.js@npm:^2.4.0, sha.js@npm:^2.4.11, sha.js@npm:^2.4.8": version: 2.4.11 resolution: "sha.js@npm:2.4.11" dependencies: @@ -5570,6 +6008,13 @@ __metadata: languageName: node linkType: hard +"sql.js@npm:^1.8.0": + version: 1.8.0 + resolution: "sql.js@npm:1.8.0" + checksum: 4c16846815664ef95c4dc2ffbbef4cba5236ead0798c9f1fac11f66c194a0ac51862fe26980be55cef8738b12ebe9d12efe71262953773cdcb41fbef034b2320 + languageName: node + linkType: hard + "sqlite3@npm:^5.1.6": version: 5.1.6 resolution: "sqlite3@npm:5.1.6" @@ -5622,6 +6067,16 @@ __metadata: languageName: node linkType: hard +"stream-browserify@npm:^3.0.0": + version: 3.0.0 + resolution: "stream-browserify@npm:3.0.0" + dependencies: + inherits: ~2.0.4 + readable-stream: ^3.5.0 + checksum: 4c47ef64d6f03815a9ca3874e2319805e8e8a85f3550776c47ce523b6f4c6cd57f40e46ec6a9ab8ad260fde61863c2718f250d3bedb3fe9052444eb9abfd9921 + languageName: node + linkType: hard + "string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" @@ -6350,12 +6805,12 @@ __metadata: linkType: hard "vite@npm:^3.0.0 || ^4.0.0": - version: 4.4.3 - resolution: "vite@npm:4.4.3" + version: 4.4.7 + resolution: "vite@npm:4.4.7" dependencies: esbuild: ^0.18.10 fsevents: ~2.3.2 - postcss: ^8.4.25 + postcss: ^8.4.26 rollup: ^3.25.2 peerDependencies: "@types/node": ">= 14" @@ -6385,7 +6840,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 2f7c90de35c840ed7f33000d65006053885c0342aa7c19cee7369d7b3d92473a9bae790f910eb3e9900bdb7ca89559a772ee4782f35636ec4e6bd10717e7f5ff + checksum: 787c4d891da18d0a0545bee07dec73c3201979dcf2b1ea3dc13fdd2d3b9ad76d413bcc0e68502183e309007a612c1f4116adefe0093d95fbbb9cf1c1755f7e41 languageName: node linkType: hard