Rc/evm signature (#249)

* feat: allow signing function only for bundled txs

* fix: after ppe review

* feat: add transaction verification

* feat: warp plugins system

* chore: removing lodash dep

* feat: isEvmSigned verification

* chore: useFastCopy fix in tests

* feat: evm signature - minor fixes

* fix: try-catch for evm sig verification

* v1.2.14-beta.5

* fix: await for sig verification

* v1.2.14-beta.6

* chore: restore original package version

Co-authored-by: asiaziola <ziola.jm@gmail.com>
This commit is contained in:
just_ppe
2022-11-07 15:16:33 +01:00
committed by GitHub
parent 9335023824
commit ef6a445a2e
20 changed files with 3194 additions and 169 deletions

View File

@@ -1,5 +1,6 @@
const { build } = require('esbuild');
const rimraf = require('rimraf');
const fs = require("fs");
const clean = async () => {
return new Promise((resolve) => {
@@ -20,17 +21,23 @@ const runBuild = async () => {
};
console.log('Building web bundle esm.');
build({
const result = await build({
...buildConfig,
minify: true,
outfile: './bundles/web.bundle.min.js'
outfile: './bundles/web.bundle.min.js',
metafile: true
}).catch((e) => {
console.log(e);
process.exit(1);
});
fs.writeFileSync('metadata.json', JSON.stringify({
inputs: result.metafile.inputs,
outputs: result.metafile.outputs
}));
console.log('Building web bundle iife.');
build({
await build({
...buildConfig,
minify: true,
target: ['esnext'],

View File

@@ -64,13 +64,11 @@
"@idena/vrf-js": "^1.0.1",
"archiver": "^5.3.0",
"arweave": "1.11.6",
"bignumber.js": "^9.0.1",
"elliptic": "^6.5.4",
"events": "3.3.0",
"fast-copy": "^2.1.1",
"knex": "^0.95.14",
"level": "^8.0.0",
"lodash": "^4.17.21",
"memory-level": "^1.0.0",
"redstone-isomorphic": "1.1.8",
"redstone-wasm-metering": "1.0.3",
@@ -89,7 +87,7 @@
"cheerio": "^1.0.0-rc.10",
"cli-table": "0.3.11",
"colors": "^1.4.0",
"esbuild": "0.15.5",
"esbuild": "0.15.12",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.1",

View File

@@ -70,7 +70,6 @@ describe.each(chunked)('v1 compare.suite %#', (contracts: string[]) => {
.build()
.contract(contractTxId)
.setEvaluationOptions({
useFastCopy: true,
allowUnsafeClient: true,
allowBigInt: true
})
@@ -113,7 +112,6 @@ describe.each(chunkedVm)('v1 compare.suite (VM2) %#', (contracts: string[]) => {
.build()
.contract(contractTxId)
.setEvaluationOptions({
useFastCopy: true,
useVM2: true,
allowUnsafeClient: true,
allowBigInt: true
@@ -153,7 +151,6 @@ describe.each(chunkedGw)('gateways compare.suite %#', (contracts: string[]) => {
const result = await warpR
.contract(contractTxId)
.setEvaluationOptions({
useFastCopy: true,
allowUnsafeClient: true,
allowBigInt: true
})
@@ -173,7 +170,6 @@ describe.each(chunkedGw)('gateways compare.suite %#', (contracts: string[]) => {
.build()
.contract(contractTxId)
.setEvaluationOptions({
useFastCopy: true,
allowUnsafeClient: true,
allowBigInt: true
})

View File

@@ -11,7 +11,7 @@ export type CurrentTx = { interactionTxId: string; contractTxId: string };
export type BenchmarkStats = { gatewayCommunication: number; stateEvaluation: number; total: number };
export type SigningFunction = (tx: Transaction) => Promise<void>;
export type Signature = { signer: SigningFunction; signatureType: 'arweave' | 'ethereum' };
export class ContractError extends Error {
constructor(message) {
super(message);
@@ -85,7 +85,7 @@ export interface Contract<State = unknown> extends Source {
*
* @param signer - either {@link ArWallet} that will be connected to this contract or custom {@link SigningFunction}
*/
connect(signer: ArWallet | SigningFunction): Contract<State>;
connect(signature: ArWallet | Signature): Contract<State>;
/**
* Allows to set ({@link EvaluationOptions})

View File

@@ -26,11 +26,11 @@ import { sleep } from '../utils/utils';
import {
Contract,
BenchmarkStats,
SigningFunction,
CurrentTx,
WriteInteractionOptions,
WriteInteractionResponse,
InnerCallData
InnerCallData,
Signature
} from './Contract';
import { Tags, ArTransfer, emptyTransfer, ArWallet } from './deploy/CreateContract';
import { SourceData, SourceImpl } from './deploy/impl/SourceImpl';
@@ -58,7 +58,7 @@ export class HandlerBasedContract<State> implements Contract<State> {
/**
* wallet connected to this contract
*/
protected signer?: SigningFunction;
protected signature?: Signature;
constructor(
private readonly _contractTxId: string,
@@ -207,7 +207,7 @@ export class HandlerBasedContract<State> implements Contract<State> {
options?: WriteInteractionOptions
): Promise<WriteInteractionResponse | null> {
this.logger.info('Write interaction', { input, options });
if (!this.signer) {
if (!this.signature) {
throw new Error("Wallet not connected. Use 'connect' method first.");
}
const { arweave, interactionsLoader, environment } = this.warp;
@@ -221,6 +221,12 @@ export class HandlerBasedContract<State> implements Contract<State> {
const bundleInteraction = interactionsLoader.type() == 'warp' && !effectiveDisableBundling;
if (this.signature.signatureType !== 'arweave' && !bundleInteraction) {
throw new Error(
`Unable to use signing function of type: ${this.signature.signatureType} when not in mainnet environment or bundling is disabled.`
);
}
if (
bundleInteraction &&
effectiveTransfer.target != emptyTransfer.target &&
@@ -369,7 +375,7 @@ export class HandlerBasedContract<State> implements Contract<State> {
const interactionTx = await createInteractionTx(
this.warp.arweave,
this.signer,
this.signature.signer,
this._contractTxId,
input,
tags,
@@ -389,12 +395,27 @@ export class HandlerBasedContract<State> implements Contract<State> {
return this._callStack;
}
connect(signer: ArWallet | SigningFunction): Contract<State> {
if (typeof signer == 'function') {
this.signer = signer;
connect(signature: ArWallet | Signature): Contract<State> {
if (this.isSignatureType(signature)) {
if (
signature.signatureType !== 'arweave' &&
(!(this.warp.environment == 'mainnet') || !(this.warp.interactionsLoader.type() == 'warp'))
) {
throw new Error(
`Unable to use signing function of type: ${signature.signatureType} when not in mainnet environment or bundling is disabled.`
);
} else {
this.signature = {
signer: signature.signer,
signatureType: signature.signatureType
};
}
} else {
this.signer = async (tx: Transaction) => {
await this.warp.arweave.transactions.sign(tx, signer);
this.signature = {
signer: async (tx: Transaction) => {
await this.warp.arweave.transactions.sign(tx, signature);
},
signatureType: 'arweave'
};
}
return this;
@@ -539,7 +560,7 @@ export class HandlerBasedContract<State> implements Contract<State> {
): Promise<InteractionResult<State, View>> {
this.logger.info('Call contract input', input);
this.maybeResetRootContract();
if (!this.signer) {
if (!this.signature) {
this.logger.warn('Wallet not set.');
}
const { arweave, stateEvaluator } = this.warp;
@@ -553,7 +574,7 @@ export class HandlerBasedContract<State> implements Contract<State> {
let effectiveCaller;
if (caller) {
effectiveCaller = caller;
} else if (this.signer) {
} else if (this.signature) {
// we're creating this transaction just to call the signing function on it
// - and retrieve the caller/owner
const dummyTx = await arweave.createTransaction({
@@ -561,7 +582,7 @@ export class HandlerBasedContract<State> implements Contract<State> {
reward: '72600854',
last_tx: 'p7vc1iSP6bvH_fCeUFa9LqoV5qiyW-jdEKouAT0XMoSwrNraB9mgpi29Q10waEpO'
});
await this.signer(dummyTx);
await this.signature.signer(dummyTx);
effectiveCaller = await arweave.wallets.ownerToAddress(dummyTx.owner);
} else {
effectiveCaller = '';
@@ -586,7 +607,7 @@ export class HandlerBasedContract<State> implements Contract<State> {
this.logger.debug('interaction', interaction);
const tx = await createInteractionTx(
arweave,
this.signer,
this.signature?.signer,
this._contractTxId,
input,
tags,
@@ -746,13 +767,13 @@ export class HandlerBasedContract<State> implements Contract<State> {
}
async save(sourceData: SourceData): Promise<any> {
if (!this.signer) {
if (!this.signature) {
throw new Error("Wallet not connected. Use 'connect' method first.");
}
const { arweave } = this.warp;
const source = new SourceImpl(arweave);
const srcTx = await source.save(sourceData, this.signer);
const srcTx = await source.save(sourceData, this.signature.signer);
return srcTx.id;
}
@@ -760,4 +781,8 @@ export class HandlerBasedContract<State> implements Contract<State> {
get rootSortKey(): string {
return this._rootSortKey;
}
private isSignatureType(signature: ArWallet | Signature): signature is Signature {
return (signature as Signature).signer !== undefined;
}
}

View File

@@ -16,5 +16,6 @@ export enum SmartWeaveTags {
WASM_LANG = 'Wasm-Lang',
WASM_LANG_VERSION = 'Wasm-Lang-Version',
WASM_META = 'Wasm-Meta',
REQUEST_VRF = 'Request-Vrf'
REQUEST_VRF = 'Request-Vrf',
SIGNATURE_TYPE = 'Signature-Type'
}

View File

@@ -15,6 +15,7 @@ import { HandlerApi } from './modules/impl/HandlerExecutorFactory';
import { InteractionsLoader } from './modules/InteractionsLoader';
import { EvalStateResult, StateEvaluator } from './modules/StateEvaluator';
import { WarpBuilder } from './WarpBuilder';
import { WarpPluginType, WarpPlugin, knownWarpPlugins } from './WarpPlugin';
export type WarpEnvironment = 'local' | 'testnet' | 'mainnet' | 'custom';
@@ -31,6 +32,8 @@ export class Warp {
readonly migrationTool: MigrationTool;
readonly testing: Testing;
private readonly plugins: Map<WarpPluginType, WarpPlugin<unknown, unknown>> = new Map();
constructor(
readonly arweave: Arweave,
readonly levelDb: LevelDbCache<EvalStateResult<unknown>>,
@@ -69,4 +72,26 @@ export class Warp {
pst(contractTxId: string): PstContract {
return new PstContractImpl(contractTxId, this);
}
use(plugin: WarpPlugin<unknown, unknown>): Warp {
const pluginType = plugin.type();
if (!knownWarpPlugins.some((p) => p == pluginType)) {
throw new Error(`Unknown plugin type ${pluginType}.`);
}
this.plugins.set(pluginType, plugin);
return this;
}
hasPlugin(type: WarpPluginType): boolean {
return this.plugins.has(type);
}
loadPlugin<P, Q>(type: WarpPluginType): WarpPlugin<P, Q> {
if (!this.hasPlugin(type)) {
throw new Error(`Plugin ${type} not registered.`);
}
return this.plugins.get(type) as WarpPlugin<P, Q>;
}
}

8
src/core/WarpPlugin.ts Normal file
View File

@@ -0,0 +1,8 @@
export const knownWarpPlugins = ['evm-signature-verification'] as const;
export type WarpPluginType = typeof knownWarpPlugins[number];
export interface WarpPlugin<T, R> {
type(): WarpPluginType;
process(input: T): R;
}

View File

@@ -121,8 +121,6 @@ export class DefaultEvaluationOptions implements EvaluationOptions {
gasLimit = Number.MAX_SAFE_INTEGER;
useFastCopy = true;
useVM2 = false;
allowUnsafeClient = false;
@@ -182,12 +180,6 @@ export interface EvaluationOptions {
gasLimit: number;
// Whether fast-copy library should be used during the state evaluation
// https://github.com/planttheidea/fast-copy#isstrict
// it's much faster (e.g. almost twice for the SJ3l7474UHh3Dw6dWVT1bzsJ-8JvOewtGoDdOecWIZo contract)
// currently defaults to true
useFastCopy: boolean;
// Whether js contracts' code should be run within vm2 sandbox (https://github.com/patriksimek/vm2#vm2-----)
// it greatly enhances security - at a cost of performance.
// use for contracts that you cannot trust.

View File

@@ -1,7 +1,6 @@
import Arweave from 'arweave';
import Transaction from 'arweave/web/lib/transaction';
import Transaction from 'arweave/node/lib/transaction';
import { ContractType } from '../../../contract/deploy/CreateContract';
import { WarpCache } from '../../../cache/WarpCache';
import { ContractDefinition, ContractSource } from '../../../core/ContractDefinition';
import { SmartWeaveTags } from '../../../core/SmartWeaveTags';
import { getTag } from '../../../legacy/utils';

View File

@@ -7,12 +7,12 @@ import { CurrentTx } from '../../../contract/Contract';
import { InteractionCall } from '../../ContractCallRecord';
import { ExecutionContext } from '../../../core/ExecutionContext';
import { ExecutionContextModifier } from '../../../core/ExecutionContextModifier';
import { GQLNodeInterface, VrfData, GQLTagInterface } from '../../../legacy/gqlResult';
import { GQLNodeInterface, GQLTagInterface, VrfData } from '../../../legacy/gqlResult';
import { Benchmark } from '../../../logging/Benchmark';
import { LoggerFactory } from '../../../logging/LoggerFactory';
import { indent } from '../../../utils/utils';
import { StateEvaluator, EvalStateResult } from '../StateEvaluator';
import { HandlerApi, ContractInteraction, InteractionResult } from './HandlerExecutorFactory';
import { EvalStateResult, StateEvaluator } from '../StateEvaluator';
import { ContractInteraction, HandlerApi, InteractionResult } from './HandlerExecutorFactory';
import { canBeCached } from './StateCache';
import { TagsParser } from './TagsParser';
@@ -54,7 +54,7 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
currentTx: CurrentTx[]
): Promise<SortKeyCacheResult<EvalStateResult<State>>> {
const { ignoreExceptions, stackTrace, internalWrites } = executionContext.evaluationOptions;
const { contract, contractDefinition, sortedInteractions } = executionContext;
const { contract, contractDefinition, sortedInteractions, warp } = executionContext;
let currentState = baseState.state;
let currentSortKey = null;
@@ -77,6 +77,10 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
const missingInteractionsLength = missingInteractions.length;
executionContext.handler.initState(currentState);
const evmSignatureVerificationPlugin = warp.hasPlugin('evm-signature-verification')
? warp.loadPlugin<GQLNodeInterface, Promise<boolean>>('evm-signature-verification')
: null;
for (let i = 0; i < missingInteractionsLength; i++) {
const missingInteraction = missingInteractions[i];
const singleInteractionBenchmark = Benchmark.measure();
@@ -88,6 +92,18 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
}
}
if (evmSignatureVerificationPlugin && this.tagsParser.isEvmSigned(missingInteraction)) {
try {
if (!(await evmSignatureVerificationPlugin.process(missingInteraction))) {
this.logger.warn(`Interaction ${missingInteraction.id} was not verified, skipping.`);
continue;
}
} catch (e) {
this.logger.error(e);
continue;
}
}
this.logger.debug(
`${indent(depth)}[${contractDefinition.txId}][${missingInteraction.id}][${missingInteraction.block.height}]: ${
missingInteractions.indexOf(missingInteraction) + 1

View File

@@ -3,7 +3,6 @@ import loader from '@assemblyscript/loader';
import { asWasmImports } from './wasm/as-wasm-imports';
import { rustWasmImports } from './wasm/rust-wasm-imports';
import { Go } from './wasm/go-wasm-imports';
import BigNumber from 'bignumber.js';
import * as vm2 from 'vm2';
import { WarpCache } from '../../../cache/WarpCache';
import { ContractDefinition } from '../../../core/ContractDefinition';
@@ -18,6 +17,7 @@ import { JsHandlerApi } from './handler/JsHandlerApi';
import { WasmHandlerApi } from './handler/WasmHandlerApi';
import { normalizeContractSource } from './normalize-source';
import { MemCache } from '../../../cache/impl/MemCache';
import BigNumber from '../../../legacy/bignumber';
class ContractError extends Error {
constructor(message) {

View File

@@ -69,6 +69,12 @@ export class TagsParser {
return result;
}
isEvmSigned(interactionTransaction: GQLNodeInterface): boolean {
return interactionTransaction.tags.some(
(tag) => tag.name === SmartWeaveTags.SIGNATURE_TYPE && tag.value === 'ethereum'
);
}
static hasMultipleInteractions(interactionTransaction: GQLNodeInterface): boolean {
return interactionTransaction.tags.filter((tag) => tag.name === SmartWeaveTags.CONTRACT_TX_ID).length > 1;
}

View File

@@ -11,7 +11,6 @@ import { LoggerFactory } from '../../../logging/LoggerFactory';
import { ArweaveWrapper } from '../../../utils/ArweaveWrapper';
import { stripTrailingSlash } from '../../../utils/utils';
import { DefinitionLoader } from '../DefinitionLoader';
import { WarpCache } from '../../../cache/WarpCache';
import { WasmSrc } from './wasm/WasmSrc';
import { CacheOptions } from '../../WarpFactory';
import { MemoryLevel } from 'memory-level';

View File

@@ -28,7 +28,7 @@ export class JsHandlerApi<State> extends AbstractContractHandler<State> {
try {
const { interaction, interactionTx, currentTx } = interactionData;
const stateCopy = deepCopy(currentResult.state, executionContext.evaluationOptions.useFastCopy);
const stateCopy = deepCopy(currentResult.state);
this.swGlobal._activeTx = interactionTx;
this.swGlobal.caller = interaction.caller; // either contract tx id (for internal writes) or transaction.owner
this.assignReadContractState<Input>(executionContext, currentTx, currentResult, interactionTx);

2927
src/legacy/bignumber.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,4 @@
/* eslint-disable */
import cloneDeep from 'lodash/cloneDeep';
import copy from 'fast-copy';
import { Buffer } from 'redstone-isomorphic';
import { randomUUID } from 'crypto';
@@ -8,8 +7,8 @@ export const sleep = (ms: number): Promise<void> => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
export const deepCopy = (input: unknown, useFastCopy = false): any => {
return useFastCopy ? copy(input) : cloneDeep(input);
export const deepCopy = (input: unknown): any => {
return copy(input);
};
export const mapReplacer = (key: unknown, value: unknown) => {

View File

@@ -1,11 +1,13 @@
/* eslint-disable */
import Arweave from 'arweave';
import {defaultCacheOptions, LoggerFactory, WarpFactory} from '../src';
import {defaultCacheOptions, LexicographicalInteractionsSorter, LoggerFactory, WarpFactory} from '../src';
import * as fs from 'fs';
import knex from 'knex';
import os from 'os';
import path from "path";
import stringify from "safe-stable-stringify";
import {WarpPlugin, WarpPluginType} from "../src/core/WarpPlugin";
import {GQLNodeInterface} from "smartweave/lib/interfaces/gqlResult";
const logger = LoggerFactory.INST.create('Contract');
@@ -31,7 +33,20 @@ async function main() {
logging: false // Enable network request logging
});
const warp = WarpFactory.forMainnet({...defaultCacheOptions, inMemory: true});
class ExamplePlugin implements WarpPlugin<GQLNodeInterface, boolean> {
process(input: GQLNodeInterface): boolean {
return false;
}
type(): WarpPluginType {
return 'evm-signature-verification';
}
}
const warp = WarpFactory
.forMainnet({...defaultCacheOptions, inMemory: true})
.use(new ExamplePlugin())
try {
const contract = warp.contract("Ws9hhYckc-zSnVmbBep6q_kZD5zmzYzDmgMC50nMiuE");
const cacheResult = await contract
@@ -84,6 +99,11 @@ function printTestInfo() {
console.log(' ', 'CPU ', cpus);
console.log(' ', 'Memory ', (os.totalmem() / 1024 / 1024 / 1024).toFixed(0), 'GB');
console.log('===============');
const sorter = new LexicographicalInteractionsSorter(arweave);
warp.interactionsLoader.load(contractId, sorter.generateLastSortKey(666), sorter.generateLastSortKey(777));
}
main().catch((e) => console.error(e));

View File

@@ -66,12 +66,18 @@ async function main() {
});*/
const contract = warp.contract(contractTxId)
/*.setEvaluationOptions({
bundlerUrl: "http://13.53.39.138:5666/"
})*/
.setEvaluationOptions({
bundlerUrl: "http://localhost:5666/"
})
.connect(wallet);
await contract.writeInteraction<any>({
function: "transfer",
target: "M-mpNeJbg9h7mZ-uHaNsa5jwFFRAq0PsTkNWXJ-ojwI",
qty: 10000
}, {tags: [{name: 'Signature-Type', value: 'ethereum'}]});
/*await contract.writeInteraction<any>({
function: "storeBalance",
target: "M-mpNeJbg9h7mZ-uHaNsa5jwFFRAq0PsTkNWXJ-ojwI",
});
@@ -79,12 +85,7 @@ async function main() {
await contract.writeInteraction<any>({
function: "storeBalance",
target: "M-mpNeJbg9h7mZ-uHaNsa5jwFFRAq0PsTkNWXJ-ojwI",
});
await contract.writeInteraction<any>({
function: "storeBalance",
target: "M-mpNeJbg9h7mZ-uHaNsa5jwFFRAq0PsTkNWXJ-ojwI",
});
});*/
const {cachedValue} = await contract.readState();

224
yarn.lock
View File

@@ -392,10 +392,15 @@
dependencies:
"@jridgewell/trace-mapping" "0.3.9"
"@esbuild/linux-loong64@0.15.5":
version "0.15.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.5.tgz#91aef76d332cdc7c8942b600fa2307f3387e6f82"
integrity sha512-UHkDFCfSGTuXq08oQltXxSZmH1TXyWsL+4QhZDWvvLl6mEJQqk3u7/wq1LjhrrAXYIllaTtRSzUXl4Olkf2J8A==
"@esbuild/android-arm@0.15.12":
version "0.15.12"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.12.tgz#e548b10a5e55b9e10537a049ebf0bc72c453b769"
integrity sha512-IC7TqIqiyE0MmvAhWkl/8AEzpOtbhRNDo7aph47We1NbE5w2bt/Q+giAhe0YYeVpYnIhGMcuZY92qDK6dQauvA==
"@esbuild/linux-loong64@0.15.12":
version "0.15.12"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.12.tgz#475b33a2631a3d8ca8aa95ee127f9a61d95bf9c1"
integrity sha512-tZEowDjvU7O7I04GYvWQOS4yyP9E/7YlsB0jjw1Ycukgr2ycEzKyIk5tms5WnLBymaewc6VmRKnn5IJWgK4eFw==
"@eslint/eslintrc@^0.4.3":
version "0.4.3"
@@ -3165,132 +3170,133 @@ es6-weak-map@~0.1.4:
es6-iterator "~0.1.3"
es6-symbol "~2.0.1"
esbuild-android-64@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.15.5.tgz#3c7b2f2a59017dab3f2c0356188a8dd9cbdc91c8"
integrity sha512-dYPPkiGNskvZqmIK29OPxolyY3tp+c47+Fsc2WYSOVjEPWNCHNyqhtFqQadcXMJDQt8eN0NMDukbyQgFcHquXg==
esbuild-android-64@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.15.12.tgz#5e8151d5f0a748c71a7fbea8cee844ccf008e6fc"
integrity sha512-MJKXwvPY9g0rGps0+U65HlTsM1wUs9lbjt5CU19RESqycGFDRijMDQsh68MtbzkqWSRdEtiKS1mtPzKneaAI0Q==
esbuild-android-arm64@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.5.tgz#e301db818c5a67b786bf3bb7320e414ac0fcf193"
integrity sha512-YyEkaQl08ze3cBzI/4Cm1S+rVh8HMOpCdq8B78JLbNFHhzi4NixVN93xDrHZLztlocEYqi45rHHCgA8kZFidFg==
esbuild-android-arm64@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.12.tgz#5ee72a6baa444bc96ffcb472a3ba4aba2cc80666"
integrity sha512-Hc9SEcZbIMhhLcvhr1DH+lrrec9SFTiRzfJ7EGSBZiiw994gfkVV6vG0sLWqQQ6DD7V4+OggB+Hn0IRUdDUqvA==
esbuild-darwin-64@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.5.tgz#11726de5d0bf5960b92421ef433e35871c091f8d"
integrity sha512-Cr0iIqnWKx3ZTvDUAzG0H/u9dWjLE4c2gTtRLz4pqOBGjfjqdcZSfAObFzKTInLLSmD0ZV1I/mshhPoYSBMMCQ==
esbuild-darwin-64@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.12.tgz#70047007e093fa1b3ba7ef86f9b3fa63db51fe25"
integrity sha512-qkmqrTVYPFiePt5qFjP8w/S+GIUMbt6k8qmiPraECUWfPptaPJUGkCKrWEfYFRWB7bY23FV95rhvPyh/KARP8Q==
esbuild-darwin-arm64@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.5.tgz#ad89dafebb3613fd374f5a245bb0ce4132413997"
integrity sha512-WIfQkocGtFrz7vCu44ypY5YmiFXpsxvz2xqwe688jFfSVCnUsCn2qkEVDo7gT8EpsLOz1J/OmqjExePL1dr1Kg==
esbuild-darwin-arm64@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.12.tgz#41c951f23d9a70539bcca552bae6e5196696ae04"
integrity sha512-z4zPX02tQ41kcXMyN3c/GfZpIjKoI/BzHrdKUwhC/Ki5BAhWv59A9M8H+iqaRbwpzYrYidTybBwiZAIWCLJAkw==
esbuild-freebsd-64@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.5.tgz#6bfb52b4a0d29c965aa833e04126e95173289c8a"
integrity sha512-M5/EfzV2RsMd/wqwR18CELcenZ8+fFxQAAEO7TJKDmP3knhWSbD72ILzrXFMMwshlPAS1ShCZ90jsxkm+8FlaA==
esbuild-freebsd-64@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.12.tgz#a761b5afd12bbedb7d56c612e9cfa4d2711f33f0"
integrity sha512-XFL7gKMCKXLDiAiBjhLG0XECliXaRLTZh6hsyzqUqPUf/PY4C6EJDTKIeqqPKXaVJ8+fzNek88285krSz1QECw==
esbuild-freebsd-arm64@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.5.tgz#38a3fed8c6398072f9914856c7c3e3444f9ef4dd"
integrity sha512-2JQQ5Qs9J0440F/n/aUBNvY6lTo4XP/4lt1TwDfHuo0DY3w5++anw+jTjfouLzbJmFFiwmX7SmUhMnysocx96w==
esbuild-freebsd-arm64@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.12.tgz#6b0839d4d58deabc6cbd96276eb8cbf94f7f335e"
integrity sha512-jwEIu5UCUk6TjiG1X+KQnCGISI+ILnXzIzt9yDVrhjug2fkYzlLbl0K43q96Q3KB66v6N1UFF0r5Ks4Xo7i72g==
esbuild-linux-32@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.15.5.tgz#942dc70127f0c0a7ea91111baf2806e61fc81b32"
integrity sha512-gO9vNnIN0FTUGjvTFucIXtBSr1Woymmx/aHQtuU+2OllGU6YFLs99960UD4Dib1kFovVgs59MTXwpFdVoSMZoQ==
esbuild-linux-32@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.15.12.tgz#bd50bfe22514d434d97d5150977496e2631345b4"
integrity sha512-uSQuSEyF1kVzGzuIr4XM+v7TPKxHjBnLcwv2yPyCz8riV8VUCnO/C4BF3w5dHiVpCd5Z1cebBtZJNlC4anWpwA==
esbuild-linux-64@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.15.5.tgz#6d748564492d5daaa7e62420862c31ac3a44aed9"
integrity sha512-ne0GFdNLsm4veXbTnYAWjbx3shpNKZJUd6XpNbKNUZaNllDZfYQt0/zRqOg0sc7O8GQ+PjSMv9IpIEULXVTVmg==
esbuild-linux-64@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.15.12.tgz#074bb2b194bf658245f8490f29c01ffcdfa8c931"
integrity sha512-QcgCKb7zfJxqT9o5z9ZUeGH1k8N6iX1Y7VNsEi5F9+HzN1OIx7ESxtQXDN9jbeUSPiRH1n9cw6gFT3H4qbdvcA==
esbuild-linux-arm64@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.5.tgz#28cd899beb2d2b0a3870fd44f4526835089a318d"
integrity sha512-7EgFyP2zjO065XTfdCxiXVEk+f83RQ1JsryN1X/VSX2li9rnHAt2swRbpoz5Vlrl6qjHrCmq5b6yxD13z6RheA==
esbuild-linux-arm64@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.12.tgz#3bf789c4396dc032875a122988efd6f3733f28f5"
integrity sha512-HtNq5xm8fUpZKwWKS2/YGwSfTF+339L4aIA8yphNKYJckd5hVdhfdl6GM2P3HwLSCORS++++7++//ApEwXEuAQ==
esbuild-linux-arm@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.5.tgz#6441c256225564d8794fdef5b0a69bc1a43051b5"
integrity sha512-wvAoHEN+gJ/22gnvhZnS/+2H14HyAxM07m59RSLn3iXrQsdS518jnEWRBnJz3fR6BJa+VUTo0NxYjGaNt7RA7Q==
esbuild-linux-arm@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.12.tgz#b91b5a8d470053f6c2c9c8a5e67ec10a71fe4a67"
integrity sha512-Wf7T0aNylGcLu7hBnzMvsTfEXdEdJY/hY3u36Vla21aY66xR0MS5I1Hw8nVquXjTN0A6fk/vnr32tkC/C2lb0A==
esbuild-linux-mips64le@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.5.tgz#d4927f817290eaffc062446896b2a553f0e11981"
integrity sha512-KdnSkHxWrJ6Y40ABu+ipTZeRhFtc8dowGyFsZY5prsmMSr1ZTG9zQawguN4/tunJ0wy3+kD54GaGwdcpwWAvZQ==
esbuild-linux-mips64le@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.12.tgz#2fb54099ada3c950a7536dfcba46172c61e580e2"
integrity sha512-Qol3+AvivngUZkTVFgLpb0H6DT+N5/zM3V1YgTkryPYFeUvuT5JFNDR3ZiS6LxhyF8EE+fiNtzwlPqMDqVcc6A==
esbuild-linux-ppc64le@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.5.tgz#b6d660dc6d5295f89ac51c675f1a2f639e2fb474"
integrity sha512-QdRHGeZ2ykl5P0KRmfGBZIHmqcwIsUKWmmpZTOq573jRWwmpfRmS7xOhmDHBj9pxv+6qRMH8tLr2fe+ZKQvCYw==
esbuild-linux-ppc64le@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.12.tgz#9e3b8c09825fb27886249dfb3142a750df29a1b7"
integrity sha512-4D8qUCo+CFKaR0cGXtGyVsOI7w7k93Qxb3KFXWr75An0DHamYzq8lt7TNZKoOq/Gh8c40/aKaxvcZnTgQ0TJNg==
esbuild-linux-riscv64@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.5.tgz#2801bf18414dc3d3ad58d1ea83084f00d9d84896"
integrity sha512-p+WE6RX+jNILsf+exR29DwgV6B73khEQV0qWUbzxaycxawZ8NE0wA6HnnTxbiw5f4Gx9sJDUBemh9v49lKOORA==
esbuild-linux-riscv64@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.12.tgz#923d0f5b6e12ee0d1fe116b08e4ae4478fe40693"
integrity sha512-G9w6NcuuCI6TUUxe6ka0enjZHDnSVK8bO+1qDhMOCtl7Tr78CcZilJj8SGLN00zO5iIlwNRZKHjdMpfFgNn1VA==
esbuild-linux-s390x@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.5.tgz#12a634ae6d3384cacc2b8f4201047deafe596eae"
integrity sha512-J2ngOB4cNzmqLHh6TYMM/ips8aoZIuzxJnDdWutBw5482jGXiOzsPoEF4j2WJ2mGnm7FBCO4StGcwzOgic70JQ==
esbuild-linux-s390x@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.12.tgz#3b1620220482b96266a0c6d9d471d451a1eab86f"
integrity sha512-Lt6BDnuXbXeqSlVuuUM5z18GkJAZf3ERskGZbAWjrQoi9xbEIsj/hEzVnSAFLtkfLuy2DE4RwTcX02tZFunXww==
esbuild-netbsd-64@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.5.tgz#951bbf87600512dfcfbe3b8d9d117d684d26c1b8"
integrity sha512-MmKUYGDizYjFia0Rwt8oOgmiFH7zaYlsoQ3tIOfPxOqLssAsEgG0MUdRDm5lliqjiuoog8LyDu9srQk5YwWF3w==
esbuild-netbsd-64@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.12.tgz#276730f80da646859b1af5a740e7802d8cd73e42"
integrity sha512-jlUxCiHO1dsqoURZDQts+HK100o0hXfi4t54MNRMCAqKGAV33JCVvMplLAa2FwviSojT/5ZG5HUfG3gstwAG8w==
esbuild-openbsd-64@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.5.tgz#26705b61961d525d79a772232e8b8f211fdbb035"
integrity sha512-2mMFfkLk3oPWfopA9Plj4hyhqHNuGyp5KQyTT9Rc8hFd8wAn5ZrbJg+gNcLMo2yzf8Uiu0RT6G9B15YN9WQyMA==
esbuild-openbsd-64@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.12.tgz#bd0eea1dd2ca0722ed489d88c26714034429f8ae"
integrity sha512-1o1uAfRTMIWNOmpf8v7iudND0L6zRBYSH45sofCZywrcf7NcZA+c7aFsS1YryU+yN7aRppTqdUK1PgbZVaB1Dw==
esbuild-sunos-64@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.5.tgz#d794da1ae60e6e2f6194c44d7b3c66bf66c7a141"
integrity sha512-2sIzhMUfLNoD+rdmV6AacilCHSxZIoGAU2oT7XmJ0lXcZWnCvCtObvO6D4puxX9YRE97GodciRGDLBaiC6x1SA==
esbuild-sunos-64@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.12.tgz#5e56bf9eef3b2d92360d6d29dcde7722acbecc9e"
integrity sha512-nkl251DpoWoBO9Eq9aFdoIt2yYmp4I3kvQjba3jFKlMXuqQ9A4q+JaqdkCouG3DHgAGnzshzaGu6xofGcXyPXg==
esbuild-windows-32@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.15.5.tgz#0670326903f421424be86bc03b7f7b3ff86a9db7"
integrity sha512-e+duNED9UBop7Vnlap6XKedA/53lIi12xv2ebeNS4gFmu7aKyTrok7DPIZyU5w/ftHD4MUDs5PJUkQPP9xJRzg==
esbuild-windows-32@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.15.12.tgz#a4f1a301c1a2fa7701fcd4b91ef9d2620cf293d0"
integrity sha512-WlGeBZHgPC00O08luIp5B2SP4cNCp/PcS+3Pcg31kdcJPopHxLkdCXtadLU9J82LCfw4TVls21A6lilQ9mzHrw==
esbuild-windows-64@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.15.5.tgz#64f32acb7341f3f0a4d10e8ff1998c2d1ebfc0a9"
integrity sha512-v+PjvNtSASHOjPDMIai9Yi+aP+Vwox+3WVdg2JB8N9aivJ7lyhp4NVU+J0MV2OkWFPnVO8AE/7xH+72ibUUEnw==
esbuild-windows-64@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.15.12.tgz#bc2b467541744d653be4fe64eaa9b0dbbf8e07f6"
integrity sha512-VActO3WnWZSN//xjSfbiGOSyC+wkZtI8I4KlgrTo5oHJM6z3MZZBCuFaZHd8hzf/W9KPhF0lY8OqlmWC9HO5AA==
esbuild-windows-arm64@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.5.tgz#4fe7f333ce22a922906b10233c62171673a3854b"
integrity sha512-Yz8w/D8CUPYstvVQujByu6mlf48lKmXkq6bkeSZZxTA626efQOJb26aDGLzmFWx6eg/FwrXgt6SZs9V8Pwy/aA==
esbuild-windows-arm64@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.12.tgz#9a7266404334a86be800957eaee9aef94c3df328"
integrity sha512-Of3MIacva1OK/m4zCNIvBfz8VVROBmQT+gRX6pFTLPngFYcj6TFH/12VveAqq1k9VB2l28EoVMNMUCcmsfwyuA==
esbuild@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.15.5.tgz#5effd05666f621d4ff2fe2c76a67c198292193ff"
integrity sha512-VSf6S1QVqvxfIsSKb3UKr3VhUCis7wgDbtF4Vd9z84UJr05/Sp2fRKmzC+CSPG/dNAPPJZ0BTBLTT1Fhd6N9Gg==
esbuild@0.15.12:
version "0.15.12"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.15.12.tgz#6c8e22d6d3b7430d165c33848298d3fc9a1f251c"
integrity sha512-PcT+/wyDqJQsRVhaE9uX/Oq4XLrFh0ce/bs2TJh4CSaw9xuvI+xFrH2nAYOADbhQjUgAhNWC5LKoUsakm4dxng==
optionalDependencies:
"@esbuild/linux-loong64" "0.15.5"
esbuild-android-64 "0.15.5"
esbuild-android-arm64 "0.15.5"
esbuild-darwin-64 "0.15.5"
esbuild-darwin-arm64 "0.15.5"
esbuild-freebsd-64 "0.15.5"
esbuild-freebsd-arm64 "0.15.5"
esbuild-linux-32 "0.15.5"
esbuild-linux-64 "0.15.5"
esbuild-linux-arm "0.15.5"
esbuild-linux-arm64 "0.15.5"
esbuild-linux-mips64le "0.15.5"
esbuild-linux-ppc64le "0.15.5"
esbuild-linux-riscv64 "0.15.5"
esbuild-linux-s390x "0.15.5"
esbuild-netbsd-64 "0.15.5"
esbuild-openbsd-64 "0.15.5"
esbuild-sunos-64 "0.15.5"
esbuild-windows-32 "0.15.5"
esbuild-windows-64 "0.15.5"
esbuild-windows-arm64 "0.15.5"
"@esbuild/android-arm" "0.15.12"
"@esbuild/linux-loong64" "0.15.12"
esbuild-android-64 "0.15.12"
esbuild-android-arm64 "0.15.12"
esbuild-darwin-64 "0.15.12"
esbuild-darwin-arm64 "0.15.12"
esbuild-freebsd-64 "0.15.12"
esbuild-freebsd-arm64 "0.15.12"
esbuild-linux-32 "0.15.12"
esbuild-linux-64 "0.15.12"
esbuild-linux-arm "0.15.12"
esbuild-linux-arm64 "0.15.12"
esbuild-linux-mips64le "0.15.12"
esbuild-linux-ppc64le "0.15.12"
esbuild-linux-riscv64 "0.15.12"
esbuild-linux-s390x "0.15.12"
esbuild-netbsd-64 "0.15.12"
esbuild-openbsd-64 "0.15.12"
esbuild-sunos-64 "0.15.12"
esbuild-windows-32 "0.15.12"
esbuild-windows-64 "0.15.12"
esbuild-windows-arm64 "0.15.12"
escalade@^3.1.1:
version "3.1.1"