From b3eb607c6aa8f80488515712f1a162fbf9322f35 Mon Sep 17 00:00:00 2001 From: Orlando Date: Fri, 28 Jul 2023 14:16:29 +0100 Subject: [PATCH 01/25] feat: stark sig auth --- starknet/src/authenticators/stark_sig.cairo | 116 ++++++++++++++++++++ starknet/src/utils/stark_signatures.cairo | 105 ++++++++++++++++++ 2 files changed, 221 insertions(+) create mode 100644 starknet/src/authenticators/stark_sig.cairo create mode 100644 starknet/src/utils/stark_signatures.cairo diff --git a/starknet/src/authenticators/stark_sig.cairo b/starknet/src/authenticators/stark_sig.cairo new file mode 100644 index 00000000..397dbf01 --- /dev/null +++ b/starknet/src/authenticators/stark_sig.cairo @@ -0,0 +1,116 @@ +use starknet::ContractAddress; +use starknet::SyscallResult; +use sx::utils::types::{Strategy, IndexedStrategy, Choice}; + +#[starknet::interface] +trait IStarkSigAuthenticator { + fn authenticate_propose( + ref self: TContractState, + r: felt252, + s: felt252, + target: ContractAddress, + author: ContractAddress, + execution_strategy: Strategy, + user_proposal_validation_params: Array, + salt: felt252, + ); + fn propose_hash( + self: @TContractState, + r: felt252, + s: felt252, + target: ContractAddress, + author: ContractAddress, + execution_strategy: Strategy, + user_proposal_validation_params: Array, + salt: felt252 + ) -> felt252; + fn encoded_strategy( + self: @TContractState, + r: felt252, + s: felt252, + target: ContractAddress, + author: ContractAddress, + execution_strategy: Strategy, + user_proposal_validation_params: Array, + salt: felt252, + ) -> Array; +} + +#[starknet::contract] +mod StarkSigAuthenticator { + use super::IStarkSigAuthenticator; + use starknet::ContractAddress; + use starknet::syscalls::call_contract_syscall; + use core::array::{ArrayTrait, SpanTrait}; + use clone::Clone; + use serde::Serde; + use sx::space::space::{ISpaceDispatcher, ISpaceDispatcherTrait}; + use sx::utils::types::{Strategy, IndexedStrategy, Choice}; + use sx::utils::stark_signatures; + + #[storage] + struct Storage { + _domain_hash: felt252, + _used_salts: LegacyMap::<(ContractAddress, felt252), bool> + } + + #[external(v0)] + impl StarkSigAuthenticator of IStarkSigAuthenticator { + fn authenticate_propose( + ref self: ContractState, + r: felt252, + s: felt252, + target: ContractAddress, + author: ContractAddress, + execution_strategy: Strategy, + user_proposal_validation_params: Array, + salt: felt252, + ) { + let msg_hash = stark_signatures::get_propose_digest( + target, author, execution_strategy, user_proposal_validation_params, salt + ); + // self._used_salts.write((author, salt), true); + + // ISpaceDispatcher { + // contract_address: target + // }.propose(author, execution_strategy, user_proposal_validation_params); + } + + fn propose_hash( + self: @ContractState, + r: felt252, + s: felt252, + target: ContractAddress, + author: ContractAddress, + execution_strategy: Strategy, + user_proposal_validation_params: Array, + salt: felt252, + ) -> felt252 { + stark_signatures::get_propose_digest( + target, author, execution_strategy, user_proposal_validation_params, salt + ) + } + + fn encoded_strategy( + self: @ContractState, + r: felt252, + s: felt252, + target: ContractAddress, + author: ContractAddress, + execution_strategy: Strategy, + user_proposal_validation_params: Array, + salt: felt252, + ) -> Array { + let mut encoded_data = ArrayTrait::::new(); + 0x14c6b221e639b0d611fd0aab18c0c1e29079e17e0445bebd85b5cad1aaaee2b.serialize(ref encoded_data); + execution_strategy.address.serialize(ref encoded_data); + execution_strategy.params.serialize(ref encoded_data); + encoded_data + } + + } +// #[constructor] +// fn constructor(ref self: ContractState, name: felt252, version: felt252) {// TODO: domain hash is immutable so could be placed in the contract code instead of storage to save on reads. +// // self._domain_hash.write(signatures::get_domain_hash(name, version)); +// } +} diff --git a/starknet/src/utils/stark_signatures.cairo b/starknet/src/utils/stark_signatures.cairo new file mode 100644 index 00000000..a9362a0c --- /dev/null +++ b/starknet/src/utils/stark_signatures.cairo @@ -0,0 +1,105 @@ +use starknet::{ContractAddress, contract_address_to_felt252}; +use array::{ArrayTrait, SpanTrait}; +use traits::Into; +use clone::Clone; +use serde::Serde; +use starknet::secp256k1; +use hash::LegacyHash; +use integer::u256_from_felt252; +use sx::utils::types::{Strategy, IndexedStrategy, Choice, Felt252ArrayIntoU256Array}; +use sx::utils::math::pow; +use sx::utils::constants::{STARKNET_MESSAGE, DOMAIN_HASH, STRATEGY_TYPEHASH, PROPOSE_TYPEHASH}; + +impl LegacyHashSpanFelt252 of LegacyHash> { + fn hash(state: felt252, mut value: Span) -> felt252 { + let mut call_data_state: felt252 = 0; + loop { + match value.pop_front() { + Option::Some(item) => { + call_data_state = LegacyHash::hash(call_data_state, *item); + }, + Option::None(_) => { + break call_data_state; + }, + }; + } + } +} + +trait StructHash { + fn struct_hash(self: @T) -> felt252; +} + +impl StructHashSpanFelt252 of StructHash> { + fn struct_hash(self: @Span) -> felt252 { + let mut call_data_state = LegacyHash::hash(0, *self); + call_data_state = LegacyHash::hash(call_data_state, (*self).len()); + call_data_state + } +} + +impl StructHashStrategy of StructHash { + fn struct_hash(self: @Strategy) -> felt252 { + let mut call_data_state = LegacyHash::hash(0, STRATEGY_TYPEHASH); + call_data_state = LegacyHash::::hash(call_data_state, (*self.address).into()); + call_data_state = LegacyHash::hash(call_data_state, self.params.span().struct_hash()); + call_data_state + } +} + +impl LegacyHashStrategy of LegacyHash { + fn hash(state: felt252, value: Strategy) -> felt252 { + let state = LegacyHash::::hash(state, value.address.into()); + LegacyHash::hash(state, value.params.span()) + } +} + +// Reverts if the signature was not signed by the author. +fn verify_propose_sig( + r: felt252, + s: felt252, + target: ContractAddress, + author: ContractAddress, + execution_strategy: Strategy, + user_proposal_validation_params: Array, + salt: felt252, +) { + let digest: felt252 = get_propose_digest( + target, author, execution_strategy, user_proposal_validation_params, salt + ); +// TODO: Actually verify the signature when it gets added +// secp256k1::verify_eth_signature(digest, r, s, v, author); +} + +fn get_propose_digest( + space: ContractAddress, + author: ContractAddress, + execution_strategy: Strategy, + user_proposal_validation_params: Array, + salt: felt252 +) -> felt252 { + // let mut encoded_data = ArrayTrait::::new(); + // PROPOSE_TYPEHASH.serialize(ref encoded_data); + // space.serialize(ref encoded_data); + // author.serialize(ref encoded_data); + // // TODO: proper typehashes for below + // LegacyHash::hash(0, execution_strategy).serialize(ref encoded_data); + // LegacyHash::hash(0, user_proposal_validation_params.span()).serialize(ref encoded_data); + // salt.serialize(ref encoded_data); + // let message_hash = LegacyHash::hash(0, encoded_data.span()); + // hash_typed_data(message_hash) + + // let mut encoded_data = ArrayTrait::::new(); + // STRATEGY_TYPEHASH.serialize(ref encoded_data); + // execution_strategy.serialize(ref encoded_data); + // LegacyHash::hash(0, encoded_data.span()) + execution_strategy.params.span().struct_hash() +} + +fn hash_typed_data(message_hash: felt252) -> felt252 { + let mut encoded_data = ArrayTrait::::new(); + STARKNET_MESSAGE.serialize(ref encoded_data); + DOMAIN_HASH.serialize(ref encoded_data); + message_hash.serialize(ref encoded_data); + LegacyHash::hash(0, encoded_data.span()) +} From 818bf4462deaceb3a622e1f6ddbfa352ff6c017f Mon Sep 17 00:00:00 2001 From: Orlando Date: Fri, 28 Jul 2023 14:17:15 +0100 Subject: [PATCH 02/25] chore: test stark sig auth --- package.json | 10 +- starknet/Scarb.toml | 3 +- starknet/src/authenticators.cairo | 2 + starknet/src/utils.cairo | 1 + starknet/src/utils/constants.cairo | 8 + starknet/tests/deploy-stark-sig-auth.ts | 32 ++++ starknet/tests/stark-sig.ts | 92 ++++++++++ starknet/tests/types.ts | 37 ++++ tsconfig.json | 13 ++ yarn.lock | 213 ++++++++++++++++++++++++ 10 files changed, 409 insertions(+), 2 deletions(-) create mode 100644 starknet/tests/deploy-stark-sig-auth.ts create mode 100644 starknet/tests/stark-sig.ts create mode 100644 starknet/tests/types.ts create mode 100644 tsconfig.json diff --git a/package.json b/package.json index 2c141701..bd1cbefb 100644 --- a/package.json +++ b/package.json @@ -4,5 +4,13 @@ "description": "Cairo 1 implementation of the Snapshot X Protocol", "repository": "https://github.com/snapshot-labs/sx-starknet-2.git", "author": "Snapshot Labs", - "license": "MIT" + "license": "MIT", + "devDependencies": { + "@types/node": "^20.4.5", + "dotenv": "^16.3.1", + "fs": "^0.0.1-security", + "starknet": "^5.14.1", + "ts-node": "^10.9.1", + "typescript": "^5.1.6" + } } diff --git a/starknet/Scarb.toml b/starknet/Scarb.toml index b40cba06..6805c0ad 100644 --- a/starknet/Scarb.toml +++ b/starknet/Scarb.toml @@ -5,7 +5,8 @@ version = "0.1.0" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest [[target.starknet-contract]] -allowed-libfuncs-list.name = "all" +allowed-libfuncs-list.name = "audited" +casm = true [dependencies] starknet = ">=2.1.0-rc1" diff --git a/starknet/src/authenticators.cairo b/starknet/src/authenticators.cairo index 3b2fa347..3e25148c 100644 --- a/starknet/src/authenticators.cairo +++ b/starknet/src/authenticators.cairo @@ -3,3 +3,5 @@ mod vanilla; mod eth_tx; mod eth_sig; + +mod stark_sig; diff --git a/starknet/src/utils.cairo b/starknet/src/utils.cairo index b2717f7e..0a807f15 100644 --- a/starknet/src/utils.cairo +++ b/starknet/src/utils.cairo @@ -14,3 +14,4 @@ mod single_slot_proof; mod signatures; +mod stark_signatures; diff --git a/starknet/src/utils/constants.cairo b/starknet/src/utils/constants.cairo index aa119ed5..d1f6ee7a 100644 --- a/starknet/src/utils/constants.cairo +++ b/starknet/src/utils/constants.cairo @@ -42,3 +42,11 @@ const STRATEGY_TYPEHASH_LOW: u128 = 0x78d5506febfdb18580ea361801747e63; // keccak256("IndexedStrategy(uint256 index,uint8[] params)") const INDEXED_STRATEGY_TYPEHASH_HIGH: u128 = 0x894665428ec742c74109dc21d320d1ab; const INDEXED_STRATEGY_TYPEHASH_LOW: u128 = 0x8b36195eec0090e913c01e7534729c74; + + +// ------ Stark Sig Constants ------ + +const STARKNET_MESSAGE: felt252 = 0x537461726b4e6574204d657373616765; +const DOMAIN_HASH: felt252 = 0x133d0430d262d06e2d4aff2851ca256738e40d43593c998ff664b5d5cb410d3; +const PROPOSE_TYPEHASH: felt252 = 0x2e1c0f94a230342f46b462fd4d3bd306f935317123fb9985b08496e8f4f4183; +const STRATEGY_TYPEHASH: felt252 = 0x14c6b221e639b0d611fd0aab18c0c1e29079e17e0445bebd85b5cad1aaaee2b; \ No newline at end of file diff --git a/starknet/tests/deploy-stark-sig-auth.ts b/starknet/tests/deploy-stark-sig-auth.ts new file mode 100644 index 00000000..711d8e14 --- /dev/null +++ b/starknet/tests/deploy-stark-sig-auth.ts @@ -0,0 +1,32 @@ +import fs from "fs"; +import dotenv from 'dotenv'; +import { Account, json, Provider, CallData, Calldata } from "starknet"; + +dotenv.config(); + +const pk = process.env.PRIVATE_KEY || ''; + +async function main() { + // connect provider + const provider = new Provider({ sequencer: { baseUrl:"http://127.0.0.1:5050"} }); + console.log('provider=', provider); + // new Open Zeppelin account v0.5.1 : + // Generate public and private key pair. + const privateKey0 = "0xe3e70682c2094cac629f6fbed82c07cd"; + const address0 = "0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a"; + const account0 = new Account(provider, address0, privateKey0); + + // Declare & deploy Test contract in devnet + const compiledContractSierra = json.parse(fs.readFileSync( "starknet/target/dev/sx_StarkSigAuthenticator.sierra.json").toString( "ascii")); + const compiledContractCasm = json.parse(fs.readFileSync( "starknet/target/dev/sx_StarkSigAuthenticator.casm.json").toString( "ascii")); + + const deployResponse = await account0.declareAndDeploy({ contract: compiledContractSierra, casm: compiledContractCasm}); + console.log('deployResponse=', deployResponse); +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); \ No newline at end of file diff --git a/starknet/tests/stark-sig.ts b/starknet/tests/stark-sig.ts new file mode 100644 index 00000000..cfb29f00 --- /dev/null +++ b/starknet/tests/stark-sig.ts @@ -0,0 +1,92 @@ +import fs from "fs"; +import dotenv from 'dotenv'; +import { Provider, Account, Contract, CallData, Calldata, typedData, cairo} from "starknet"; +import { typedDataPropose } from "./types"; + +dotenv.config(); + +const pk = process.env.PRIVATE_KEY || ''; + +async function main() { + const p = new Provider(); + console.log(p); + // // connect provider + // const provider = new Provider({ sequencer: { baseUrl:"http://127.0.0.1:5050"} }); + // // new Open Zeppelin account v0.5.1 : + // // Generate public and private key pair. + // const privateKey0 = "0xe3e70682c2094cac629f6fbed82c07cd"; + // const address0 = "0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a"; + // const account0 = new Account(provider, address0, privateKey0); + + // const starkSigAuthAddress = "0x391ed8d6795fbb5f3ffb6994bcaa95e9b34dc6489e658c6d7fc86817bf4fe54"; + + // const {abi: starkSigAuthAbi} = await provider.getClassAt(starkSigAuthAddress); + // const starkSigAuth = new Contract(starkSigAuthAbi, starkSigAuthAddress, provider); + + // const msgHash = typedData.getMessageHash(typedDataPropose, address0); + + // console.log('msgHash=', msgHash); + + // const signature2 = await account0.signMessage(typedDataPropose); + + // console.log('signature2=', signature2); + + // // console.log(starkSigAuth.abi[2]); + // const specialParameters: Calldata = CallData.compile({ + // r: 1, + // s: 2, + // target: "0x0000000000000000000000000000000000007777", + // author: address0, + // execution_strategy: { + // addr: "0x0000000000000000000000000000000000001234", + // params: [5,6,7,8] + // }, + // user_proposal_validation_params: [1,2,3,4], + // salt: 0 + // }); + + // // console.log(specialParameters); + + // const out = await starkSigAuth.call("propose_hash", specialParameters, {parseResponse: false}); + + // console.log('out=', out); + + + // // const result = await account0.execute({ + // // contractAddress: starkSigAuthAddress, + // // entrypoint: "propose_hash", + // // calldata: CallData.compile({ + // // r: 1, + // // s: 2, + // // target: "0x0000000000000000000000000000000000001235", + // // author: address0, + // // execution_strategy: { + // // addr: "0x0000000000000000000000000000000000001234", + // // params: [1,2,3,4] + // // }, + // // user_proposal_validation_params: [1,2,3,4], + // // salt: 0 + // // }) + // // }) + // // console.log(result); + + + // // const proposeMessage: Propose = { + // // space: "0x0000000000000000000000000000000000001234", + // // author: signer.address, + // // executionStrategy: { + // // addr: "0x0000000000000000000000000000000000001234", + // // params: "0x1234" + // // }, + // // userProposalValidationParams: "0x1234", + // // salt: "0x0" + // // } + +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); \ No newline at end of file diff --git a/starknet/tests/types.ts b/starknet/tests/types.ts new file mode 100644 index 00000000..e3883549 --- /dev/null +++ b/starknet/tests/types.ts @@ -0,0 +1,37 @@ +import { TypedData } from "starknet"; +export const typedDataPropose: TypedData = { + types: { + StarkNetDomain: [ + { name: "name", type: "felt252" }, + { name: "version", type: "felt252" }, + { name: "chainId", type: "felt252" }, + ], + Strategy: [ + { name: "address", type: "felt252" }, + { name: "params", type: "felt*" } + ], + Propose: [ + { name: 'space', type: 'ContractAddress' }, + { name: 'author', type: 'ContractAddress' }, + { name: 'executionStrategy', type: 'Strategy' }, + { name: 'userProposalValidationParams', type: 'Array' }, + { name: 'salt', type: 'felt252' } + ] + }, + primaryType: "Propose", + domain: { + name: "1", // put the name of your dapp to ensure that the signatures will not be used by other DAPP + version: "1", + chainId: "0x534e5f474f45524c49" // devnet id + }, + message: { + space: "0x0000000000000000000000000000000000007777", + author: "0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a", + executionStrategy: { + address: "0x0000000000000000000000000000000000001234", + params: ["0x5", "0x6", "0x7", "0x8"] + }, + userProposalValidationParams: "0x1234", + salt: "0x0" + }, +}; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..c6620060 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "esModuleInterop": true, + "module": "commonjs", + "outDir": "dist", + "resolveJsonModule": true, + "strict": true, + "target": "es5" + }, + "include": [ + "./starknet/tests" + ] +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index fb57ccd1..acb6c1e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,3 +2,216 @@ # yarn lockfile v1 +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@noble/curves@~1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.0.0.tgz#e40be8c7daf088aaf291887cbc73f43464a92932" + integrity sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw== + dependencies: + "@noble/hashes" "1.3.0" + +"@noble/hashes@1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1" + integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg== + +"@noble/hashes@~1.3.0": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" + integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== + +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + +"@types/node@^20.4.5": + version "20.4.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.5.tgz#9dc0a5cb1ccce4f7a731660935ab70b9c00a5d69" + integrity sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg== + +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^8.4.1: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +dotenv@^16.3.1: + version "16.3.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" + integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== + +fs@^0.0.1-security: + version "0.0.1-security" + resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.1-security.tgz#8a7bd37186b6dddf3813f23858b57ecaaf5e41d4" + integrity sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w== + +isomorphic-fetch@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4" + integrity sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA== + dependencies: + node-fetch "^2.6.1" + whatwg-fetch "^3.4.1" + +lossless-json@^2.0.8: + version "2.0.11" + resolved "https://registry.yarnpkg.com/lossless-json/-/lossless-json-2.0.11.tgz#3137684c93fd99481c6f99c985efc9c9c5cc76a5" + integrity sha512-BP0vn+NGYvzDielvBZaFain/wgeJ1hTvURCqtKvhr1SCPePdaaTanmmcplrHfEJSJOUql7hk4FHwToNJjWRY3g== + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +micro-starknet@~0.2.1: + version "0.2.3" + resolved "https://registry.yarnpkg.com/micro-starknet/-/micro-starknet-0.2.3.tgz#ff4e7caf599255d2110e9c57bb483dfaf493ccb3" + integrity sha512-6XBcC+GerlwJSR4iA0VaeXtS2wrayWFcA4PEzrJPMuFmWCaUtuGIq5K/DB5F/XgnL54/zl2Bxo690Lj7mYVA8A== + dependencies: + "@noble/curves" "~1.0.0" + "@noble/hashes" "~1.3.0" + +node-fetch@^2.6.1: + version "2.6.12" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.12.tgz#02eb8e22074018e3d5a83016649d04df0e348fba" + integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g== + dependencies: + whatwg-url "^5.0.0" + +pako@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== + +starknet@^5.14.1: + version "5.14.1" + resolved "https://registry.yarnpkg.com/starknet/-/starknet-5.14.1.tgz#97fa5f99c4c24e42ffa315cfda525461d09d6087" + integrity sha512-EtJwQ6RmFsqSLGuMP+PRp4DwNsMYXy63HDnd1plLCdQKl3FMYajqNKf5RbDl03uGU0uE5ctGp+OW3firHuv6IA== + dependencies: + "@noble/curves" "~1.0.0" + isomorphic-fetch "^3.0.0" + lossless-json "^2.0.8" + micro-starknet "~0.2.1" + pako "^2.0.4" + url-join "^4.0.1" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +ts-node@^10.9.1: + version "10.9.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + +typescript@^5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== + +url-join@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" + integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA== + +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-fetch@^3.4.1: + version "3.6.17" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.17.tgz#009bbbfc122b227b74ba1ff31536b3a1a0e0e212" + integrity sha512-c4ghIvG6th0eudYwKZY5keb81wtFz9/WeAHAoy8+r18kcWlitUIrmGFQ2rWEl4UCKUilD3zCLHOIPheHx5ypRQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== From 26f37068d8022c67823066986234db090e2f56f7 Mon Sep 17 00:00:00 2001 From: Orlando Date: Fri, 28 Jul 2023 23:19:31 +0100 Subject: [PATCH 03/25] feat: propose digest --- starknet/src/authenticators/stark_sig.cairo | 28 ------------- starknet/src/utils/constants.cairo | 5 ++- starknet/src/utils/stark_signatures.cairo | 45 ++++++++------------- 3 files changed, 19 insertions(+), 59 deletions(-) diff --git a/starknet/src/authenticators/stark_sig.cairo b/starknet/src/authenticators/stark_sig.cairo index 397dbf01..ddf56f1e 100644 --- a/starknet/src/authenticators/stark_sig.cairo +++ b/starknet/src/authenticators/stark_sig.cairo @@ -24,16 +24,6 @@ trait IStarkSigAuthenticator { user_proposal_validation_params: Array, salt: felt252 ) -> felt252; - fn encoded_strategy( - self: @TContractState, - r: felt252, - s: felt252, - target: ContractAddress, - author: ContractAddress, - execution_strategy: Strategy, - user_proposal_validation_params: Array, - salt: felt252, - ) -> Array; } #[starknet::contract] @@ -90,24 +80,6 @@ mod StarkSigAuthenticator { target, author, execution_strategy, user_proposal_validation_params, salt ) } - - fn encoded_strategy( - self: @ContractState, - r: felt252, - s: felt252, - target: ContractAddress, - author: ContractAddress, - execution_strategy: Strategy, - user_proposal_validation_params: Array, - salt: felt252, - ) -> Array { - let mut encoded_data = ArrayTrait::::new(); - 0x14c6b221e639b0d611fd0aab18c0c1e29079e17e0445bebd85b5cad1aaaee2b.serialize(ref encoded_data); - execution_strategy.address.serialize(ref encoded_data); - execution_strategy.params.serialize(ref encoded_data); - encoded_data - } - } // #[constructor] // fn constructor(ref self: ContractState, name: felt252, version: felt252) {// TODO: domain hash is immutable so could be placed in the contract code instead of storage to save on reads. diff --git a/starknet/src/utils/constants.cairo b/starknet/src/utils/constants.cairo index d1f6ee7a..a652222b 100644 --- a/starknet/src/utils/constants.cairo +++ b/starknet/src/utils/constants.cairo @@ -48,5 +48,6 @@ const INDEXED_STRATEGY_TYPEHASH_LOW: u128 = 0x8b36195eec0090e913c01e7534729c74; const STARKNET_MESSAGE: felt252 = 0x537461726b4e6574204d657373616765; const DOMAIN_HASH: felt252 = 0x133d0430d262d06e2d4aff2851ca256738e40d43593c998ff664b5d5cb410d3; -const PROPOSE_TYPEHASH: felt252 = 0x2e1c0f94a230342f46b462fd4d3bd306f935317123fb9985b08496e8f4f4183; -const STRATEGY_TYPEHASH: felt252 = 0x14c6b221e639b0d611fd0aab18c0c1e29079e17e0445bebd85b5cad1aaaee2b; \ No newline at end of file +const PROPOSE_TYPEHASH: felt252 = 0x1f8c9b1ab74c5990f89bac4c632dc405457352e22bbc7573a237989aa62cb60; +const STRATEGY_TYPEHASH: felt252 = + 0x39154ec0efadcd0deffdfc2044cf45dd986d260e59c26d69564b50a18f40f6b; diff --git a/starknet/src/utils/stark_signatures.cairo b/starknet/src/utils/stark_signatures.cairo index a9362a0c..aa975f85 100644 --- a/starknet/src/utils/stark_signatures.cairo +++ b/starknet/src/utils/stark_signatures.cairo @@ -40,17 +40,11 @@ impl StructHashSpanFelt252 of StructHash> { impl StructHashStrategy of StructHash { fn struct_hash(self: @Strategy) -> felt252 { - let mut call_data_state = LegacyHash::hash(0, STRATEGY_TYPEHASH); - call_data_state = LegacyHash::::hash(call_data_state, (*self.address).into()); - call_data_state = LegacyHash::hash(call_data_state, self.params.span().struct_hash()); - call_data_state - } -} - -impl LegacyHashStrategy of LegacyHash { - fn hash(state: felt252, value: Strategy) -> felt252 { - let state = LegacyHash::::hash(state, value.address.into()); - LegacyHash::hash(state, value.params.span()) + let mut encoded_data = ArrayTrait::::new(); + STRATEGY_TYPEHASH.serialize(ref encoded_data); + (*self.address).serialize(ref encoded_data); + self.params.span().struct_hash().serialize(ref encoded_data); + encoded_data.span().struct_hash() } } @@ -78,28 +72,21 @@ fn get_propose_digest( user_proposal_validation_params: Array, salt: felt252 ) -> felt252 { - // let mut encoded_data = ArrayTrait::::new(); - // PROPOSE_TYPEHASH.serialize(ref encoded_data); - // space.serialize(ref encoded_data); - // author.serialize(ref encoded_data); - // // TODO: proper typehashes for below - // LegacyHash::hash(0, execution_strategy).serialize(ref encoded_data); - // LegacyHash::hash(0, user_proposal_validation_params.span()).serialize(ref encoded_data); - // salt.serialize(ref encoded_data); - // let message_hash = LegacyHash::hash(0, encoded_data.span()); - // hash_typed_data(message_hash) - - // let mut encoded_data = ArrayTrait::::new(); - // STRATEGY_TYPEHASH.serialize(ref encoded_data); - // execution_strategy.serialize(ref encoded_data); - // LegacyHash::hash(0, encoded_data.span()) - execution_strategy.params.span().struct_hash() + let mut encoded_data = ArrayTrait::::new(); + PROPOSE_TYPEHASH.serialize(ref encoded_data); + space.serialize(ref encoded_data); + author.serialize(ref encoded_data); + execution_strategy.struct_hash().serialize(ref encoded_data); + user_proposal_validation_params.span().struct_hash().serialize(ref encoded_data); + salt.serialize(ref encoded_data); + hash_typed_data(encoded_data.span().struct_hash(), author) } -fn hash_typed_data(message_hash: felt252) -> felt252 { +fn hash_typed_data(message_hash: felt252, signer: ContractAddress) -> felt252 { let mut encoded_data = ArrayTrait::::new(); STARKNET_MESSAGE.serialize(ref encoded_data); DOMAIN_HASH.serialize(ref encoded_data); + signer.serialize(ref encoded_data); message_hash.serialize(ref encoded_data); - LegacyHash::hash(0, encoded_data.span()) + encoded_data.span().struct_hash() } From 39e66e40ad61f917a0fa8ed41d77d6ac853340f2 Mon Sep 17 00:00:00 2001 From: Orlando Date: Fri, 28 Jul 2023 23:19:56 +0100 Subject: [PATCH 04/25] chore: starknetjs test scripts --- starknet/tests/stark-sig.ts | 76 ++++++++++++++++++------------------- starknet/tests/types.ts | 6 +-- 2 files changed, 40 insertions(+), 42 deletions(-) diff --git a/starknet/tests/stark-sig.ts b/starknet/tests/stark-sig.ts index cfb29f00..1df3664f 100644 --- a/starknet/tests/stark-sig.ts +++ b/starknet/tests/stark-sig.ts @@ -8,48 +8,46 @@ dotenv.config(); const pk = process.env.PRIVATE_KEY || ''; async function main() { - const p = new Provider(); - console.log(p); - // // connect provider - // const provider = new Provider({ sequencer: { baseUrl:"http://127.0.0.1:5050"} }); - // // new Open Zeppelin account v0.5.1 : - // // Generate public and private key pair. - // const privateKey0 = "0xe3e70682c2094cac629f6fbed82c07cd"; - // const address0 = "0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a"; - // const account0 = new Account(provider, address0, privateKey0); - - // const starkSigAuthAddress = "0x391ed8d6795fbb5f3ffb6994bcaa95e9b34dc6489e658c6d7fc86817bf4fe54"; - - // const {abi: starkSigAuthAbi} = await provider.getClassAt(starkSigAuthAddress); - // const starkSigAuth = new Contract(starkSigAuthAbi, starkSigAuthAddress, provider); - - // const msgHash = typedData.getMessageHash(typedDataPropose, address0); - - // console.log('msgHash=', msgHash); - - // const signature2 = await account0.signMessage(typedDataPropose); - - // console.log('signature2=', signature2); - - // // console.log(starkSigAuth.abi[2]); - // const specialParameters: Calldata = CallData.compile({ - // r: 1, - // s: 2, - // target: "0x0000000000000000000000000000000000007777", - // author: address0, - // execution_strategy: { - // addr: "0x0000000000000000000000000000000000001234", - // params: [5,6,7,8] - // }, - // user_proposal_validation_params: [1,2,3,4], - // salt: 0 - // }); + // connect provider + const provider = new Provider({ sequencer: { baseUrl:"http://127.0.0.1:5050"} }); + // new Open Zeppelin account v0.5.1 : + // Generate public and private key pair. + const privateKey0 = "0xe3e70682c2094cac629f6fbed82c07cd"; + const address0 = "0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a"; + const account0 = new Account(provider, address0, privateKey0); + + const starkSigAuthAddress = "0x14f48340c1ee431755c004365b58e92e69003495af214cf90c3603338e7e945"; + + const {abi: starkSigAuthAbi} = await provider.getClassAt(starkSigAuthAddress); + const starkSigAuth = new Contract(starkSigAuthAbi, starkSigAuthAddress, provider); + + const msgHash = typedData.getMessageHash(typedDataPropose, address0); + + console.log('msgHash=', msgHash); + + const signature2 = await account0.signMessage(typedDataPropose); + + console.log('signature2=', signature2); + + // console.log(starkSigAuth.abi[2]); + const specialParameters: Calldata = CallData.compile({ + r: 1, + s: 2, + target: "0x0000000000000000000000000000000000007777", + author: address0, + execution_strategy: { + addr: "0x0000000000000000000000000000000000001234", + params: [5,6,7,8] + }, + user_proposal_validation_params: [1,2,3,4], + salt: 0 + }); - // // console.log(specialParameters); + // console.log(specialParameters); - // const out = await starkSigAuth.call("propose_hash", specialParameters, {parseResponse: false}); + const out = await starkSigAuth.call("propose_hash", specialParameters, {parseResponse: false}); - // console.log('out=', out); + console.log('out=', out); // // const result = await account0.execute({ diff --git a/starknet/tests/types.ts b/starknet/tests/types.ts index e3883549..4f880a33 100644 --- a/starknet/tests/types.ts +++ b/starknet/tests/types.ts @@ -14,7 +14,7 @@ export const typedDataPropose: TypedData = { { name: 'space', type: 'ContractAddress' }, { name: 'author', type: 'ContractAddress' }, { name: 'executionStrategy', type: 'Strategy' }, - { name: 'userProposalValidationParams', type: 'Array' }, + { name: 'userProposalValidationParams', type: 'felt*' }, { name: 'salt', type: 'felt252' } ] }, @@ -29,9 +29,9 @@ export const typedDataPropose: TypedData = { author: "0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a", executionStrategy: { address: "0x0000000000000000000000000000000000001234", - params: ["0x5", "0x6", "0x7", "0x8"] + params: [5,6,7,8] }, - userProposalValidationParams: "0x1234", + userProposalValidationParams: ["0x1", "0x2", "0x3", "0x4"], salt: "0x0" }, }; \ No newline at end of file From 1e0009bda847abc8f38f84db783ec571c03f4078 Mon Sep 17 00:00:00 2001 From: Orlando Date: Mon, 31 Jul 2023 12:43:40 +0100 Subject: [PATCH 05/25] feat: verify propose sig --- starknet/src/authenticators/stark_sig.cairo | 15 +++++++++++++-- starknet/src/utils/stark_signatures.cairo | 6 +++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/starknet/src/authenticators/stark_sig.cairo b/starknet/src/authenticators/stark_sig.cairo index ddf56f1e..76474221 100644 --- a/starknet/src/authenticators/stark_sig.cairo +++ b/starknet/src/authenticators/stark_sig.cairo @@ -13,6 +13,7 @@ trait IStarkSigAuthenticator { execution_strategy: Strategy, user_proposal_validation_params: Array, salt: felt252, + public_key: felt252, ); fn propose_hash( self: @TContractState, @@ -55,10 +56,20 @@ mod StarkSigAuthenticator { execution_strategy: Strategy, user_proposal_validation_params: Array, salt: felt252, + public_key: felt252, ) { - let msg_hash = stark_signatures::get_propose_digest( - target, author, execution_strategy, user_proposal_validation_params, salt + stark_signatures::verify_propose_sig( + r, + s, + target, + author, + execution_strategy, + user_proposal_validation_params, + salt, + public_key ); + // Check public key corresponds to the author account address. + // self._used_salts.write((author, salt), true); // ISpaceDispatcher { diff --git a/starknet/src/utils/stark_signatures.cairo b/starknet/src/utils/stark_signatures.cairo index aa975f85..74095b13 100644 --- a/starknet/src/utils/stark_signatures.cairo +++ b/starknet/src/utils/stark_signatures.cairo @@ -3,7 +3,7 @@ use array::{ArrayTrait, SpanTrait}; use traits::Into; use clone::Clone; use serde::Serde; -use starknet::secp256k1; +use ecdsa::check_ecdsa_signature; use hash::LegacyHash; use integer::u256_from_felt252; use sx::utils::types::{Strategy, IndexedStrategy, Choice, Felt252ArrayIntoU256Array}; @@ -57,12 +57,12 @@ fn verify_propose_sig( execution_strategy: Strategy, user_proposal_validation_params: Array, salt: felt252, + public_key: felt252 ) { let digest: felt252 = get_propose_digest( target, author, execution_strategy, user_proposal_validation_params, salt ); -// TODO: Actually verify the signature when it gets added -// secp256k1::verify_eth_signature(digest, r, s, v, author); + assert(check_ecdsa_signature(digest, public_key, r, s), 'Invalid signature'); } fn get_propose_digest( From 12d6ba3fa28d65a1cd242d602720d3a09556eb12 Mon Sep 17 00:00:00 2001 From: Orlando Date: Mon, 31 Jul 2023 12:43:58 +0100 Subject: [PATCH 06/25] chore: cleaned up stark sig test --- starknet/tests/stark-sig.ts | 99 +++++++++++------------------ starknet/tests/types.ts | 122 +++++++++++++++++++++++++----------- 2 files changed, 123 insertions(+), 98 deletions(-) diff --git a/starknet/tests/stark-sig.ts b/starknet/tests/stark-sig.ts index 1df3664f..7b2a4304 100644 --- a/starknet/tests/stark-sig.ts +++ b/starknet/tests/stark-sig.ts @@ -1,85 +1,62 @@ import fs from "fs"; import dotenv from 'dotenv'; import { Provider, Account, Contract, CallData, Calldata, typedData, cairo} from "starknet"; -import { typedDataPropose } from "./types"; +import { proposeTypes, Propose, StarknetSigProposeCalldata, domain } from "./types"; dotenv.config(); const pk = process.env.PRIVATE_KEY || ''; async function main() { - // connect provider const provider = new Provider({ sequencer: { baseUrl:"http://127.0.0.1:5050"} }); - // new Open Zeppelin account v0.5.1 : - // Generate public and private key pair. + const privateKey0 = "0xe3e70682c2094cac629f6fbed82c07cd"; const address0 = "0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a"; + const publickey0 = "0x7e52885445756b313ea16849145363ccb73fb4ab0440dbac333cf9d13de82b9" const account0 = new Account(provider, address0, privateKey0); - - const starkSigAuthAddress = "0x14f48340c1ee431755c004365b58e92e69003495af214cf90c3603338e7e945"; + + const starkSigAuthAddress = "0x2baf1877b1388d8421485c8cb419b37ebce3096e323c4ef6b3c979a8a30917e"; const {abi: starkSigAuthAbi} = await provider.getClassAt(starkSigAuthAddress); const starkSigAuth = new Contract(starkSigAuthAbi, starkSigAuthAddress, provider); - const msgHash = typedData.getMessageHash(typedDataPropose, address0); + const proposeMsg: Propose = { + space: "0x0000000000000000000000000000000000007777", + author: "0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a", + executionStrategy: { + address: "0x0000000000000000000000000000000000001234", + params: ["0x5", "0x6", "0x7", "0x8"] + }, + userProposalValidationParams: ["0x1", "0x2", "0x3", "0x4"], + salt: "0x0" + } + + const proposeData: typedData.TypedData = { + types: proposeTypes, + primaryType: "Propose", + domain: domain, + message: proposeMsg as any + } + + const msgHash = typedData.getMessageHash(proposeData, address0); console.log('msgHash=', msgHash); - const signature2 = await account0.signMessage(typedDataPropose); + const signature2 = await account0.signMessage(proposeData) as any; - console.log('signature2=', signature2); - - // console.log(starkSigAuth.abi[2]); - const specialParameters: Calldata = CallData.compile({ - r: 1, - s: 2, - target: "0x0000000000000000000000000000000000007777", - author: address0, - execution_strategy: { - addr: "0x0000000000000000000000000000000000001234", - params: [5,6,7,8] - }, - user_proposal_validation_params: [1,2,3,4], - salt: 0 - }); + const proposeCalldata: StarknetSigProposeCalldata = { + r: signature2.r, + s: signature2.s, + ...proposeMsg, + public_key: publickey0 + } - // console.log(specialParameters); - - const out = await starkSigAuth.call("propose_hash", specialParameters, {parseResponse: false}); - - console.log('out=', out); - - - // // const result = await account0.execute({ - // // contractAddress: starkSigAuthAddress, - // // entrypoint: "propose_hash", - // // calldata: CallData.compile({ - // // r: 1, - // // s: 2, - // // target: "0x0000000000000000000000000000000000001235", - // // author: address0, - // // execution_strategy: { - // // addr: "0x0000000000000000000000000000000000001234", - // // params: [1,2,3,4] - // // }, - // // user_proposal_validation_params: [1,2,3,4], - // // salt: 0 - // // }) - // // }) - // // console.log(result); - - - // // const proposeMessage: Propose = { - // // space: "0x0000000000000000000000000000000000001234", - // // author: signer.address, - // // executionStrategy: { - // // addr: "0x0000000000000000000000000000000000001234", - // // params: "0x1234" - // // }, - // // userProposalValidationParams: "0x1234", - // // salt: "0x0" - // // } - + const result = await account0.execute({ + contractAddress: starkSigAuthAddress, + entrypoint: "authenticate_propose", + calldata: CallData.compile(proposeCalldata as any) + }) + console.log(result); } main() @@ -87,4 +64,4 @@ main() .catch((error) => { console.error(error); process.exit(1); - }); \ No newline at end of file + }); diff --git a/starknet/tests/types.ts b/starknet/tests/types.ts index 4f880a33..bbcc891d 100644 --- a/starknet/tests/types.ts +++ b/starknet/tests/types.ts @@ -1,37 +1,85 @@ -import { TypedData } from "starknet"; -export const typedDataPropose: TypedData = { - types: { - StarkNetDomain: [ - { name: "name", type: "felt252" }, - { name: "version", type: "felt252" }, - { name: "chainId", type: "felt252" }, - ], - Strategy: [ - { name: "address", type: "felt252" }, - { name: "params", type: "felt*" } - ], - Propose: [ - { name: 'space', type: 'ContractAddress' }, - { name: 'author', type: 'ContractAddress' }, - { name: 'executionStrategy', type: 'Strategy' }, - { name: 'userProposalValidationParams', type: 'felt*' }, - { name: 'salt', type: 'felt252' } - ] - }, - primaryType: "Propose", - domain: { - name: "1", // put the name of your dapp to ensure that the signatures will not be used by other DAPP - version: "1", - chainId: "0x534e5f474f45524c49" // devnet id - }, - message: { - space: "0x0000000000000000000000000000000000007777", - author: "0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a", - executionStrategy: { - address: "0x0000000000000000000000000000000000001234", - params: [5,6,7,8] - }, - userProposalValidationParams: ["0x1", "0x2", "0x3", "0x4"], - salt: "0x0" - }, -}; \ No newline at end of file +// import { TypedData } from "starknet"; +// export const typedDataPropose: TypedData = { +// types: { +// StarkNetDomain: [ +// { name: "name", type: "felt252" }, +// { name: "version", type: "felt252" }, +// { name: "chainId", type: "felt252" }, +// ], +// Strategy: [ +// { name: "address", type: "felt252" }, +// { name: "params", type: "felt*" } +// ], +// Propose: [ +// { name: 'space', type: 'ContractAddress' }, +// { name: 'author', type: 'ContractAddress' }, +// { name: 'executionStrategy', type: 'Strategy' }, +// { name: 'userProposalValidationParams', type: 'felt*' }, +// { name: 'salt', type: 'felt252' } +// ] +// }, +// primaryType: "Propose", +// domain: { +// name: "1", // put the name of your dapp to ensure that the signatures will not be used by other DAPP +// version: "1", +// chainId: "0x534e5f474f45524c49" // devnet id +// }, +// message: { +// space: "0x0000000000000000000000000000000000007777", +// author: "0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a", +// executionStrategy: { +// address: "0x0000000000000000000000000000000000001234", +// params: [5,6,7,8] +// }, +// userProposalValidationParams: ["0x1", "0x2", "0x3", "0x4"], +// salt: "0x0" +// }, +// }; + +export const domain = { + name: "1", // put the name of your dapp to ensure that the signatures will not be used by other DAPP + version: "1", + chainId: "0x534e5f474f45524c49" // devnet id +} + +export const domainTypes = { + StarkNetDomain: [ + { name: "name", type: "felt252" }, + { name: "version", type: "felt252" }, + { name: "chainId", type: "felt252" }, + ], + }; + +export const proposeTypes = { + StarkNetDomain: domainTypes.StarkNetDomain, + Propose: [ + { name: 'space', type: 'ContractAddress' }, + { name: 'author', type: 'ContractAddress' }, + { name: 'executionStrategy', type: 'Strategy' }, + { name: 'userProposalValidationParams', type: 'felt*' }, + { name: 'salt', type: 'felt252' } + ], + Strategy: [ + { name: "address", type: "felt252" }, + { name: "params", type: "felt*" } + ], + }; + +export interface Strategy { + address: string; + params: string[]; +} + +export interface Propose { + space: string; + author: string; + executionStrategy: Strategy; + userProposalValidationParams: string[]; + salt: string; +} + +export interface StarknetSigProposeCalldata extends Propose { + r: string; + s: string; + public_key: string; +} From fe9e772dfa1aad11c87da8c410e847961fea5843 Mon Sep 17 00:00:00 2001 From: Orlando Date: Mon, 31 Jul 2023 12:44:46 +0100 Subject: [PATCH 07/25] chore: removed: dead code --- starknet/tests/types.ts | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/starknet/tests/types.ts b/starknet/tests/types.ts index bbcc891d..1c8cb4e2 100644 --- a/starknet/tests/types.ts +++ b/starknet/tests/types.ts @@ -1,41 +1,3 @@ -// import { TypedData } from "starknet"; -// export const typedDataPropose: TypedData = { -// types: { -// StarkNetDomain: [ -// { name: "name", type: "felt252" }, -// { name: "version", type: "felt252" }, -// { name: "chainId", type: "felt252" }, -// ], -// Strategy: [ -// { name: "address", type: "felt252" }, -// { name: "params", type: "felt*" } -// ], -// Propose: [ -// { name: 'space', type: 'ContractAddress' }, -// { name: 'author', type: 'ContractAddress' }, -// { name: 'executionStrategy', type: 'Strategy' }, -// { name: 'userProposalValidationParams', type: 'felt*' }, -// { name: 'salt', type: 'felt252' } -// ] -// }, -// primaryType: "Propose", -// domain: { -// name: "1", // put the name of your dapp to ensure that the signatures will not be used by other DAPP -// version: "1", -// chainId: "0x534e5f474f45524c49" // devnet id -// }, -// message: { -// space: "0x0000000000000000000000000000000000007777", -// author: "0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a", -// executionStrategy: { -// address: "0x0000000000000000000000000000000000001234", -// params: [5,6,7,8] -// }, -// userProposalValidationParams: ["0x1", "0x2", "0x3", "0x4"], -// salt: "0x0" -// }, -// }; - export const domain = { name: "1", // put the name of your dapp to ensure that the signatures will not be used by other DAPP version: "1", From adcb1abcd14064cacfebf19fa37188c559d92242 Mon Sep 17 00:00:00 2001 From: Orlando Date: Mon, 31 Jul 2023 19:20:07 +0100 Subject: [PATCH 08/25] feat: vote and update proposal sig auth --- starknet/src/authenticators/stark_sig.cairo | 69 +++++++++++++++ starknet/src/utils/constants.cairo | 4 + starknet/src/utils/stark_signatures.cairo | 96 ++++++++++++++++++++- 3 files changed, 168 insertions(+), 1 deletion(-) diff --git a/starknet/src/authenticators/stark_sig.cairo b/starknet/src/authenticators/stark_sig.cairo index 76474221..458d9125 100644 --- a/starknet/src/authenticators/stark_sig.cairo +++ b/starknet/src/authenticators/stark_sig.cairo @@ -15,6 +15,28 @@ trait IStarkSigAuthenticator { salt: felt252, public_key: felt252, ); + fn authenticate_vote( + ref self: TContractState, + r: felt252, + s: felt252, + target: ContractAddress, + voter: ContractAddress, + proposal_id: u256, + choice: Choice, + user_voting_strategies: Array, + public_key: felt252 + ); + fn authenticate_update_proposal( + ref self: TContractState, + r: felt252, + s: felt252, + target: ContractAddress, + author: ContractAddress, + proposal_id: u256, + execution_strategy: Strategy, + salt: felt252, + public_key: felt252 + ); fn propose_hash( self: @TContractState, r: felt252, @@ -77,6 +99,53 @@ mod StarkSigAuthenticator { // }.propose(author, execution_strategy, user_proposal_validation_params); } + fn authenticate_vote( + ref self: ContractState, + r: felt252, + s: felt252, + target: ContractAddress, + voter: ContractAddress, + proposal_id: u256, + choice: Choice, + user_voting_strategies: Array, + public_key: felt252 + ) { + stark_signatures::verify_vote_sig( + r, s, target, voter, proposal_id, choice, user_voting_strategies.span(), public_key + ); + + // Check public key corresponds to the voter account address. + + // No need to check salts here, as double voting is prevented by the space itself. + + ISpaceDispatcher { + contract_address: target + }.vote(voter, proposal_id, choice, user_voting_strategies); + } + + fn authenticate_update_proposal( + ref self: ContractState, + r: felt252, + s: felt252, + target: ContractAddress, + author: ContractAddress, + proposal_id: u256, + execution_strategy: Strategy, + salt: felt252, + public_key: felt252 + ) { + stark_signatures::verify_update_proposal_sig( + r, s, target, author, proposal_id, execution_strategy, salt, public_key + ); + // Check public key corresponds to the author account address. + + // self._used_salts.write((author, salt), true); + + // ISpaceDispatcher { + // contract_address: target + // }.update_proposal(author, proposal_id, execution_strategy); + } + fn propose_hash( self: @ContractState, r: felt252, diff --git a/starknet/src/utils/constants.cairo b/starknet/src/utils/constants.cairo index a652222b..049c327a 100644 --- a/starknet/src/utils/constants.cairo +++ b/starknet/src/utils/constants.cairo @@ -49,5 +49,9 @@ const INDEXED_STRATEGY_TYPEHASH_LOW: u128 = 0x8b36195eec0090e913c01e7534729c74; const STARKNET_MESSAGE: felt252 = 0x537461726b4e6574204d657373616765; const DOMAIN_HASH: felt252 = 0x133d0430d262d06e2d4aff2851ca256738e40d43593c998ff664b5d5cb410d3; const PROPOSE_TYPEHASH: felt252 = 0x1f8c9b1ab74c5990f89bac4c632dc405457352e22bbc7573a237989aa62cb60; +const VOTE_TYPEHASH: felt252 = 0x131659fe0b2bb8b8675a687562649c5b10b7d3fd3d4ac797d137c1608f07f81; +const UPDATE_PROPOSAL_TYPEHASH: felt252 = 0x1234; const STRATEGY_TYPEHASH: felt252 = 0x39154ec0efadcd0deffdfc2044cf45dd986d260e59c26d69564b50a18f40f6b; +const INDEXED_STRATEGY_TYPEHASH: felt252 = + 0x1f464f3e668281a899c5f3fc74a009ccd1df05fd0b9331b0460dc3f8054f64c; diff --git a/starknet/src/utils/stark_signatures.cairo b/starknet/src/utils/stark_signatures.cairo index 74095b13..8082e069 100644 --- a/starknet/src/utils/stark_signatures.cairo +++ b/starknet/src/utils/stark_signatures.cairo @@ -8,7 +8,10 @@ use hash::LegacyHash; use integer::u256_from_felt252; use sx::utils::types::{Strategy, IndexedStrategy, Choice, Felt252ArrayIntoU256Array}; use sx::utils::math::pow; -use sx::utils::constants::{STARKNET_MESSAGE, DOMAIN_HASH, STRATEGY_TYPEHASH, PROPOSE_TYPEHASH}; +use sx::utils::constants::{ + STARKNET_MESSAGE, DOMAIN_HASH, STRATEGY_TYPEHASH, INDEXED_STRATEGY_TYPEHASH, PROPOSE_TYPEHASH, + VOTE_TYPEHASH, UPDATE_PROPOSAL_TYPEHASH +}; impl LegacyHashSpanFelt252 of LegacyHash> { fn hash(state: felt252, mut value: Span) -> felt252 { @@ -48,6 +51,30 @@ impl StructHashStrategy of StructHash { } } +impl StructHashIndexedStrategy of StructHash { + fn struct_hash(self: @IndexedStrategy) -> felt252 { + let mut encoded_data = ArrayTrait::::new(); + INDEXED_STRATEGY_TYPEHASH.serialize(ref encoded_data); + (*self.index).serialize(ref encoded_data); + self.params.span().struct_hash().serialize(ref encoded_data); + encoded_data.span().struct_hash() + } +} + +impl StructHashIndexedStrategySpan of StructHash> { + fn struct_hash(self: @Span) -> felt252 { + let mut encoded_data = ArrayTrait::::new(); + let mut i: usize = 0; + loop { + if i >= (*self).len() { + break (); + }; + encoded_data.append((*self).at(i).struct_hash()); + }; + encoded_data.span().struct_hash() + } +} + // Reverts if the signature was not signed by the author. fn verify_propose_sig( r: felt252, @@ -65,6 +92,39 @@ fn verify_propose_sig( assert(check_ecdsa_signature(digest, public_key, r, s), 'Invalid signature'); } +fn verify_vote_sig( + r: felt252, + s: felt252, + target: ContractAddress, + voter: ContractAddress, + proposal_id: u256, + choice: Choice, + user_voting_strategies: Span, + public_key: felt252 +) { + let digest: felt252 = get_vote_digest( + target, voter, proposal_id, choice, user_voting_strategies + ); + assert(check_ecdsa_signature(digest, public_key, r, s), 'Invalid signature'); +} + +fn verify_update_proposal_sig( + r: felt252, + s: felt252, + target: ContractAddress, + author: ContractAddress, + proposal_id: u256, + execution_strategy: Strategy, + salt: felt252, + public_key: felt252 +) { + let digest: felt252 = get_update_proposal_digest( + target, author, proposal_id, execution_strategy, salt + ); + assert(check_ecdsa_signature(digest, public_key, r, s), 'Invalid signature'); +} + + fn get_propose_digest( space: ContractAddress, author: ContractAddress, @@ -82,6 +142,40 @@ fn get_propose_digest( hash_typed_data(encoded_data.span().struct_hash(), author) } +fn get_vote_digest( + space: ContractAddress, + voter: ContractAddress, + proposal_id: u256, + choice: Choice, + user_voting_strategies: Span +) -> felt252 { + let mut encoded_data = ArrayTrait::::new(); + VOTE_TYPEHASH.serialize(ref encoded_data); + space.serialize(ref encoded_data); + voter.serialize(ref encoded_data); + proposal_id.serialize(ref encoded_data); + choice.serialize(ref encoded_data); + user_voting_strategies.struct_hash().serialize(ref encoded_data); + hash_typed_data(encoded_data.span().struct_hash(), voter) +} + +fn get_update_proposal_digest( + space: ContractAddress, + author: ContractAddress, + proposal_id: u256, + execution_strategy: Strategy, + salt: felt252 +) -> felt252 { + let mut encoded_data = ArrayTrait::::new(); + UPDATE_PROPOSAL_TYPEHASH.serialize(ref encoded_data); + space.serialize(ref encoded_data); + author.serialize(ref encoded_data); + proposal_id.serialize(ref encoded_data); + execution_strategy.struct_hash().serialize(ref encoded_data); + salt.serialize(ref encoded_data); + hash_typed_data(encoded_data.span().struct_hash(), author) +} + fn hash_typed_data(message_hash: felt252, signer: ContractAddress) -> felt252 { let mut encoded_data = ArrayTrait::::new(); STARKNET_MESSAGE.serialize(ref encoded_data); From ef8ff50d7914c0f051a3f08f74bb9bf69c805e4b Mon Sep 17 00:00:00 2001 From: Orlando Date: Tue, 1 Aug 2023 18:08:30 +0100 Subject: [PATCH 09/25] chore: typescript linting + style --- .eslintignore | 1 + .eslintrc | 22 ++++++++++++++++++++++ .prettierrc | 6 ++++++ package.json | 10 ++++++++++ 4 files changed, 39 insertions(+) create mode 100644 .eslintignore create mode 100644 .eslintrc create mode 100644 .prettierrc diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..8c2a0056 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +ethereum/lib \ No newline at end of file diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..5cd0c783 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,22 @@ +{ + "parser": "@typescript-eslint/parser", + "extends": [ + "plugin:@typescript-eslint/recommended" + ], + "plugins": [ + "prettier", + "@typescript-eslint" + ], + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module" + }, + "rules": { + "no-console": "off", + "prettier/prettier": "error", + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/ban-ts-ignore": "off", + "@typescript-eslint/camelcase": "off", + "@typescript-eslint/no-explicit-any": "off" + } +} \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..2572ac3a --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "semi": true, + "singleQuote": true, + "printWidth": 100, + "tabWidth": 2 +} \ No newline at end of file diff --git a/package.json b/package.json index bd1cbefb..e85dd9d9 100644 --- a/package.json +++ b/package.json @@ -5,12 +5,22 @@ "repository": "https://github.com/snapshot-labs/sx-starknet-2.git", "author": "Snapshot Labs", "license": "MIT", + "scripts": { + "format": "eslint . --ext .ts --fix" + }, "devDependencies": { "@types/node": "^20.4.5", + "@typescript-eslint/parser": "^6.2.1", "dotenv": "^16.3.1", + "eslint": "^8.46.0", + "eslint-plugin-prettier": "^5.0.0", "fs": "^0.0.1-security", + "prettier": "^3.0.0", "starknet": "^5.14.1", "ts-node": "^10.9.1", "typescript": "^5.1.6" + }, + "dependencies": { + "@typescript-eslint/eslint-plugin": "^6.2.1" } } From eda44ca1b6a91a92dbb5aadfc63691940c48e0da Mon Sep 17 00:00:00 2001 From: Orlando Date: Tue, 1 Aug 2023 18:09:04 +0100 Subject: [PATCH 10/25] chore: update yarn lock --- yarn.lock | 1127 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1126 insertions(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index acb6c1e3..097eabf1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" @@ -9,6 +14,57 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": + version "4.6.2" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.6.2.tgz#1816b5f6948029c5eaacb0703b850ee0cb37d8f8" + integrity sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw== + +"@eslint/eslintrc@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.1.tgz#18d635e24ad35f7276e8a49d135c7d3ca6a46f93" + integrity sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@^8.46.0": + version "8.46.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.46.0.tgz#3f7802972e8b6fe3f88ed1aabc74ec596c456db6" + integrity sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA== + +"@humanwhocodes/config-array@^0.11.10": + version "0.11.10" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" + integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + "@jridgewell/resolve-uri@^3.0.3": version "3.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" @@ -44,6 +100,39 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@pkgr/utils@^2.3.1": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.4.2.tgz#9e638bbe9a6a6f165580dc943f138fd3309a2cbc" + integrity sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw== + dependencies: + cross-spawn "^7.0.3" + fast-glob "^3.3.0" + is-glob "^4.0.3" + open "^9.1.0" + picocolors "^1.0.0" + tslib "^2.6.0" + "@tsconfig/node10@^1.0.7": version "1.0.9" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" @@ -64,46 +153,678 @@ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== +"@types/json-schema@^7.0.12": + version "7.0.12" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" + integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== + "@types/node@^20.4.5": version "20.4.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.5.tgz#9dc0a5cb1ccce4f7a731660935ab70b9c00a5d69" integrity sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg== +"@types/semver@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" + integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== + +"@typescript-eslint/eslint-plugin@^6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.1.tgz#41b79923fee46a745a3a50cba1c33c622aa3c79a" + integrity sha512-iZVM/ALid9kO0+I81pnp1xmYiFyqibAHzrqX4q5YvvVEyJqY+e6rfTXSCsc2jUxGNqJqTfFSSij/NFkZBiBzLw== + dependencies: + "@eslint-community/regexpp" "^4.5.1" + "@typescript-eslint/scope-manager" "6.2.1" + "@typescript-eslint/type-utils" "6.2.1" + "@typescript-eslint/utils" "6.2.1" + "@typescript-eslint/visitor-keys" "6.2.1" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.4" + natural-compare "^1.4.0" + natural-compare-lite "^1.4.0" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/parser@^6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.2.1.tgz#e18a31eea1cca8841a565f1701960c8123ed07f9" + integrity sha512-Ld+uL1kYFU8e6btqBFpsHkwQ35rw30IWpdQxgOqOh4NfxSDH6uCkah1ks8R/RgQqI5hHPXMaLy9fbFseIe+dIg== + dependencies: + "@typescript-eslint/scope-manager" "6.2.1" + "@typescript-eslint/types" "6.2.1" + "@typescript-eslint/typescript-estree" "6.2.1" + "@typescript-eslint/visitor-keys" "6.2.1" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz#b6f43a867b84e5671fe531f2b762e0b68f7cf0c4" + integrity sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q== + dependencies: + "@typescript-eslint/types" "6.2.1" + "@typescript-eslint/visitor-keys" "6.2.1" + +"@typescript-eslint/type-utils@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.2.1.tgz#8eb8a2cccdf39cd7cf93e02bd2c3782dc90b0525" + integrity sha512-fTfCgomBMIgu2Dh2Or3gMYgoNAnQm3RLtRp+jP7A8fY+LJ2+9PNpi5p6QB5C4RSP+U3cjI0vDlI3mspAkpPVbQ== + dependencies: + "@typescript-eslint/typescript-estree" "6.2.1" + "@typescript-eslint/utils" "6.2.1" + debug "^4.3.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/types@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.2.1.tgz#7fcdeceb503aab601274bf5e210207050d88c8ab" + integrity sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ== + +"@typescript-eslint/typescript-estree@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz#2af6e90c1e91cb725a5fe1682841a3f74549389e" + integrity sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q== + dependencies: + "@typescript-eslint/types" "6.2.1" + "@typescript-eslint/visitor-keys" "6.2.1" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/utils@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.2.1.tgz#2aa4279ec13053d05615bcbde2398e1e8f08c334" + integrity sha512-eBIXQeupYmxVB6S7x+B9SdBeB6qIdXKjgQBge2J+Ouv8h9Cxm5dHf/gfAZA6dkMaag+03HdbVInuXMmqFB/lKQ== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@types/json-schema" "^7.0.12" + "@types/semver" "^7.5.0" + "@typescript-eslint/scope-manager" "6.2.1" + "@typescript-eslint/types" "6.2.1" + "@typescript-eslint/typescript-estree" "6.2.1" + semver "^7.5.4" + +"@typescript-eslint/visitor-keys@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz#442e7c09fe94b715a54ebe30e967987c3c41fbf4" + integrity sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA== + dependencies: + "@typescript-eslint/types" "6.2.1" + eslint-visitor-keys "^3.4.1" + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + acorn-walk@^8.1.1: version "8.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== -acorn@^8.4.1: +acorn@^8.4.1, acorn@^8.9.0: version "8.10.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== +ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + arg@^4.1.0: version "4.1.3" resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +big-integer@^1.6.44: + version "1.6.51" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" + integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== + +bplist-parser@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" + integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== + dependencies: + big-integer "^1.6.44" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +bundle-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" + integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== + dependencies: + run-applescript "^5.0.0" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + create-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== +cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +default-browser-id@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" + integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== + dependencies: + bplist-parser "^0.2.0" + untildify "^4.0.0" + +default-browser@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-4.0.0.tgz#53c9894f8810bf86696de117a6ce9085a3cbc7da" + integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== + dependencies: + bundle-name "^3.0.0" + default-browser-id "^3.0.0" + execa "^7.1.1" + titleize "^3.0.0" + +define-lazy-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" + integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== + diff@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + dotenv@^16.3.1: version "16.3.1" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-plugin-prettier@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz#6887780ed95f7708340ec79acfdf60c35b9be57a" + integrity sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w== + dependencies: + prettier-linter-helpers "^1.0.0" + synckit "^0.8.5" + +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.2: + version "3.4.2" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz#8c2095440eca8c933bedcadf16fefa44dbe9ba5f" + integrity sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw== + +eslint@^8.46.0: + version "8.46.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.46.0.tgz#a06a0ff6974e53e643acc42d1dcf2e7f797b3552" + integrity sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.1" + "@eslint/js" "^8.46.0" + "@humanwhocodes/config-array" "^0.11.10" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.2" + espree "^9.6.1" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== + dependencies: + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +execa@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-7.2.0.tgz#657e75ba984f42a70f38928cedc87d6f2d4fe4e9" + integrity sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.1" + human-signals "^4.3.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^3.0.7" + strip-final-newline "^3.0.0" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-diff@^1.1.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== + +fast-glob@^3.2.9, fast-glob@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.2.7" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + fs@^0.0.1-security: version "0.0.1-security" resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.1-security.tgz#8a7bd37186b6dddf3813f23858b57ecaaf5e41d4" integrity sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w== +get-stream@^6.0.0, get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^13.19.0: + version "13.20.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + dependencies: + type-fest "^0.20.2" + +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +human-signals@^4.3.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" + integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== + +ignore@^5.2.0, ignore@^5.2.4: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-docker@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" + integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-inside-container@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" + integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== + dependencies: + is-docker "^3.0.0" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + isomorphic-fetch@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4" @@ -112,16 +833,70 @@ isomorphic-fetch@^3.0.0: node-fetch "^2.6.1" whatwg-fetch "^3.4.1" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + lossless-json@^2.0.8: version "2.0.11" resolved "https://registry.yarnpkg.com/lossless-json/-/lossless-json-2.0.11.tgz#3137684c93fd99481c6f99c985efc9c9c5cc76a5" integrity sha512-BP0vn+NGYvzDielvBZaFain/wgeJ1hTvURCqtKvhr1SCPePdaaTanmmcplrHfEJSJOUql7hk4FHwToNJjWRY3g== +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + micro-starknet@~0.2.1: version "0.2.3" resolved "https://registry.yarnpkg.com/micro-starknet/-/micro-starknet-0.2.3.tgz#ff4e7caf599255d2110e9c57bb483dfaf493ccb3" @@ -130,6 +905,46 @@ micro-starknet@~0.2.1: "@noble/curves" "~1.0.0" "@noble/hashes" "~1.3.0" +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + +minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + node-fetch@^2.6.1: version "2.6.12" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.12.tgz#02eb8e22074018e3d5a83016649d04df0e348fba" @@ -137,11 +952,211 @@ node-fetch@^2.6.1: dependencies: whatwg-url "^5.0.0" +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +npm-run-path@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" + integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== + dependencies: + path-key "^4.0.0" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + +open@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/open/-/open-9.1.0.tgz#684934359c90ad25742f5a26151970ff8c6c80b6" + integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== + dependencies: + default-browser "^4.0.0" + define-lazy-prop "^3.0.0" + is-inside-container "^1.0.0" + is-wsl "^2.2.0" + +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + pako@^2.0.4: version "2.1.0" resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.0.tgz#e7b19f691245a21d618c68bc54dc06122f6105ae" + integrity sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g== + +punycode@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-applescript@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-5.0.0.tgz#e11e1c932e055d5c6b40d98374e0268d9b11899c" + integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== + dependencies: + execa "^5.0.0" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + starknet@^5.14.1: version "5.14.1" resolved "https://registry.yarnpkg.com/starknet/-/starknet-5.14.1.tgz#97fa5f99c4c24e42ffa315cfda525461d09d6087" @@ -154,11 +1169,70 @@ starknet@^5.14.1: pako "^2.0.4" url-join "^4.0.1" +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +synckit@^0.8.5: + version "0.8.5" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.5.tgz#b7f4358f9bb559437f9f167eb6bc46b3c9818fa3" + integrity sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q== + dependencies: + "@pkgr/utils" "^2.3.1" + tslib "^2.5.0" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +titleize@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" + integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== +ts-api-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.1.tgz#8144e811d44c749cd65b2da305a032510774452d" + integrity sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A== + ts-node@^10.9.1: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" @@ -178,11 +1252,40 @@ ts-node@^10.9.1: v8-compile-cache-lib "^3.0.1" yn "3.1.1" +tslib@^2.5.0, tslib@^2.6.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.1.tgz#fd8c9a0ff42590b25703c0acb3de3d3f4ede0410" + integrity sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig== + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + typescript@^5.1.6: version "5.1.6" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + url-join@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" @@ -211,7 +1314,29 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From 10d5af5597d4c82ba789542f2174fbe4ae65f451 Mon Sep 17 00:00:00 2001 From: Orlando Date: Tue, 1 Aug 2023 18:09:46 +0100 Subject: [PATCH 11/25] chore: tests for vote and update proposal starknet sig authentication --- starknet/src/authenticators/stark_sig.cairo | 45 ++--- starknet/src/utils/constants.cairo | 6 +- starknet/src/utils/signatures.cairo | 1 + starknet/src/utils/stark_signatures.cairo | 23 ++- starknet/tests/deploy-stark-sig-auth.ts | 41 +++-- starknet/tests/stark-sig.ts | 179 ++++++++++++++------ starknet/tests/types.ts | 146 ++++++++++++---- 7 files changed, 308 insertions(+), 133 deletions(-) diff --git a/starknet/src/authenticators/stark_sig.cairo b/starknet/src/authenticators/stark_sig.cairo index 458d9125..acf5fb2f 100644 --- a/starknet/src/authenticators/stark_sig.cairo +++ b/starknet/src/authenticators/stark_sig.cairo @@ -47,6 +47,28 @@ trait IStarkSigAuthenticator { user_proposal_validation_params: Array, salt: felt252 ) -> felt252; + fn vote_hash( + self: @TContractState, + r: felt252, + s: felt252, + target: ContractAddress, + voter: ContractAddress, + proposal_id: u256, + choice: Choice, + user_voting_strategies: Array, + public_key: felt252 + ) -> felt252; + fn encoded_vote( + self: @TContractState, + r: felt252, + s: felt252, + target: ContractAddress, + author: ContractAddress, + proposal_id: u256, + execution_strategy: Strategy, + salt: felt252, + public_key: felt252 + ) -> Array; } #[starknet::contract] @@ -111,16 +133,16 @@ mod StarkSigAuthenticator { public_key: felt252 ) { stark_signatures::verify_vote_sig( - r, s, target, voter, proposal_id, choice, user_voting_strategies.span(), public_key + r, s, target, voter, proposal_id, choice, user_voting_strategies, public_key ); // Check public key corresponds to the voter account address. // No need to check salts here, as double voting is prevented by the space itself. - ISpaceDispatcher { - contract_address: target - }.vote(voter, proposal_id, choice, user_voting_strategies); + // ISpaceDispatcher { + // contract_address: target + // }.vote(voter, proposal_id, choice, user_voting_strategies); } fn authenticate_update_proposal( @@ -145,21 +167,6 @@ mod StarkSigAuthenticator { // contract_address: target // }.update_proposal(author, proposal_id, execution_strategy); } - - fn propose_hash( - self: @ContractState, - r: felt252, - s: felt252, - target: ContractAddress, - author: ContractAddress, - execution_strategy: Strategy, - user_proposal_validation_params: Array, - salt: felt252, - ) -> felt252 { - stark_signatures::get_propose_digest( - target, author, execution_strategy, user_proposal_validation_params, salt - ) - } } // #[constructor] // fn constructor(ref self: ContractState, name: felt252, version: felt252) {// TODO: domain hash is immutable so could be placed in the contract code instead of storage to save on reads. diff --git a/starknet/src/utils/constants.cairo b/starknet/src/utils/constants.cairo index 049c327a..c2aff30a 100644 --- a/starknet/src/utils/constants.cairo +++ b/starknet/src/utils/constants.cairo @@ -46,12 +46,14 @@ const INDEXED_STRATEGY_TYPEHASH_LOW: u128 = 0x8b36195eec0090e913c01e7534729c74; // ------ Stark Sig Constants ------ +// TODO: Add comments containing pre-images of the constants const STARKNET_MESSAGE: felt252 = 0x537461726b4e6574204d657373616765; const DOMAIN_HASH: felt252 = 0x133d0430d262d06e2d4aff2851ca256738e40d43593c998ff664b5d5cb410d3; const PROPOSE_TYPEHASH: felt252 = 0x1f8c9b1ab74c5990f89bac4c632dc405457352e22bbc7573a237989aa62cb60; -const VOTE_TYPEHASH: felt252 = 0x131659fe0b2bb8b8675a687562649c5b10b7d3fd3d4ac797d137c1608f07f81; -const UPDATE_PROPOSAL_TYPEHASH: felt252 = 0x1234; +const VOTE_TYPEHASH: felt252 = 0x1845db28c74470cdaa3cf6a1c5017d013586d70ffee45b519a5670e23fe9512; +const UPDATE_PROPOSAL_TYPEHASH: felt252 = 0x222b737bd5f9ba595cf15e62d789e31a2e51c57c794a82802c94cd3925e7d49; const STRATEGY_TYPEHASH: felt252 = 0x39154ec0efadcd0deffdfc2044cf45dd986d260e59c26d69564b50a18f40f6b; const INDEXED_STRATEGY_TYPEHASH: felt252 = 0x1f464f3e668281a899c5f3fc74a009ccd1df05fd0b9331b0460dc3f8054f64c; +const U256_TYPEHASH: felt252 = 0x1094260a770342332e6a73e9256b901d484a438925316205b4b6ff25df4a97a; diff --git a/starknet/src/utils/signatures.cairo b/starknet/src/utils/signatures.cairo index 9ab60a1c..35cad8bc 100644 --- a/starknet/src/utils/signatures.cairo +++ b/starknet/src/utils/signatures.cairo @@ -72,6 +72,7 @@ impl KeccakTypeHashIndexedStrategyArray of KeccakTypeHash break (); } encoded_data.append(self.at(i).clone().hash()); + i += 1; }; keccak::keccak_u256s_le_inputs(encoded_data.span()) } diff --git a/starknet/src/utils/stark_signatures.cairo b/starknet/src/utils/stark_signatures.cairo index 8082e069..5f01d3dd 100644 --- a/starknet/src/utils/stark_signatures.cairo +++ b/starknet/src/utils/stark_signatures.cairo @@ -9,7 +9,7 @@ use integer::u256_from_felt252; use sx::utils::types::{Strategy, IndexedStrategy, Choice, Felt252ArrayIntoU256Array}; use sx::utils::math::pow; use sx::utils::constants::{ - STARKNET_MESSAGE, DOMAIN_HASH, STRATEGY_TYPEHASH, INDEXED_STRATEGY_TYPEHASH, PROPOSE_TYPEHASH, + STARKNET_MESSAGE, DOMAIN_HASH, STRATEGY_TYPEHASH, INDEXED_STRATEGY_TYPEHASH, U256_TYPEHASH, PROPOSE_TYPEHASH, VOTE_TYPEHASH, UPDATE_PROPOSAL_TYPEHASH }; @@ -70,11 +70,21 @@ impl StructHashIndexedStrategySpan of StructHash> { break (); }; encoded_data.append((*self).at(i).struct_hash()); + i += 1; }; encoded_data.span().struct_hash() } } +impl StructHashU256 of StructHash { + fn struct_hash(self: @u256) -> felt252 { + let mut encoded_data = ArrayTrait::::new(); + U256_TYPEHASH.serialize(ref encoded_data); + self.serialize(ref encoded_data); + encoded_data.span().struct_hash() + } +} + // Reverts if the signature was not signed by the author. fn verify_propose_sig( r: felt252, @@ -99,7 +109,7 @@ fn verify_vote_sig( voter: ContractAddress, proposal_id: u256, choice: Choice, - user_voting_strategies: Span, + user_voting_strategies: Array, public_key: felt252 ) { let digest: felt252 = get_vote_digest( @@ -124,7 +134,6 @@ fn verify_update_proposal_sig( assert(check_ecdsa_signature(digest, public_key, r, s), 'Invalid signature'); } - fn get_propose_digest( space: ContractAddress, author: ContractAddress, @@ -147,15 +156,15 @@ fn get_vote_digest( voter: ContractAddress, proposal_id: u256, choice: Choice, - user_voting_strategies: Span + user_voting_strategies: Array ) -> felt252 { let mut encoded_data = ArrayTrait::::new(); VOTE_TYPEHASH.serialize(ref encoded_data); space.serialize(ref encoded_data); voter.serialize(ref encoded_data); - proposal_id.serialize(ref encoded_data); + proposal_id.struct_hash().serialize(ref encoded_data); choice.serialize(ref encoded_data); - user_voting_strategies.struct_hash().serialize(ref encoded_data); + user_voting_strategies.span().struct_hash().serialize(ref encoded_data); hash_typed_data(encoded_data.span().struct_hash(), voter) } @@ -170,7 +179,7 @@ fn get_update_proposal_digest( UPDATE_PROPOSAL_TYPEHASH.serialize(ref encoded_data); space.serialize(ref encoded_data); author.serialize(ref encoded_data); - proposal_id.serialize(ref encoded_data); + proposal_id.struct_hash().serialize(ref encoded_data); execution_strategy.struct_hash().serialize(ref encoded_data); salt.serialize(ref encoded_data); hash_typed_data(encoded_data.span().struct_hash(), author) diff --git a/starknet/tests/deploy-stark-sig-auth.ts b/starknet/tests/deploy-stark-sig-auth.ts index 711d8e14..784ac562 100644 --- a/starknet/tests/deploy-stark-sig-auth.ts +++ b/starknet/tests/deploy-stark-sig-auth.ts @@ -1,27 +1,32 @@ -import fs from "fs"; +import fs from 'fs'; import dotenv from 'dotenv'; -import { Account, json, Provider, CallData, Calldata } from "starknet"; +import { Account, json, Provider } from 'starknet'; dotenv.config(); -const pk = process.env.PRIVATE_KEY || ''; - async function main() { - // connect provider - const provider = new Provider({ sequencer: { baseUrl:"http://127.0.0.1:5050"} }); - console.log('provider=', provider); - // new Open Zeppelin account v0.5.1 : - // Generate public and private key pair. - const privateKey0 = "0xe3e70682c2094cac629f6fbed82c07cd"; - const address0 = "0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a"; - const account0 = new Account(provider, address0, privateKey0); + // connect provider + const provider = new Provider({ sequencer: { baseUrl: 'http://127.0.0.1:5050' } }); + console.log('provider=', provider); + // new Open Zeppelin account v0.5.1 : + // Generate public and private key pair. + const privateKey0 = '0xe3e70682c2094cac629f6fbed82c07cd'; + const address0 = '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a'; + const account0 = new Account(provider, address0, privateKey0); - // Declare & deploy Test contract in devnet - const compiledContractSierra = json.parse(fs.readFileSync( "starknet/target/dev/sx_StarkSigAuthenticator.sierra.json").toString( "ascii")); - const compiledContractCasm = json.parse(fs.readFileSync( "starknet/target/dev/sx_StarkSigAuthenticator.casm.json").toString( "ascii")); + // Declare & deploy Test contract in devnet + const compiledContractSierra = json.parse( + fs.readFileSync('starknet/target/dev/sx_StarkSigAuthenticator.sierra.json').toString('ascii'), + ); + const compiledContractCasm = json.parse( + fs.readFileSync('starknet/target/dev/sx_StarkSigAuthenticator.casm.json').toString('ascii'), + ); - const deployResponse = await account0.declareAndDeploy({ contract: compiledContractSierra, casm: compiledContractCasm}); - console.log('deployResponse=', deployResponse); + const deployResponse = await account0.declareAndDeploy({ + contract: compiledContractSierra, + casm: compiledContractCasm, + }); + console.log('deployResponse=', deployResponse); } main() @@ -29,4 +34,4 @@ main() .catch((error) => { console.error(error); process.exit(1); - }); \ No newline at end of file + }); diff --git a/starknet/tests/stark-sig.ts b/starknet/tests/stark-sig.ts index 7b2a4304..4c141ece 100644 --- a/starknet/tests/stark-sig.ts +++ b/starknet/tests/stark-sig.ts @@ -1,62 +1,133 @@ -import fs from "fs"; import dotenv from 'dotenv'; -import { Provider, Account, Contract, CallData, Calldata, typedData, cairo} from "starknet"; -import { proposeTypes, Propose, StarknetSigProposeCalldata, domain } from "./types"; +import { Provider, Account, CallData, typedData } from 'starknet'; +import { + proposeTypes, + voteTypes, + updateProposalTypes, + Propose, + Vote, + UpdateProposal, + StarknetSigProposeCalldata, + StarknetSigVoteCalldata, + StarknetSigUpdateProposalCalldata, + domain, +} from './types'; dotenv.config(); -const pk = process.env.PRIVATE_KEY || ''; - async function main() { - const provider = new Provider({ sequencer: { baseUrl:"http://127.0.0.1:5050"} }); - - const privateKey0 = "0xe3e70682c2094cac629f6fbed82c07cd"; - const address0 = "0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a"; - const publickey0 = "0x7e52885445756b313ea16849145363ccb73fb4ab0440dbac333cf9d13de82b9" - const account0 = new Account(provider, address0, privateKey0); - - const starkSigAuthAddress = "0x2baf1877b1388d8421485c8cb419b37ebce3096e323c4ef6b3c979a8a30917e"; - - const {abi: starkSigAuthAbi} = await provider.getClassAt(starkSigAuthAddress); - const starkSigAuth = new Contract(starkSigAuthAbi, starkSigAuthAddress, provider); - - const proposeMsg: Propose = { - space: "0x0000000000000000000000000000000000007777", - author: "0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a", - executionStrategy: { - address: "0x0000000000000000000000000000000000001234", - params: ["0x5", "0x6", "0x7", "0x8"] - }, - userProposalValidationParams: ["0x1", "0x2", "0x3", "0x4"], - salt: "0x0" - } - - const proposeData: typedData.TypedData = { - types: proposeTypes, - primaryType: "Propose", - domain: domain, - message: proposeMsg as any - } - - const msgHash = typedData.getMessageHash(proposeData, address0); - - console.log('msgHash=', msgHash); - - const signature2 = await account0.signMessage(proposeData) as any; - - const proposeCalldata: StarknetSigProposeCalldata = { - r: signature2.r, - s: signature2.s, - ...proposeMsg, - public_key: publickey0 - } - - const result = await account0.execute({ - contractAddress: starkSigAuthAddress, - entrypoint: "authenticate_propose", - calldata: CallData.compile(proposeCalldata as any) - }) - console.log(result); + const provider = new Provider({ sequencer: { baseUrl: 'http://127.0.0.1:5050' } }); + + const privateKey0 = '0xe3e70682c2094cac629f6fbed82c07cd'; + const address0 = '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a'; + const publickey0 = '0x7e52885445756b313ea16849145363ccb73fb4ab0440dbac333cf9d13de82b9'; + const account0 = new Account(provider, address0, privateKey0); + + const starkSigAuthAddress = '0x20d7169022756f2d8b63d5c2ad8fa812c43dcdc9041f306129d6f7ec4730e51'; + + // PROPOSE + + const proposeMsg: Propose = { + space: '0x0000000000000000000000000000000000007777', + author: '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a', + executionStrategy: { + address: '0x0000000000000000000000000000000000001234', + params: ['0x5', '0x6', '0x7', '0x8'], + }, + userProposalValidationParams: ['0x1', '0x2', '0x3', '0x4'], + salt: '0x0', + }; + + const proposeData: typedData.TypedData = { + types: proposeTypes, + primaryType: 'Propose', + domain: domain, + message: proposeMsg as any, + }; + + const proposeSig = (await account0.signMessage(proposeData)) as any; + + const proposeCalldata: StarknetSigProposeCalldata = { + r: proposeSig.r, + s: proposeSig.s, + ...proposeMsg, + public_key: publickey0, + }; + + await account0.execute({ + contractAddress: starkSigAuthAddress, + entrypoint: 'authenticate_propose', + calldata: CallData.compile(proposeCalldata as any), + }); + + // VOTE + + const voteMsg: Vote = { + space: '0x0000000000000000000000000000000000007777', + voter: '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a', + proposalId: { low: '0x1', high: '0x0' }, + choice: '0x1', + userVotingStrategies: [ + { index: '0x1', params: ['0x1', '0x2', '0x3', '0x4'] }, + { index: '0x2', params: [] }, + ], + }; + + const voteData: typedData.TypedData = { + types: voteTypes, + primaryType: 'Vote', + domain: domain, + message: voteMsg as any, + }; + + const voteSig = (await account0.signMessage(voteData)) as any; + + const voteCalldata: StarknetSigVoteCalldata = { + r: voteSig.r, + s: voteSig.s, + ...voteMsg, + public_key: publickey0, + }; + + await account0.execute({ + contractAddress: starkSigAuthAddress, + entrypoint: 'authenticate_vote', + calldata: CallData.compile(voteCalldata as any), + }); + + // UPDATE PROPOSAL + + const updateProposalMsg: UpdateProposal = { + space: '0x0000000000000000000000000000000000007777', + author: '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a', + proposalId: { low: '0x1', high: '0x0' }, + executionStrategy: { + address: '0x0000000000000000000000000000000000001234', + params: ['0x5', '0x6', '0x7', '0x8'], + }, + salt: '0x0', + }; + const updateProposalData: typedData.TypedData = { + types: updateProposalTypes, + primaryType: 'UpdateProposal', + domain: domain, + message: updateProposalMsg as any, + }; + + const updateProposalSig = (await account0.signMessage(updateProposalData)) as any; + + const updateProposalCalldata: StarknetSigUpdateProposalCalldata = { + r: updateProposalSig.r, + s: updateProposalSig.s, + ...updateProposalMsg, + public_key: publickey0, + }; + + await account0.execute({ + contractAddress: starkSigAuthAddress, + entrypoint: 'authenticate_update_proposal', + calldata: CallData.compile(updateProposalCalldata as any), + }); } main() diff --git a/starknet/tests/types.ts b/starknet/tests/types.ts index 1c8cb4e2..c959854c 100644 --- a/starknet/tests/types.ts +++ b/starknet/tests/types.ts @@ -1,47 +1,127 @@ export const domain = { - name: "1", // put the name of your dapp to ensure that the signatures will not be used by other DAPP - version: "1", - chainId: "0x534e5f474f45524c49" // devnet id -} + name: '1', // put the name of your dapp to ensure that the signatures will not be used by other DAPP + version: '1', + chainId: '0x534e5f474f45524c49', // devnet id +}; export const domainTypes = { - StarkNetDomain: [ - { name: "name", type: "felt252" }, - { name: "version", type: "felt252" }, - { name: "chainId", type: "felt252" }, - ], - }; + StarkNetDomain: [ + { name: 'name', type: 'felt252' }, + { name: 'version', type: 'felt252' }, + { name: 'chainId', type: 'felt252' }, + ], +}; export const proposeTypes = { - StarkNetDomain: domainTypes.StarkNetDomain, - Propose: [ - { name: 'space', type: 'ContractAddress' }, - { name: 'author', type: 'ContractAddress' }, - { name: 'executionStrategy', type: 'Strategy' }, - { name: 'userProposalValidationParams', type: 'felt*' }, - { name: 'salt', type: 'felt252' } - ], - Strategy: [ - { name: "address", type: "felt252" }, - { name: "params", type: "felt*" } - ], - }; + StarkNetDomain: domainTypes.StarkNetDomain, + Propose: [ + { name: 'space', type: 'ContractAddress' }, + { name: 'author', type: 'ContractAddress' }, + { name: 'executionStrategy', type: 'Strategy' }, + { name: 'userProposalValidationParams', type: 'felt*' }, + { name: 'salt', type: 'felt252' }, + ], + Strategy: [ + { name: 'address', type: 'felt252' }, + { name: 'params', type: 'felt*' }, + ], +}; + +export const voteTypes = { + StarkNetDomain: domainTypes.StarkNetDomain, + Vote: [ + { name: 'space', type: 'ContractAddress' }, + { name: 'voter', type: 'ContractAddress' }, + { name: 'proposalId', type: 'u256' }, + { name: 'choice', type: 'felt252' }, + { name: 'userVotingStrategies', type: 'IndexedStrategy*' }, + ], + IndexedStrategy: [ + { name: 'index', type: 'felt252' }, + { name: 'params', type: 'felt*' }, + ], + u256: [ + { name: 'low', type: 'felt252' }, + { name: 'high', type: 'felt252' }, + ], +}; + +export const updateProposalTypes = { + StarkNetDomain: [ + { name: 'name', type: 'felt252' }, + { name: 'version', type: 'felt252' }, + { name: 'chainId', type: 'felt252' }, + ], + UpdateProposal: [ + { name: 'space', type: 'ContractAddress' }, + { name: 'author', type: 'ContractAddress' }, + { name: 'proposalId', type: 'u256' }, + { name: 'executionStrategy', type: 'Strategy' }, + { name: 'salt', type: 'felt252' }, + ], + Strategy: [ + { name: 'address', type: 'felt252' }, + { name: 'params', type: 'felt*' }, + ], + u256: [ + { name: 'low', type: 'felt252' }, + { name: 'high', type: 'felt252' }, + ], +}; export interface Strategy { - address: string; - params: string[]; + address: string; + params: string[]; +} + +export interface IndexedStrategy { + index: string; + params: string[]; +} + +export interface u256 { + low: string; + high: string; } export interface Propose { - space: string; - author: string; - executionStrategy: Strategy; - userProposalValidationParams: string[]; - salt: string; + space: string; + author: string; + executionStrategy: Strategy; + userProposalValidationParams: string[]; + salt: string; +} + +export interface Vote { + space: string; + voter: string; + proposalId: u256; + choice: string; + userVotingStrategies: IndexedStrategy[]; +} + +export interface UpdateProposal { + space: string; + author: string; + proposalId: u256; + executionStrategy: Strategy; + salt: string; } export interface StarknetSigProposeCalldata extends Propose { - r: string; - s: string; - public_key: string; + r: string; + s: string; + public_key: string; +} + +export interface StarknetSigVoteCalldata extends Vote { + r: string; + s: string; + public_key: string; +} + +export interface StarknetSigUpdateProposalCalldata extends UpdateProposal { + r: string; + s: string; + public_key: string; } From d624029389400cd8b321d2810c6de48a1ce031fc Mon Sep 17 00:00:00 2001 From: Orlando Date: Wed, 2 Aug 2023 18:30:50 +0100 Subject: [PATCH 12/25] feat: compute domain hash --- starknet/src/authenticators/stark_sig.cairo | 95 ++++++++++----------- starknet/src/utils/constants.cairo | 5 +- starknet/src/utils/stark_signatures.cairo | 41 ++++++--- 3 files changed, 79 insertions(+), 62 deletions(-) diff --git a/starknet/src/authenticators/stark_sig.cairo b/starknet/src/authenticators/stark_sig.cairo index acf5fb2f..f6da8590 100644 --- a/starknet/src/authenticators/stark_sig.cairo +++ b/starknet/src/authenticators/stark_sig.cairo @@ -37,38 +37,6 @@ trait IStarkSigAuthenticator { salt: felt252, public_key: felt252 ); - fn propose_hash( - self: @TContractState, - r: felt252, - s: felt252, - target: ContractAddress, - author: ContractAddress, - execution_strategy: Strategy, - user_proposal_validation_params: Array, - salt: felt252 - ) -> felt252; - fn vote_hash( - self: @TContractState, - r: felt252, - s: felt252, - target: ContractAddress, - voter: ContractAddress, - proposal_id: u256, - choice: Choice, - user_voting_strategies: Array, - public_key: felt252 - ) -> felt252; - fn encoded_vote( - self: @TContractState, - r: felt252, - s: felt252, - target: ContractAddress, - author: ContractAddress, - proposal_id: u256, - execution_strategy: Strategy, - salt: felt252, - public_key: felt252 - ) -> Array; } #[starknet::contract] @@ -82,6 +50,7 @@ mod StarkSigAuthenticator { use sx::space::space::{ISpaceDispatcher, ISpaceDispatcherTrait}; use sx::utils::types::{Strategy, IndexedStrategy, Choice}; use sx::utils::stark_signatures; + use sx::interfaces::{IAccountDispatcher, IAccountDispatcherTrait}; #[storage] struct Storage { @@ -103,6 +72,7 @@ mod StarkSigAuthenticator { public_key: felt252, ) { stark_signatures::verify_propose_sig( + self._domain_hash.read(), r, s, target, @@ -112,10 +82,10 @@ mod StarkSigAuthenticator { salt, public_key ); - // Check public key corresponds to the author account address. - - // self._used_salts.write((author, salt), true); + // Check public key corresponds to the author account address. + assert_valid_account(author, public_key); + self._used_salts.write((author, salt), true); // ISpaceDispatcher { // contract_address: target // }.propose(author, execution_strategy, user_proposal_validation_params); @@ -133,16 +103,24 @@ mod StarkSigAuthenticator { public_key: felt252 ) { stark_signatures::verify_vote_sig( - r, s, target, voter, proposal_id, choice, user_voting_strategies, public_key + self._domain_hash.read(), + r, + s, + target, + voter, + proposal_id, + choice, + user_voting_strategies, + public_key ); // Check public key corresponds to the voter account address. + assert_valid_account(voter, public_key); + // No need to check salts here, as double voting is prevented by the space itself. - // No need to check salts here, as double voting is prevented by the space itself. - - // ISpaceDispatcher { - // contract_address: target - // }.vote(voter, proposal_id, choice, user_voting_strategies); + // ISpaceDispatcher { + // contract_address: target + // }.vote(voter, proposal_id, choice, user_voting_strategies); } fn authenticate_update_proposal( @@ -157,19 +135,38 @@ mod StarkSigAuthenticator { public_key: felt252 ) { stark_signatures::verify_update_proposal_sig( - r, s, target, author, proposal_id, execution_strategy, salt, public_key + self._domain_hash.read(), + r, + s, + target, + author, + proposal_id, + execution_strategy, + salt, + public_key ); - // Check public key corresponds to the author account address. - - // self._used_salts.write((author, salt), true); + // Check public key corresponds to the author account address. + assert_valid_account(author, public_key); + self._used_salts.write((author, salt), true); // ISpaceDispatcher { // contract_address: target // }.update_proposal(author, proposal_id, execution_strategy); } } -// #[constructor] -// fn constructor(ref self: ContractState, name: felt252, version: felt252) {// TODO: domain hash is immutable so could be placed in the contract code instead of storage to save on reads. -// // self._domain_hash.write(signatures::get_domain_hash(name, version)); -// } + #[constructor] + fn constructor( + ref self: ContractState, name: felt252, version: felt252 + ) { // TODO: domain hash is immutable so could be placed in the contract code instead of storage to save on reads. + self._domain_hash.write(stark_signatures::get_domain_hash(name, version)); + } + + fn assert_valid_account(address: ContractAddress, public_key: felt252) { + // TODO: should query the supportsInterface function before calling getPublicKey. + // What should the interface id be? + assert( + IAccountDispatcher { contract_address: address }.getPublicKey() == public_key, + 'Invalid public key' + ); + } } diff --git a/starknet/src/utils/constants.cairo b/starknet/src/utils/constants.cairo index c2aff30a..cf49aeef 100644 --- a/starknet/src/utils/constants.cairo +++ b/starknet/src/utils/constants.cairo @@ -48,10 +48,11 @@ const INDEXED_STRATEGY_TYPEHASH_LOW: u128 = 0x8b36195eec0090e913c01e7534729c74; // TODO: Add comments containing pre-images of the constants const STARKNET_MESSAGE: felt252 = 0x537461726b4e6574204d657373616765; -const DOMAIN_HASH: felt252 = 0x133d0430d262d06e2d4aff2851ca256738e40d43593c998ff664b5d5cb410d3; +const DOMAIN_TYPEHASH: felt252 = 0xa9974a36dee531bbc36aad5eeab4ade4df5ad388a296bb14d28ad4e9bf2164; const PROPOSE_TYPEHASH: felt252 = 0x1f8c9b1ab74c5990f89bac4c632dc405457352e22bbc7573a237989aa62cb60; const VOTE_TYPEHASH: felt252 = 0x1845db28c74470cdaa3cf6a1c5017d013586d70ffee45b519a5670e23fe9512; -const UPDATE_PROPOSAL_TYPEHASH: felt252 = 0x222b737bd5f9ba595cf15e62d789e31a2e51c57c794a82802c94cd3925e7d49; +const UPDATE_PROPOSAL_TYPEHASH: felt252 = + 0x222b737bd5f9ba595cf15e62d789e31a2e51c57c794a82802c94cd3925e7d49; const STRATEGY_TYPEHASH: felt252 = 0x39154ec0efadcd0deffdfc2044cf45dd986d260e59c26d69564b50a18f40f6b; const INDEXED_STRATEGY_TYPEHASH: felt252 = diff --git a/starknet/src/utils/stark_signatures.cairo b/starknet/src/utils/stark_signatures.cairo index 5f01d3dd..3ede1d87 100644 --- a/starknet/src/utils/stark_signatures.cairo +++ b/starknet/src/utils/stark_signatures.cairo @@ -1,6 +1,7 @@ -use starknet::{ContractAddress, contract_address_to_felt252}; +use starknet::{ContractAddress, contract_address_to_felt252, get_tx_info, get_contract_address}; use array::{ArrayTrait, SpanTrait}; use traits::Into; +use box::BoxTrait; use clone::Clone; use serde::Serde; use ecdsa::check_ecdsa_signature; @@ -9,8 +10,8 @@ use integer::u256_from_felt252; use sx::utils::types::{Strategy, IndexedStrategy, Choice, Felt252ArrayIntoU256Array}; use sx::utils::math::pow; use sx::utils::constants::{ - STARKNET_MESSAGE, DOMAIN_HASH, STRATEGY_TYPEHASH, INDEXED_STRATEGY_TYPEHASH, U256_TYPEHASH, PROPOSE_TYPEHASH, - VOTE_TYPEHASH, UPDATE_PROPOSAL_TYPEHASH + STARKNET_MESSAGE, DOMAIN_TYPEHASH, STRATEGY_TYPEHASH, INDEXED_STRATEGY_TYPEHASH, U256_TYPEHASH, + PROPOSE_TYPEHASH, VOTE_TYPEHASH, UPDATE_PROPOSAL_TYPEHASH }; impl LegacyHashSpanFelt252 of LegacyHash> { @@ -87,6 +88,7 @@ impl StructHashU256 of StructHash { // Reverts if the signature was not signed by the author. fn verify_propose_sig( + domain_hash: felt252, r: felt252, s: felt252, target: ContractAddress, @@ -97,12 +99,13 @@ fn verify_propose_sig( public_key: felt252 ) { let digest: felt252 = get_propose_digest( - target, author, execution_strategy, user_proposal_validation_params, salt + domain_hash, target, author, execution_strategy, user_proposal_validation_params, salt ); assert(check_ecdsa_signature(digest, public_key, r, s), 'Invalid signature'); } fn verify_vote_sig( + domain_hash: felt252, r: felt252, s: felt252, target: ContractAddress, @@ -113,12 +116,13 @@ fn verify_vote_sig( public_key: felt252 ) { let digest: felt252 = get_vote_digest( - target, voter, proposal_id, choice, user_voting_strategies + domain_hash, target, voter, proposal_id, choice, user_voting_strategies ); assert(check_ecdsa_signature(digest, public_key, r, s), 'Invalid signature'); } fn verify_update_proposal_sig( + domain_hash: felt252, r: felt252, s: felt252, target: ContractAddress, @@ -129,12 +133,13 @@ fn verify_update_proposal_sig( public_key: felt252 ) { let digest: felt252 = get_update_proposal_digest( - target, author, proposal_id, execution_strategy, salt + domain_hash, target, author, proposal_id, execution_strategy, salt ); assert(check_ecdsa_signature(digest, public_key, r, s), 'Invalid signature'); } fn get_propose_digest( + domain_hash: felt252, space: ContractAddress, author: ContractAddress, execution_strategy: Strategy, @@ -148,10 +153,11 @@ fn get_propose_digest( execution_strategy.struct_hash().serialize(ref encoded_data); user_proposal_validation_params.span().struct_hash().serialize(ref encoded_data); salt.serialize(ref encoded_data); - hash_typed_data(encoded_data.span().struct_hash(), author) + hash_typed_data(domain_hash, encoded_data.span().struct_hash(), author) } fn get_vote_digest( + domain_hash: felt252, space: ContractAddress, voter: ContractAddress, proposal_id: u256, @@ -165,10 +171,11 @@ fn get_vote_digest( proposal_id.struct_hash().serialize(ref encoded_data); choice.serialize(ref encoded_data); user_voting_strategies.span().struct_hash().serialize(ref encoded_data); - hash_typed_data(encoded_data.span().struct_hash(), voter) + hash_typed_data(domain_hash, encoded_data.span().struct_hash(), voter) } fn get_update_proposal_digest( + domain_hash: felt252, space: ContractAddress, author: ContractAddress, proposal_id: u256, @@ -182,13 +189,25 @@ fn get_update_proposal_digest( proposal_id.struct_hash().serialize(ref encoded_data); execution_strategy.struct_hash().serialize(ref encoded_data); salt.serialize(ref encoded_data); - hash_typed_data(encoded_data.span().struct_hash(), author) + hash_typed_data(domain_hash, encoded_data.span().struct_hash(), author) } -fn hash_typed_data(message_hash: felt252, signer: ContractAddress) -> felt252 { +fn get_domain_hash(name: felt252, version: felt252) -> felt252 { + let mut encoded_data = ArrayTrait::::new(); + DOMAIN_TYPEHASH.serialize(ref encoded_data); + name.serialize(ref encoded_data); + version.serialize(ref encoded_data); + get_tx_info().unbox().chain_id.serialize(ref encoded_data); + get_contract_address().serialize(ref encoded_data); + encoded_data.span().struct_hash() +} + +fn hash_typed_data( + domain_hash: felt252, message_hash: felt252, signer: ContractAddress +) -> felt252 { let mut encoded_data = ArrayTrait::::new(); STARKNET_MESSAGE.serialize(ref encoded_data); - DOMAIN_HASH.serialize(ref encoded_data); + domain_hash.serialize(ref encoded_data); signer.serialize(ref encoded_data); message_hash.serialize(ref encoded_data); encoded_data.span().struct_hash() From e8398657e84e0f91a107f0f53688d336e43da34e Mon Sep 17 00:00:00 2001 From: Orlando Date: Wed, 2 Aug 2023 18:31:20 +0100 Subject: [PATCH 13/25] chore: account inteface --- starknet/src/interfaces.cairo | 2 ++ starknet/src/interfaces/i_account.cairo | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 starknet/src/interfaces/i_account.cairo diff --git a/starknet/src/interfaces.cairo b/starknet/src/interfaces.cairo index 010d25f7..58218ffa 100644 --- a/starknet/src/interfaces.cairo +++ b/starknet/src/interfaces.cairo @@ -1,6 +1,7 @@ mod i_voting_strategy; mod i_execution_strategy; mod i_proposal_validation_strategy; +mod i_account; use i_voting_strategy::{IVotingStrategy, IVotingStrategyDispatcher, IVotingStrategyDispatcherTrait}; use i_execution_strategy::{ @@ -10,3 +11,4 @@ use i_proposal_validation_strategy::{ IProposalValidationStrategy, IProposalValidationStrategyDispatcher, IProposalValidationStrategyDispatcherTrait }; +use i_account::{IAccount, IAccountDispatcher, IAccountDispatcherTrait}; diff --git a/starknet/src/interfaces/i_account.cairo b/starknet/src/interfaces/i_account.cairo new file mode 100644 index 00000000..682b3dbb --- /dev/null +++ b/starknet/src/interfaces/i_account.cairo @@ -0,0 +1,18 @@ +use array::ArrayTrait; +use array::SpanTrait; +use starknet::account::Call; +use starknet::ContractAddress; + +#[starknet::interface] +trait IAccount { + fn __execute__(self: @TState, calls: Array) -> Array>; + fn __validate__(self: @TState, calls: Array) -> felt252; + fn __validate_declare__(self: @TState, classHash: felt252) -> felt252; + fn __validate_deploy__( + self: @TState, classHash: felt252, contractAddressSalt: felt252, _publicKey: felt252 + ) -> felt252; + fn setPublicKey(ref self: TState, newPublicKey: felt252); + fn getPublicKey(self: @TState) -> felt252; + fn isValidSignature(self: @TState, hash: felt252, signature: Array) -> felt252; + fn supportsInterface(self: @TState, interfaceId: felt252) -> bool; +} From 1faa74d8d4fb741ad4521d2564ec6cb8a2f8e655 Mon Sep 17 00:00:00 2001 From: Orlando Date: Wed, 2 Aug 2023 18:31:51 +0100 Subject: [PATCH 14/25] chore: updated tests --- starknet/tests/deploy-stark-sig-auth.ts | 8 +++++++- starknet/tests/stark-sig.ts | 10 ++++++++-- starknet/tests/types.ts | 13 ++----------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/starknet/tests/deploy-stark-sig-auth.ts b/starknet/tests/deploy-stark-sig-auth.ts index 784ac562..f0173bae 100644 --- a/starknet/tests/deploy-stark-sig-auth.ts +++ b/starknet/tests/deploy-stark-sig-auth.ts @@ -1,6 +1,6 @@ import fs from 'fs'; import dotenv from 'dotenv'; -import { Account, json, Provider } from 'starknet'; +import { Account, json, Provider, CallData, Calldata} from 'starknet'; dotenv.config(); @@ -22,9 +22,15 @@ async function main() { fs.readFileSync('starknet/target/dev/sx_StarkSigAuthenticator.casm.json').toString('ascii'), ); + const contractConstructor: Calldata = CallData.compile({ + name: 'sx-sn', + version: '0.1.0', + }); + const deployResponse = await account0.declareAndDeploy({ contract: compiledContractSierra, casm: compiledContractCasm, + constructorCalldata: contractConstructor, }); console.log('deployResponse=', deployResponse); } diff --git a/starknet/tests/stark-sig.ts b/starknet/tests/stark-sig.ts index 4c141ece..d726de66 100644 --- a/starknet/tests/stark-sig.ts +++ b/starknet/tests/stark-sig.ts @@ -10,7 +10,6 @@ import { StarknetSigProposeCalldata, StarknetSigVoteCalldata, StarknetSigUpdateProposalCalldata, - domain, } from './types'; dotenv.config(); @@ -23,7 +22,14 @@ async function main() { const publickey0 = '0x7e52885445756b313ea16849145363ccb73fb4ab0440dbac333cf9d13de82b9'; const account0 = new Account(provider, address0, privateKey0); - const starkSigAuthAddress = '0x20d7169022756f2d8b63d5c2ad8fa812c43dcdc9041f306129d6f7ec4730e51'; + const starkSigAuthAddress = '0x25e72fe267e1d1adc59812dbdde56fb8e5156bb29d5f11ff1dd6317fca682fb'; + + const domain = { + name: 'sx-sn', + version: '0.1.0', + chainId: '0x534e5f474f45524c49', // devnet id + verifyingContract: starkSigAuthAddress, + }; // PROPOSE diff --git a/starknet/tests/types.ts b/starknet/tests/types.ts index c959854c..8cc22262 100644 --- a/starknet/tests/types.ts +++ b/starknet/tests/types.ts @@ -1,14 +1,9 @@ -export const domain = { - name: '1', // put the name of your dapp to ensure that the signatures will not be used by other DAPP - version: '1', - chainId: '0x534e5f474f45524c49', // devnet id -}; - export const domainTypes = { StarkNetDomain: [ { name: 'name', type: 'felt252' }, { name: 'version', type: 'felt252' }, { name: 'chainId', type: 'felt252' }, + { name: 'verifyingContract', type: 'ContractAddress' }, ], }; @@ -47,11 +42,7 @@ export const voteTypes = { }; export const updateProposalTypes = { - StarkNetDomain: [ - { name: 'name', type: 'felt252' }, - { name: 'version', type: 'felt252' }, - { name: 'chainId', type: 'felt252' }, - ], + StarkNetDomain: domainTypes.StarkNetDomain, UpdateProposal: [ { name: 'space', type: 'ContractAddress' }, { name: 'author', type: 'ContractAddress' }, From 5d1f8a20e911a8b6ce3601cf182ddbcca9f80f2b Mon Sep 17 00:00:00 2001 From: Orlando Date: Thu, 3 Aug 2023 17:51:27 +0100 Subject: [PATCH 15/25] feat: use er165 to check account and sig --- starknet/src/authenticators/stark_sig.cairo | 88 ++++------- starknet/src/interfaces.cairo | 5 +- starknet/src/interfaces/i_account.cairo | 17 ++- starknet/src/utils/stark_signatures.cairo | 80 +++++++--- starknet/tests/stark-sig.test.ts | 159 ++++++++++++++++++++ 5 files changed, 268 insertions(+), 81 deletions(-) create mode 100644 starknet/tests/stark-sig.test.ts diff --git a/starknet/src/authenticators/stark_sig.cairo b/starknet/src/authenticators/stark_sig.cairo index f6da8590..440a227a 100644 --- a/starknet/src/authenticators/stark_sig.cairo +++ b/starknet/src/authenticators/stark_sig.cairo @@ -6,36 +6,33 @@ use sx::utils::types::{Strategy, IndexedStrategy, Choice}; trait IStarkSigAuthenticator { fn authenticate_propose( ref self: TContractState, - r: felt252, - s: felt252, + signature: Array, target: ContractAddress, author: ContractAddress, execution_strategy: Strategy, user_proposal_validation_params: Array, salt: felt252, - public_key: felt252, + account_type: felt252 ); fn authenticate_vote( ref self: TContractState, - r: felt252, - s: felt252, + signature: Array, target: ContractAddress, voter: ContractAddress, proposal_id: u256, choice: Choice, user_voting_strategies: Array, - public_key: felt252 + account_type: felt252 ); fn authenticate_update_proposal( ref self: TContractState, - r: felt252, - s: felt252, + signature: Array, target: ContractAddress, author: ContractAddress, proposal_id: u256, execution_strategy: Strategy, salt: felt252, - public_key: felt252 + account_type: felt252 ); } @@ -50,7 +47,6 @@ mod StarkSigAuthenticator { use sx::space::space::{ISpaceDispatcher, ISpaceDispatcherTrait}; use sx::utils::types::{Strategy, IndexedStrategy, Choice}; use sx::utils::stark_signatures; - use sx::interfaces::{IAccountDispatcher, IAccountDispatcherTrait}; #[storage] struct Storage { @@ -62,96 +58,83 @@ mod StarkSigAuthenticator { impl StarkSigAuthenticator of IStarkSigAuthenticator { fn authenticate_propose( ref self: ContractState, - r: felt252, - s: felt252, + signature: Array, target: ContractAddress, author: ContractAddress, execution_strategy: Strategy, user_proposal_validation_params: Array, salt: felt252, - public_key: felt252, + account_type: felt252 ) { stark_signatures::verify_propose_sig( self._domain_hash.read(), - r, - s, + signature, target, author, - execution_strategy, - user_proposal_validation_params, + @execution_strategy, + user_proposal_validation_params.span(), salt, - public_key + account_type ); - // Check public key corresponds to the author account address. - assert_valid_account(author, public_key); self._used_salts.write((author, salt), true); - // ISpaceDispatcher { - // contract_address: target - // }.propose(author, execution_strategy, user_proposal_validation_params); + ISpaceDispatcher { + contract_address: target + }.propose(author, execution_strategy, user_proposal_validation_params); } fn authenticate_vote( ref self: ContractState, - r: felt252, - s: felt252, + signature: Array, target: ContractAddress, voter: ContractAddress, proposal_id: u256, choice: Choice, user_voting_strategies: Array, - public_key: felt252 + account_type: felt252 ) { stark_signatures::verify_vote_sig( self._domain_hash.read(), - r, - s, + signature, target, voter, proposal_id, choice, - user_voting_strategies, - public_key + user_voting_strategies.span(), + account_type ); - - // Check public key corresponds to the voter account address. - assert_valid_account(voter, public_key); // No need to check salts here, as double voting is prevented by the space itself. - // ISpaceDispatcher { - // contract_address: target - // }.vote(voter, proposal_id, choice, user_voting_strategies); + ISpaceDispatcher { + contract_address: target + }.vote(voter, proposal_id, choice, user_voting_strategies); } fn authenticate_update_proposal( ref self: ContractState, - r: felt252, - s: felt252, + signature: Array, target: ContractAddress, author: ContractAddress, proposal_id: u256, execution_strategy: Strategy, salt: felt252, - public_key: felt252 + account_type: felt252 ) { stark_signatures::verify_update_proposal_sig( self._domain_hash.read(), - r, - s, + signature, target, author, proposal_id, - execution_strategy, + @execution_strategy, salt, - public_key + account_type ); - // Check public key corresponds to the author account address. - assert_valid_account(author, public_key); self._used_salts.write((author, salt), true); - // ISpaceDispatcher { - // contract_address: target - // }.update_proposal(author, proposal_id, execution_strategy); + ISpaceDispatcher { + contract_address: target + }.update_proposal(author, proposal_id, execution_strategy); } } #[constructor] @@ -160,13 +143,4 @@ mod StarkSigAuthenticator { ) { // TODO: domain hash is immutable so could be placed in the contract code instead of storage to save on reads. self._domain_hash.write(stark_signatures::get_domain_hash(name, version)); } - - fn assert_valid_account(address: ContractAddress, public_key: felt252) { - // TODO: should query the supportsInterface function before calling getPublicKey. - // What should the interface id be? - assert( - IAccountDispatcher { contract_address: address }.getPublicKey() == public_key, - 'Invalid public key' - ); - } } diff --git a/starknet/src/interfaces.cairo b/starknet/src/interfaces.cairo index 58218ffa..3b37529f 100644 --- a/starknet/src/interfaces.cairo +++ b/starknet/src/interfaces.cairo @@ -11,4 +11,7 @@ use i_proposal_validation_strategy::{ IProposalValidationStrategy, IProposalValidationStrategyDispatcher, IProposalValidationStrategyDispatcherTrait }; -use i_account::{IAccount, IAccountDispatcher, IAccountDispatcherTrait}; +use i_account::{ + AccountABI, AccountABIDispatcher, AccountABIDispatcherTrait, AccountCamelABI, + AccountCamelABIDispatcher, AccountCamelABIDispatcherTrait +}; diff --git a/starknet/src/interfaces/i_account.cairo b/starknet/src/interfaces/i_account.cairo index 682b3dbb..aafc7c5f 100644 --- a/starknet/src/interfaces/i_account.cairo +++ b/starknet/src/interfaces/i_account.cairo @@ -4,7 +4,22 @@ use starknet::account::Call; use starknet::ContractAddress; #[starknet::interface] -trait IAccount { +trait AccountABI { + fn __execute__(self: @TState, calls: Array) -> Array>; + fn __validate__(self: @TState, calls: Array) -> felt252; + fn __validate_declare__(self: @TState, class_hash: felt252) -> felt252; + fn __validate_deploy__( + self: @TState, class_hash: felt252, contract_address_salt: felt252, _public_key: felt252 + ) -> felt252; + fn set_public_key(ref self: TState, new_public_key: felt252); + fn get_public_key(self: @TState) -> felt252; + fn is_valid_signature(self: @TState, hash: felt252, signature: Array) -> felt252; + fn supports_interface(self: @TState, interface_id: felt252) -> bool; +} + +// Entry points case-convention is enforced by the protocol +#[starknet::interface] +trait AccountCamelABI { fn __execute__(self: @TState, calls: Array) -> Array>; fn __validate__(self: @TState, calls: Array) -> felt252; fn __validate_declare__(self: @TState, classHash: felt252) -> felt252; diff --git a/starknet/src/utils/stark_signatures.cairo b/starknet/src/utils/stark_signatures.cairo index 3ede1d87..04973dee 100644 --- a/starknet/src/utils/stark_signatures.cairo +++ b/starknet/src/utils/stark_signatures.cairo @@ -1,3 +1,4 @@ +use core::starknet::SyscallResultTrait; use starknet::{ContractAddress, contract_address_to_felt252, get_tx_info, get_contract_address}; use array::{ArrayTrait, SpanTrait}; use traits::Into; @@ -13,6 +14,10 @@ use sx::utils::constants::{ STARKNET_MESSAGE, DOMAIN_TYPEHASH, STRATEGY_TYPEHASH, INDEXED_STRATEGY_TYPEHASH, U256_TYPEHASH, PROPOSE_TYPEHASH, VOTE_TYPEHASH, UPDATE_PROPOSAL_TYPEHASH }; +use sx::interfaces::{ + AccountABIDispatcher, AccountABIDispatcherTrait, AccountCamelABIDispatcher, + AccountCamelABIDispatcherTrait +}; impl LegacyHashSpanFelt252 of LegacyHash> { fn hash(state: felt252, mut value: Span) -> felt252 { @@ -74,6 +79,19 @@ impl StructHashIndexedStrategySpan of StructHash> { i += 1; }; encoded_data.span().struct_hash() + + // let mut self_ = *self; + // let mut encoded_data = ArrayTrait::::new(); + // loop { + // match self_.pop_front() { + // Option::Some(item) => { + // encoded_data.append(item.struct_hash()); + // }, + // Option::None(_) => { + // break encoded_data.span().struct_hash(); + // }, + // }; + // } } } @@ -89,61 +107,59 @@ impl StructHashU256 of StructHash { // Reverts if the signature was not signed by the author. fn verify_propose_sig( domain_hash: felt252, - r: felt252, - s: felt252, + signature: Array, target: ContractAddress, author: ContractAddress, - execution_strategy: Strategy, - user_proposal_validation_params: Array, + execution_strategy: @Strategy, + user_proposal_validation_params: Span, salt: felt252, - public_key: felt252 + account_type: felt252, ) { let digest: felt252 = get_propose_digest( domain_hash, target, author, execution_strategy, user_proposal_validation_params, salt ); - assert(check_ecdsa_signature(digest, public_key, r, s), 'Invalid signature'); + + verify_signature(digest, signature, author, account_type); } fn verify_vote_sig( domain_hash: felt252, - r: felt252, - s: felt252, + signature: Array, target: ContractAddress, voter: ContractAddress, proposal_id: u256, choice: Choice, - user_voting_strategies: Array, - public_key: felt252 + user_voting_strategies: Span, + account_type: felt252, ) { let digest: felt252 = get_vote_digest( domain_hash, target, voter, proposal_id, choice, user_voting_strategies ); - assert(check_ecdsa_signature(digest, public_key, r, s), 'Invalid signature'); + verify_signature(digest, signature, voter, account_type); } fn verify_update_proposal_sig( domain_hash: felt252, - r: felt252, - s: felt252, + signature: Array, target: ContractAddress, author: ContractAddress, proposal_id: u256, - execution_strategy: Strategy, + execution_strategy: @Strategy, salt: felt252, - public_key: felt252 + account_type: felt252, ) { let digest: felt252 = get_update_proposal_digest( domain_hash, target, author, proposal_id, execution_strategy, salt ); - assert(check_ecdsa_signature(digest, public_key, r, s), 'Invalid signature'); + verify_signature(digest, signature, author, account_type); } fn get_propose_digest( domain_hash: felt252, space: ContractAddress, author: ContractAddress, - execution_strategy: Strategy, - user_proposal_validation_params: Array, + execution_strategy: @Strategy, + user_proposal_validation_params: Span, salt: felt252 ) -> felt252 { let mut encoded_data = ArrayTrait::::new(); @@ -151,7 +167,7 @@ fn get_propose_digest( space.serialize(ref encoded_data); author.serialize(ref encoded_data); execution_strategy.struct_hash().serialize(ref encoded_data); - user_proposal_validation_params.span().struct_hash().serialize(ref encoded_data); + user_proposal_validation_params.struct_hash().serialize(ref encoded_data); salt.serialize(ref encoded_data); hash_typed_data(domain_hash, encoded_data.span().struct_hash(), author) } @@ -162,7 +178,7 @@ fn get_vote_digest( voter: ContractAddress, proposal_id: u256, choice: Choice, - user_voting_strategies: Array + user_voting_strategies: Span ) -> felt252 { let mut encoded_data = ArrayTrait::::new(); VOTE_TYPEHASH.serialize(ref encoded_data); @@ -170,7 +186,7 @@ fn get_vote_digest( voter.serialize(ref encoded_data); proposal_id.struct_hash().serialize(ref encoded_data); choice.serialize(ref encoded_data); - user_voting_strategies.span().struct_hash().serialize(ref encoded_data); + user_voting_strategies.struct_hash().serialize(ref encoded_data); hash_typed_data(domain_hash, encoded_data.span().struct_hash(), voter) } @@ -179,7 +195,7 @@ fn get_update_proposal_digest( space: ContractAddress, author: ContractAddress, proposal_id: u256, - execution_strategy: Strategy, + execution_strategy: @Strategy, salt: felt252 ) -> felt252 { let mut encoded_data = ArrayTrait::::new(); @@ -212,3 +228,23 @@ fn hash_typed_data( message_hash.serialize(ref encoded_data); encoded_data.span().struct_hash() } + +/// Verifies the signature of a message by calling the account contract. +fn verify_signature(digest: felt252, signature: Array, account: ContractAddress, account_type: felt252) { + if account_type == 'camel' { + assert( + AccountCamelABIDispatcher { contract_address: account }.supportsInterface(0xa66bd575) == true, + 'Invalid Account' + ); + AccountCamelABIDispatcher { contract_address: account }.isValidSignature(digest, signature); + } else if account_type == 'snake' { + assert( + AccountABIDispatcher { contract_address: account }.supports_interface(0x01ffc9a7) == true, + 'Invalid Account' + ); + AccountABIDispatcher { contract_address: account }.is_valid_signature(digest, signature); + } else { + panic_with_felt252('Invalid Account Type'); + } + +} diff --git a/starknet/tests/stark-sig.test.ts b/starknet/tests/stark-sig.test.ts new file mode 100644 index 00000000..e7a22e43 --- /dev/null +++ b/starknet/tests/stark-sig.test.ts @@ -0,0 +1,159 @@ +import fs from 'fs'; +import dotenv from 'dotenv'; +import { Provider, Account, CallData, Calldata, typedData, json } from 'starknet'; +import { + proposeTypes, + voteTypes, + updateProposalTypes, + Propose, + Vote, + UpdateProposal, + StarknetSigProposeCalldata, + StarknetSigVoteCalldata, + StarknetSigUpdateProposalCalldata, +} from './types'; + +dotenv.config(); + +describe('Starknet Signature Authenticator', () => { + const provider = new Provider({ sequencer: { baseUrl: 'http://127.0.0.1:5050' } }); + // devnet predeployed account + const privateKey0 = '0xe3e70682c2094cac629f6fbed82c07cd'; + const address0 = '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a'; + const publickey0 = '0x7e52885445756b313ea16849145363ccb73fb4ab0440dbac333cf9d13de82b9'; + const account0 = new Account(provider, address0, privateKey0); + + let starkSigAuthAddress: string; + let domain: any; + + beforeAll(async () => { + const compiledContractSierra = json.parse( + fs.readFileSync('starknet/target/dev/sx_StarkSigAuthenticator.sierra.json').toString('ascii'), + ); + const compiledContractCasm = json.parse( + fs.readFileSync('starknet/target/dev/sx_StarkSigAuthenticator.casm.json').toString('ascii'), + ); + + const contractConstructor: Calldata = CallData.compile({ + name: 'sx-sn', + version: '0.1.0', + }); + + const deployResponse = await account0.declareAndDeploy({ + contract: compiledContractSierra, + casm: compiledContractCasm, + constructorCalldata: contractConstructor, + }); + starkSigAuthAddress = deployResponse.deploy.contract_address; + domain = { + name: 'sx-sn', + version: '0.1.0', + chainId: '0x534e5f474f45524c49', // devnet id + verifyingContract: starkSigAuthAddress, + }; + }, 100000); + test('can authenticate a proposal, a vote, and a proposal update', async () => { + // PROPOSE + const proposeMsg: Propose = { + space: '0x0000000000000000000000000000000000007777', + author: '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a', + executionStrategy: { + address: '0x0000000000000000000000000000000000001234', + params: ['0x5', '0x6', '0x7', '0x8'], + }, + userProposalValidationParams: ['0x1', '0x2', '0x3', '0x4'], + salt: '0x0', + }; + + const proposeData: typedData.TypedData = { + types: proposeTypes, + primaryType: 'Propose', + domain: domain, + message: proposeMsg as any, + }; + + const proposeSig = (await account0.signMessage(proposeData)) as any; + + const proposeCalldata: StarknetSigProposeCalldata = { + r: proposeSig.r, + s: proposeSig.s, + ...proposeMsg, + public_key: publickey0, + }; + + await account0.execute({ + contractAddress: starkSigAuthAddress, + entrypoint: 'authenticate_propose', + calldata: CallData.compile(proposeCalldata as any), + }); + + // VOTE + + const voteMsg: Vote = { + space: '0x0000000000000000000000000000000000007777', + voter: '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a', + proposalId: { low: '0x1', high: '0x0' }, + choice: '0x1', + userVotingStrategies: [ + { index: '0x1', params: ['0x1', '0x2', '0x3', '0x4'] }, + { index: '0x2', params: [] }, + ], + }; + + const voteData: typedData.TypedData = { + types: voteTypes, + primaryType: 'Vote', + domain: domain, + message: voteMsg as any, + }; + + const voteSig = (await account0.signMessage(voteData)) as any; + + const voteCalldata: StarknetSigVoteCalldata = { + r: voteSig.r, + s: voteSig.s, + ...voteMsg, + public_key: publickey0, + }; + + await account0.execute({ + contractAddress: starkSigAuthAddress, + entrypoint: 'authenticate_vote', + calldata: CallData.compile(voteCalldata as any), + }); + + // UPDATE PROPOSAL + + const updateProposalMsg: UpdateProposal = { + space: '0x0000000000000000000000000000000000007777', + author: '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a', + proposalId: { low: '0x1', high: '0x0' }, + executionStrategy: { + address: '0x0000000000000000000000000000000000001234', + params: ['0x5', '0x6', '0x7', '0x8'], + }, + salt: '0x0', + }; + const updateProposalData: typedData.TypedData = { + types: updateProposalTypes, + primaryType: 'UpdateProposal', + domain: domain, + message: updateProposalMsg as any, + }; + + const updateProposalSig = (await account0.signMessage(updateProposalData)) as any; + + const updateProposalCalldata: StarknetSigUpdateProposalCalldata = { + r: updateProposalSig.r, + s: updateProposalSig.s, + ...updateProposalMsg, + public_key: publickey0, + }; + + await account0.execute({ + contractAddress: starkSigAuthAddress, + entrypoint: 'authenticate_update_proposal', + calldata: CallData.compile(updateProposalCalldata as any), + }); + }, 100000); +}); From abedf0b9a0b520d3c81c7236b40a9f67bd3aee3b Mon Sep 17 00:00:00 2001 From: Orlando Date: Thu, 3 Aug 2023 17:53:32 +0100 Subject: [PATCH 16/25] chore: updated tests --- jest.config.ts | 11 + package.json | 3 + starknet/tests/deploy-stark-sig-auth.ts | 43 - starknet/tests/stark-sig.test.ts | 176 ++- starknet/tests/stark-sig.ts | 144 -- starknet/tests/types.ts | 55 +- yarn.lock | 1824 ++++++++++++++++++++++- 7 files changed, 1969 insertions(+), 287 deletions(-) create mode 100644 jest.config.ts delete mode 100644 starknet/tests/deploy-stark-sig-auth.ts delete mode 100644 starknet/tests/stark-sig.ts diff --git a/jest.config.ts b/jest.config.ts new file mode 100644 index 00000000..69046f30 --- /dev/null +++ b/jest.config.ts @@ -0,0 +1,11 @@ +import type { JestConfigWithTsJest } from 'ts-jest'; + +const jestConfig: JestConfigWithTsJest = { + // [...] + // Replace `ts-jest` with the preset you want to use + // from the above list + preset: 'ts-jest', + roots: ['/starknet/tests'], +}; + +export default jestConfig; diff --git a/package.json b/package.json index e85dd9d9..4e5c338e 100644 --- a/package.json +++ b/package.json @@ -9,14 +9,17 @@ "format": "eslint . --ext .ts --fix" }, "devDependencies": { + "@types/jest": "^29.5.3", "@types/node": "^20.4.5", "@typescript-eslint/parser": "^6.2.1", "dotenv": "^16.3.1", "eslint": "^8.46.0", "eslint-plugin-prettier": "^5.0.0", "fs": "^0.0.1-security", + "jest": "^29.6.2", "prettier": "^3.0.0", "starknet": "^5.14.1", + "ts-jest": "^29.1.1", "ts-node": "^10.9.1", "typescript": "^5.1.6" }, diff --git a/starknet/tests/deploy-stark-sig-auth.ts b/starknet/tests/deploy-stark-sig-auth.ts deleted file mode 100644 index f0173bae..00000000 --- a/starknet/tests/deploy-stark-sig-auth.ts +++ /dev/null @@ -1,43 +0,0 @@ -import fs from 'fs'; -import dotenv from 'dotenv'; -import { Account, json, Provider, CallData, Calldata} from 'starknet'; - -dotenv.config(); - -async function main() { - // connect provider - const provider = new Provider({ sequencer: { baseUrl: 'http://127.0.0.1:5050' } }); - console.log('provider=', provider); - // new Open Zeppelin account v0.5.1 : - // Generate public and private key pair. - const privateKey0 = '0xe3e70682c2094cac629f6fbed82c07cd'; - const address0 = '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a'; - const account0 = new Account(provider, address0, privateKey0); - - // Declare & deploy Test contract in devnet - const compiledContractSierra = json.parse( - fs.readFileSync('starknet/target/dev/sx_StarkSigAuthenticator.sierra.json').toString('ascii'), - ); - const compiledContractCasm = json.parse( - fs.readFileSync('starknet/target/dev/sx_StarkSigAuthenticator.casm.json').toString('ascii'), - ); - - const contractConstructor: Calldata = CallData.compile({ - name: 'sx-sn', - version: '0.1.0', - }); - - const deployResponse = await account0.declareAndDeploy({ - contract: compiledContractSierra, - casm: compiledContractCasm, - constructorCalldata: contractConstructor, - }); - console.log('deployResponse=', deployResponse); -} - -main() - .then(() => process.exit(0)) - .catch((error) => { - console.error(error); - process.exit(1); - }); diff --git a/starknet/tests/stark-sig.test.ts b/starknet/tests/stark-sig.test.ts index e7a22e43..326ff229 100644 --- a/starknet/tests/stark-sig.test.ts +++ b/starknet/tests/stark-sig.test.ts @@ -1,6 +1,6 @@ import fs from 'fs'; import dotenv from 'dotenv'; -import { Provider, Account, CallData, Calldata, typedData, json } from 'starknet'; +import { Provider, Account, CallData, typedData, shortString, json } from 'starknet'; import { proposeTypes, voteTypes, @@ -13,38 +13,98 @@ import { StarknetSigUpdateProposalCalldata, } from './types'; -dotenv.config(); - describe('Starknet Signature Authenticator', () => { const provider = new Provider({ sequencer: { baseUrl: 'http://127.0.0.1:5050' } }); // devnet predeployed account const privateKey0 = '0xe3e70682c2094cac629f6fbed82c07cd'; const address0 = '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a'; - const publickey0 = '0x7e52885445756b313ea16849145363ccb73fb4ab0440dbac333cf9d13de82b9'; const account0 = new Account(provider, address0, privateKey0); + // change this to 'snake' if the account interface uses snake case + const account0Type = shortString.encodeShortString('camel'); + + let spaceAddress: string; + let vanillaVotingStrategyAddress: string; + let vanillaProposalValidationStrategyAddress: string; let starkSigAuthAddress: string; let domain: any; beforeAll(async () => { - const compiledContractSierra = json.parse( + // Deploy Starknet Signature Authenticator + const starkSigAuthSierra = json.parse( fs.readFileSync('starknet/target/dev/sx_StarkSigAuthenticator.sierra.json').toString('ascii'), ); - const compiledContractCasm = json.parse( + const starkSigAuthCasm = json.parse( fs.readFileSync('starknet/target/dev/sx_StarkSigAuthenticator.casm.json').toString('ascii'), ); - const contractConstructor: Calldata = CallData.compile({ - name: 'sx-sn', - version: '0.1.0', + let deployResponse = await account0.declareAndDeploy({ + contract: starkSigAuthSierra, + casm: starkSigAuthCasm, + constructorCalldata: CallData.compile({ name: 'sx-sn', version: '0.1.0' }), }); + starkSigAuthAddress = deployResponse.deploy.contract_address; - const deployResponse = await account0.declareAndDeploy({ - contract: compiledContractSierra, - casm: compiledContractCasm, - constructorCalldata: contractConstructor, + // Deploy Vanilla Voting Strategy + const vanillaVotingStrategySierra = json.parse( + fs.readFileSync('starknet/target/dev/sx_VanillaVotingStrategy.sierra.json').toString('ascii'), + ); + const vanillaVotingStrategyCasm = json.parse( + fs.readFileSync('starknet/target/dev/sx_VanillaVotingStrategy.casm.json').toString('ascii'), + ); + + deployResponse = await account0.declareAndDeploy({ + contract: vanillaVotingStrategySierra, + casm: vanillaVotingStrategyCasm, + constructorCalldata: CallData.compile({}), }); - starkSigAuthAddress = deployResponse.deploy.contract_address; + vanillaVotingStrategyAddress = deployResponse.deploy.contract_address; + + // Deploy Vanilla Proposal Validation Strategy + const vanillaProposalValidationStrategySierra = json.parse( + fs + .readFileSync('starknet/target/dev/sx_VanillaProposalValidationStrategy.sierra.json') + .toString('ascii'), + ); + const vanillaProposalValidationStrategyCasm = json.parse( + fs + .readFileSync('starknet/target/dev/sx_VanillaProposalValidationStrategy.casm.json') + .toString('ascii'), + ); + + deployResponse = await account0.declareAndDeploy({ + contract: vanillaProposalValidationStrategySierra, + casm: vanillaProposalValidationStrategyCasm, + constructorCalldata: CallData.compile({}), + }); + vanillaProposalValidationStrategyAddress = deployResponse.deploy.contract_address; + + // Deploy Space + const spaceSierra = json.parse( + fs.readFileSync('starknet/target/dev/sx_Space.sierra.json').toString('ascii'), + ); + const spaceCasm = json.parse( + fs.readFileSync('starknet/target/dev/sx_Space.casm.json').toString('ascii'), + ); + + deployResponse = await account0.declareAndDeploy({ + contract: spaceSierra, + casm: spaceCasm, + constructorCalldata: CallData.compile({ + _owner: 1, + _max_voting_duration: 100, + _min_voting_duration: 100, + _voting_delay: 10, + _proposal_validation_strategy: { + address: vanillaProposalValidationStrategyAddress, + params: [], + }, + _voting_strategies: [{ address: vanillaVotingStrategyAddress, params: [] }], + _authenticators: [starkSigAuthAddress], + }), + }); + spaceAddress = deployResponse.deploy.contract_address; + domain = { name: 'sx-sn', version: '0.1.0', @@ -55,8 +115,8 @@ describe('Starknet Signature Authenticator', () => { test('can authenticate a proposal, a vote, and a proposal update', async () => { // PROPOSE const proposeMsg: Propose = { - space: '0x0000000000000000000000000000000000007777', - author: '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a', + space: spaceAddress, + author: address0, executionStrategy: { address: '0x0000000000000000000000000000000000001234', params: ['0x5', '0x6', '0x7', '0x8'], @@ -75,10 +135,9 @@ describe('Starknet Signature Authenticator', () => { const proposeSig = (await account0.signMessage(proposeData)) as any; const proposeCalldata: StarknetSigProposeCalldata = { - r: proposeSig.r, - s: proposeSig.s, + signature: [proposeSig.r, proposeSig.s], ...proposeMsg, - public_key: publickey0, + accountType: account0Type, }; await account0.execute({ @@ -87,49 +146,14 @@ describe('Starknet Signature Authenticator', () => { calldata: CallData.compile(proposeCalldata as any), }); - // VOTE - - const voteMsg: Vote = { - space: '0x0000000000000000000000000000000000007777', - voter: '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a', - proposalId: { low: '0x1', high: '0x0' }, - choice: '0x1', - userVotingStrategies: [ - { index: '0x1', params: ['0x1', '0x2', '0x3', '0x4'] }, - { index: '0x2', params: [] }, - ], - }; - - const voteData: typedData.TypedData = { - types: voteTypes, - primaryType: 'Vote', - domain: domain, - message: voteMsg as any, - }; - - const voteSig = (await account0.signMessage(voteData)) as any; - - const voteCalldata: StarknetSigVoteCalldata = { - r: voteSig.r, - s: voteSig.s, - ...voteMsg, - public_key: publickey0, - }; - - await account0.execute({ - contractAddress: starkSigAuthAddress, - entrypoint: 'authenticate_vote', - calldata: CallData.compile(voteCalldata as any), - }); - // UPDATE PROPOSAL const updateProposalMsg: UpdateProposal = { - space: '0x0000000000000000000000000000000000007777', - author: '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a', + space: spaceAddress, + author: address0, proposalId: { low: '0x1', high: '0x0' }, executionStrategy: { - address: '0x0000000000000000000000000000000000001234', + address: '0x0000000000000000000000000000000000005678', params: ['0x5', '0x6', '0x7', '0x8'], }, salt: '0x0', @@ -144,10 +168,9 @@ describe('Starknet Signature Authenticator', () => { const updateProposalSig = (await account0.signMessage(updateProposalData)) as any; const updateProposalCalldata: StarknetSigUpdateProposalCalldata = { - r: updateProposalSig.r, - s: updateProposalSig.s, + signature: [updateProposalSig.r, updateProposalSig.s], ...updateProposalMsg, - public_key: publickey0, + accountType: account0Type, }; await account0.execute({ @@ -155,5 +178,36 @@ describe('Starknet Signature Authenticator', () => { entrypoint: 'authenticate_update_proposal', calldata: CallData.compile(updateProposalCalldata as any), }); - }, 100000); + + // VOTE + + const voteMsg: Vote = { + space: spaceAddress, + voter: address0, + proposalId: { low: '0x1', high: '0x0' }, + choice: '0x2', + userVotingStrategies: [{ index: '0x0', params: ['0x1', '0x2', '0x3', '0x4'] }], + }; + + const voteData: typedData.TypedData = { + types: voteTypes, + primaryType: 'Vote', + domain: domain, + message: voteMsg as any, + }; + + const voteSig = (await account0.signMessage(voteData)) as any; + + const voteCalldata: StarknetSigVoteCalldata = { + signature: [voteSig.r, voteSig.s], + ...voteMsg, + accountType: account0Type, + }; + + await account0.execute({ + contractAddress: starkSigAuthAddress, + entrypoint: 'authenticate_vote', + calldata: CallData.compile(voteCalldata as any), + }); + }, 1000000); }); diff --git a/starknet/tests/stark-sig.ts b/starknet/tests/stark-sig.ts deleted file mode 100644 index d726de66..00000000 --- a/starknet/tests/stark-sig.ts +++ /dev/null @@ -1,144 +0,0 @@ -import dotenv from 'dotenv'; -import { Provider, Account, CallData, typedData } from 'starknet'; -import { - proposeTypes, - voteTypes, - updateProposalTypes, - Propose, - Vote, - UpdateProposal, - StarknetSigProposeCalldata, - StarknetSigVoteCalldata, - StarknetSigUpdateProposalCalldata, -} from './types'; - -dotenv.config(); - -async function main() { - const provider = new Provider({ sequencer: { baseUrl: 'http://127.0.0.1:5050' } }); - - const privateKey0 = '0xe3e70682c2094cac629f6fbed82c07cd'; - const address0 = '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a'; - const publickey0 = '0x7e52885445756b313ea16849145363ccb73fb4ab0440dbac333cf9d13de82b9'; - const account0 = new Account(provider, address0, privateKey0); - - const starkSigAuthAddress = '0x25e72fe267e1d1adc59812dbdde56fb8e5156bb29d5f11ff1dd6317fca682fb'; - - const domain = { - name: 'sx-sn', - version: '0.1.0', - chainId: '0x534e5f474f45524c49', // devnet id - verifyingContract: starkSigAuthAddress, - }; - - // PROPOSE - - const proposeMsg: Propose = { - space: '0x0000000000000000000000000000000000007777', - author: '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a', - executionStrategy: { - address: '0x0000000000000000000000000000000000001234', - params: ['0x5', '0x6', '0x7', '0x8'], - }, - userProposalValidationParams: ['0x1', '0x2', '0x3', '0x4'], - salt: '0x0', - }; - - const proposeData: typedData.TypedData = { - types: proposeTypes, - primaryType: 'Propose', - domain: domain, - message: proposeMsg as any, - }; - - const proposeSig = (await account0.signMessage(proposeData)) as any; - - const proposeCalldata: StarknetSigProposeCalldata = { - r: proposeSig.r, - s: proposeSig.s, - ...proposeMsg, - public_key: publickey0, - }; - - await account0.execute({ - contractAddress: starkSigAuthAddress, - entrypoint: 'authenticate_propose', - calldata: CallData.compile(proposeCalldata as any), - }); - - // VOTE - - const voteMsg: Vote = { - space: '0x0000000000000000000000000000000000007777', - voter: '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a', - proposalId: { low: '0x1', high: '0x0' }, - choice: '0x1', - userVotingStrategies: [ - { index: '0x1', params: ['0x1', '0x2', '0x3', '0x4'] }, - { index: '0x2', params: [] }, - ], - }; - - const voteData: typedData.TypedData = { - types: voteTypes, - primaryType: 'Vote', - domain: domain, - message: voteMsg as any, - }; - - const voteSig = (await account0.signMessage(voteData)) as any; - - const voteCalldata: StarknetSigVoteCalldata = { - r: voteSig.r, - s: voteSig.s, - ...voteMsg, - public_key: publickey0, - }; - - await account0.execute({ - contractAddress: starkSigAuthAddress, - entrypoint: 'authenticate_vote', - calldata: CallData.compile(voteCalldata as any), - }); - - // UPDATE PROPOSAL - - const updateProposalMsg: UpdateProposal = { - space: '0x0000000000000000000000000000000000007777', - author: '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a', - proposalId: { low: '0x1', high: '0x0' }, - executionStrategy: { - address: '0x0000000000000000000000000000000000001234', - params: ['0x5', '0x6', '0x7', '0x8'], - }, - salt: '0x0', - }; - const updateProposalData: typedData.TypedData = { - types: updateProposalTypes, - primaryType: 'UpdateProposal', - domain: domain, - message: updateProposalMsg as any, - }; - - const updateProposalSig = (await account0.signMessage(updateProposalData)) as any; - - const updateProposalCalldata: StarknetSigUpdateProposalCalldata = { - r: updateProposalSig.r, - s: updateProposalSig.s, - ...updateProposalMsg, - public_key: publickey0, - }; - - await account0.execute({ - contractAddress: starkSigAuthAddress, - entrypoint: 'authenticate_update_proposal', - calldata: CallData.compile(updateProposalCalldata as any), - }); -} - -main() - .then(() => process.exit(0)) - .catch((error) => { - console.error(error); - process.exit(1); - }); diff --git a/starknet/tests/types.ts b/starknet/tests/types.ts index 8cc22262..ce3ddffe 100644 --- a/starknet/tests/types.ts +++ b/starknet/tests/types.ts @@ -7,6 +7,21 @@ export const domainTypes = { ], }; +export const sharedTypes = { + Strategy: [ + { name: 'address', type: 'felt252' }, + { name: 'params', type: 'felt*' }, + ], + IndexedStrategy: [ + { name: 'index', type: 'felt252' }, + { name: 'params', type: 'felt*' }, + ], + u256: [ + { name: 'low', type: 'felt252' }, + { name: 'high', type: 'felt252' }, + ], +}; + export const proposeTypes = { StarkNetDomain: domainTypes.StarkNetDomain, Propose: [ @@ -16,10 +31,7 @@ export const proposeTypes = { { name: 'userProposalValidationParams', type: 'felt*' }, { name: 'salt', type: 'felt252' }, ], - Strategy: [ - { name: 'address', type: 'felt252' }, - { name: 'params', type: 'felt*' }, - ], + Strategy: sharedTypes.Strategy, }; export const voteTypes = { @@ -31,14 +43,8 @@ export const voteTypes = { { name: 'choice', type: 'felt252' }, { name: 'userVotingStrategies', type: 'IndexedStrategy*' }, ], - IndexedStrategy: [ - { name: 'index', type: 'felt252' }, - { name: 'params', type: 'felt*' }, - ], - u256: [ - { name: 'low', type: 'felt252' }, - { name: 'high', type: 'felt252' }, - ], + IndexedStrategy: sharedTypes.IndexedStrategy, + u256: sharedTypes.u256, }; export const updateProposalTypes = { @@ -50,14 +56,8 @@ export const updateProposalTypes = { { name: 'executionStrategy', type: 'Strategy' }, { name: 'salt', type: 'felt252' }, ], - Strategy: [ - { name: 'address', type: 'felt252' }, - { name: 'params', type: 'felt*' }, - ], - u256: [ - { name: 'low', type: 'felt252' }, - { name: 'high', type: 'felt252' }, - ], + Strategy: sharedTypes.Strategy, + u256: sharedTypes.u256, }; export interface Strategy { @@ -100,19 +100,16 @@ export interface UpdateProposal { } export interface StarknetSigProposeCalldata extends Propose { - r: string; - s: string; - public_key: string; + signature: string[]; + accountType: string; } export interface StarknetSigVoteCalldata extends Vote { - r: string; - s: string; - public_key: string; + signature: string[]; + accountType: string; } export interface StarknetSigUpdateProposalCalldata extends UpdateProposal { - r: string; - s: string; - public_key: string; + signature: string[]; + accountType: string; } diff --git a/yarn.lock b/yarn.lock index 097eabf1..7dc1a8ea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,6 +7,300 @@ resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658" + integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ== + dependencies: + "@babel/highlight" "^7.22.5" + +"@babel/compat-data@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" + integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== + +"@babel/core@^7.11.6", "@babel/core@^7.12.3": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.9.tgz#bd96492c68822198f33e8a256061da3cf391f58f" + integrity sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.9" + "@babel/helper-compilation-targets" "^7.22.9" + "@babel/helper-module-transforms" "^7.22.9" + "@babel/helpers" "^7.22.6" + "@babel/parser" "^7.22.7" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.8" + "@babel/types" "^7.22.5" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.2" + semver "^6.3.1" + +"@babel/generator@^7.22.7", "@babel/generator@^7.22.9", "@babel/generator@^7.7.2": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.9.tgz#572ecfa7a31002fa1de2a9d91621fd895da8493d" + integrity sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw== + dependencies: + "@babel/types" "^7.22.5" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/helper-compilation-targets@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz#f9d0a7aaaa7cd32a3f31c9316a69f5a9bcacb892" + integrity sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.5" + browserslist "^4.21.9" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-environment-visitor@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" + integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== + +"@babel/helper-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" + integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== + dependencies: + "@babel/template" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-imports@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" + integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-transforms@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz#92dfcb1fbbb2bc62529024f72d942a8c97142129" + integrity sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.5" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + +"@babel/helper-validator-identifier@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" + integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== + +"@babel/helper-validator-option@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" + integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== + +"@babel/helpers@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.6.tgz#8e61d3395a4f0c5a8060f309fb008200969b5ecd" + integrity sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA== + dependencies: + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.6" + "@babel/types" "^7.22.5" + +"@babel/highlight@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" + integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw== + dependencies: + "@babel/helper-validator-identifier" "^7.22.5" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.5", "@babel/parser@^7.22.7": + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.7.tgz#df8cf085ce92ddbdbf668a7f186ce848c9036cae" + integrity sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q== + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.7.2": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" + integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz#aac8d383b062c5072c647a31ef990c1d0af90272" + integrity sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/template@^7.22.5", "@babel/template@^7.3.3": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" + integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/traverse@^7.22.6", "@babel/traverse@^7.22.8": + version "7.22.8" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.8.tgz#4d4451d31bc34efeae01eac222b514a77aa4000e" + integrity sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.7" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.22.7" + "@babel/types" "^7.22.5" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.5", "@babel/types@^7.3.3": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe" + integrity sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" @@ -65,11 +359,243 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^29.6.2": + version "29.6.2" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.6.2.tgz#bf1d4101347c23e07c029a1b1ae07d550f5cc541" + integrity sha512-0N0yZof5hi44HAR2pPS+ikJ3nzKNoZdVu8FffRf3wy47I7Dm7etk/3KetMdRUqzVd16V4O2m2ISpNTbnIuqy1w== + dependencies: + "@jest/types" "^29.6.1" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^29.6.2" + jest-util "^29.6.2" + slash "^3.0.0" + +"@jest/core@^29.6.2": + version "29.6.2" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.6.2.tgz#6f2d1dbe8aa0265fcd4fb8082ae1952f148209c8" + integrity sha512-Oj+5B+sDMiMWLhPFF+4/DvHOf+U10rgvCLGPHP8Xlsy/7QxS51aU/eBngudHlJXnaWD5EohAgJ4js+T6pa+zOg== + dependencies: + "@jest/console" "^29.6.2" + "@jest/reporters" "^29.6.2" + "@jest/test-result" "^29.6.2" + "@jest/transform" "^29.6.2" + "@jest/types" "^29.6.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^29.5.0" + jest-config "^29.6.2" + jest-haste-map "^29.6.2" + jest-message-util "^29.6.2" + jest-regex-util "^29.4.3" + jest-resolve "^29.6.2" + jest-resolve-dependencies "^29.6.2" + jest-runner "^29.6.2" + jest-runtime "^29.6.2" + jest-snapshot "^29.6.2" + jest-util "^29.6.2" + jest-validate "^29.6.2" + jest-watcher "^29.6.2" + micromatch "^4.0.4" + pretty-format "^29.6.2" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^29.6.2": + version "29.6.2" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.6.2.tgz#794c0f769d85e7553439d107d3f43186dc6874a9" + integrity sha512-AEcW43C7huGd/vogTddNNTDRpO6vQ2zaQNrttvWV18ArBx9Z56h7BIsXkNFJVOO4/kblWEQz30ckw0+L3izc+Q== + dependencies: + "@jest/fake-timers" "^29.6.2" + "@jest/types" "^29.6.1" + "@types/node" "*" + jest-mock "^29.6.2" + +"@jest/expect-utils@^29.6.2": + version "29.6.2" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.6.2.tgz#1b97f290d0185d264dd9fdec7567a14a38a90534" + integrity sha512-6zIhM8go3RV2IG4aIZaZbxwpOzz3ZiM23oxAlkquOIole+G6TrbeXnykxWYlqF7kz2HlBjdKtca20x9atkEQYg== + dependencies: + jest-get-type "^29.4.3" + +"@jest/expect@^29.6.2": + version "29.6.2" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.6.2.tgz#5a2ad58bb345165d9ce0a1845bbf873c480a4b28" + integrity sha512-m6DrEJxVKjkELTVAztTLyS/7C92Y2b0VYqmDROYKLLALHn8T/04yPs70NADUYPrV3ruI+H3J0iUIuhkjp7vkfg== + dependencies: + expect "^29.6.2" + jest-snapshot "^29.6.2" + +"@jest/fake-timers@^29.6.2": + version "29.6.2" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.6.2.tgz#fe9d43c5e4b1b901168fe6f46f861b3e652a2df4" + integrity sha512-euZDmIlWjm1Z0lJ1D0f7a0/y5Kh/koLFMUBE5SUYWrmy8oNhJpbTBDAP6CxKnadcMLDoDf4waRYCe35cH6G6PA== + dependencies: + "@jest/types" "^29.6.1" + "@sinonjs/fake-timers" "^10.0.2" + "@types/node" "*" + jest-message-util "^29.6.2" + jest-mock "^29.6.2" + jest-util "^29.6.2" + +"@jest/globals@^29.6.2": + version "29.6.2" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.6.2.tgz#74af81b9249122cc46f1eb25793617eec69bf21a" + integrity sha512-cjuJmNDjs6aMijCmSa1g2TNG4Lby/AeU7/02VtpW+SLcZXzOLK2GpN2nLqcFjmhy3B3AoPeQVx7BnyOf681bAw== + dependencies: + "@jest/environment" "^29.6.2" + "@jest/expect" "^29.6.2" + "@jest/types" "^29.6.1" + jest-mock "^29.6.2" + +"@jest/reporters@^29.6.2": + version "29.6.2" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.6.2.tgz#524afe1d76da33d31309c2c4a2c8062d0c48780a" + integrity sha512-sWtijrvIav8LgfJZlrGCdN0nP2EWbakglJY49J1Y5QihcQLfy7ovyxxjJBRXMNltgt4uPtEcFmIMbVshEDfFWw== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^29.6.2" + "@jest/test-result" "^29.6.2" + "@jest/transform" "^29.6.2" + "@jest/types" "^29.6.1" + "@jridgewell/trace-mapping" "^0.3.18" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-message-util "^29.6.2" + jest-util "^29.6.2" + jest-worker "^29.6.2" + slash "^3.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" + v8-to-istanbul "^9.0.1" + +"@jest/schemas@^29.6.0": + version "29.6.0" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.0.tgz#0f4cb2c8e3dca80c135507ba5635a4fd755b0040" + integrity sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ== + dependencies: + "@sinclair/typebox" "^0.27.8" + +"@jest/source-map@^29.6.0": + version "29.6.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.0.tgz#bd34a05b5737cb1a99d43e1957020ac8e5b9ddb1" + integrity sha512-oA+I2SHHQGxDCZpbrsCQSoMLb3Bz547JnM+jUr9qEbuw0vQlWZfpPS7CO9J7XiwKicEz9OFn/IYoLkkiUD7bzA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.18" + callsites "^3.0.0" + graceful-fs "^4.2.9" + +"@jest/test-result@^29.6.2": + version "29.6.2" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.6.2.tgz#fdd11583cd1608e4db3114e8f0cce277bf7a32ed" + integrity sha512-3VKFXzcV42EYhMCsJQURptSqnyjqCGbtLuX5Xxb6Pm6gUf1wIRIl+mandIRGJyWKgNKYF9cnstti6Ls5ekduqw== + dependencies: + "@jest/console" "^29.6.2" + "@jest/types" "^29.6.1" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^29.6.2": + version "29.6.2" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.6.2.tgz#585eff07a68dd75225a7eacf319780cb9f6b9bf4" + integrity sha512-GVYi6PfPwVejO7slw6IDO0qKVum5jtrJ3KoLGbgBWyr2qr4GaxFV6su+ZAjdTX75Sr1DkMFRk09r2ZVa+wtCGw== + dependencies: + "@jest/test-result" "^29.6.2" + graceful-fs "^4.2.9" + jest-haste-map "^29.6.2" + slash "^3.0.0" + +"@jest/transform@^29.6.2": + version "29.6.2" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.6.2.tgz#522901ebbb211af08835bc3bcdf765ab778094e3" + integrity sha512-ZqCqEISr58Ce3U+buNFJYUktLJZOggfyvR+bZMaiV1e8B1SIvJbwZMrYz3gx/KAPn9EXmOmN+uB08yLCjWkQQg== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^29.6.1" + "@jridgewell/trace-mapping" "^0.3.18" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^2.0.0" + fast-json-stable-stringify "^2.1.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.6.2" + jest-regex-util "^29.4.3" + jest-util "^29.6.2" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.2" + +"@jest/types@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.1.tgz#ae79080278acff0a6af5eb49d063385aaa897bf2" + integrity sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw== + dependencies: + "@jest/schemas" "^29.6.0" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + "@jridgewell/resolve-uri@^3.0.3": version "3.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@1.4.14": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.15" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" @@ -83,6 +609,14 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.18" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" + integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + "@noble/curves@~1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.0.0.tgz#e40be8c7daf088aaf291887cbc73f43464a92932" @@ -133,6 +667,25 @@ picocolors "^1.0.0" tslib "^2.6.0" +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + +"@sinonjs/commons@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.0.tgz#beb434fe875d965265e04722ccfc21df7f755d72" + integrity sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^10.0.2": + version "10.3.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" + integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== + dependencies: + "@sinonjs/commons" "^3.0.0" + "@tsconfig/node10@^1.0.7": version "1.0.9" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" @@ -153,11 +706,83 @@ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== +"@types/babel__core@^7.1.14": + version "7.20.1" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.1.tgz#916ecea274b0c776fec721e333e55762d3a9614b" + integrity sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw== + dependencies: + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.4" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" + integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.20.1" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.1.tgz#dd6f1d2411ae677dcb2db008c962598be31d6acf" + integrity sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg== + dependencies: + "@babel/types" "^7.20.7" + +"@types/graceful-fs@^4.1.3": + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" + integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== + dependencies: + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@^29.5.3": + version "29.5.3" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.3.tgz#7a35dc0044ffb8b56325c6802a4781a626b05777" + integrity sha512-1Nq7YrO/vJE/FYnqYyw0FS8LdrjExSgIiHyKg7xPpn+yi8Q4huZryKnkJatN1ZRH89Kw2v33/8ZMB7DuZeSLlA== + dependencies: + expect "^29.0.0" + pretty-format "^29.0.0" + "@types/json-schema@^7.0.12": version "7.0.12" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== +"@types/node@*": + version "20.4.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.6.tgz#b66b66c9bb5d49b199f03399e341c9d6036e9e88" + integrity sha512-q0RkvNgMweWWIvSMDiXhflGUKMdIxBo2M2tYM/0kEGDueQByFzK4KZAgu5YHGFNxziTlppNpTIBcqHQAxlfHdA== + "@types/node@^20.4.5": version "20.4.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.5.tgz#9dc0a5cb1ccce4f7a731660935ab70b9c00a5d69" @@ -168,6 +793,23 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== +"@types/stack-utils@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + +"@types/yargs-parser@*": + version "21.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" + integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== + +"@types/yargs@^17.0.8": + version "17.0.24" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" + integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw== + dependencies: + "@types/yargs-parser" "*" + "@typescript-eslint/eslint-plugin@^6.2.1": version "6.2.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.1.tgz#41b79923fee46a745a3a50cba1c33c622aa3c79a" @@ -279,23 +921,57 @@ ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-styles@^4.1.0: +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +anymatch@^3.0.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + arg@^4.1.0: version "4.1.3" resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + argparse@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" @@ -306,6 +982,66 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== +babel-jest@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.6.2.tgz#cada0a59e07f5acaeb11cbae7e3ba92aec9c1126" + integrity sha512-BYCzImLos6J3BH/+HvUCHG1dTf2MzmAB4jaVxHV+29RZLjR29XuYTmsf2sdDwkrb+FczkGo3kOhE7ga6sI0P4A== + dependencies: + "@jest/transform" "^29.6.2" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^29.5.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz#a97db437936f441ec196990c9738d4b88538618a" + integrity sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz#57bc8cc88097af7ff6a5ab59d1cd29d52a5916e2" + integrity sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg== + dependencies: + babel-plugin-jest-hoist "^29.5.0" + babel-preset-current-node-syntax "^1.0.0" + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -338,6 +1074,35 @@ braces@^3.0.2: dependencies: fill-range "^7.0.1" +browserslist@^4.21.9: + version "4.21.10" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0" + integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ== + dependencies: + caniuse-lite "^1.0.30001517" + electron-to-chromium "^1.4.477" + node-releases "^2.0.13" + update-browserslist-db "^1.0.11" + +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + bundle-name@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" @@ -350,6 +1115,30 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001517: + version "1.0.30001519" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001519.tgz#3e7b8b8a7077e78b0eb054d69e6edf5c7df35601" + integrity sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg== + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + chalk@^4.0.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -358,6 +1147,47 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +ci-info@^3.2.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== + +cjs-module-lexer@^1.0.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + +collect-v8-coverage@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" + integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -365,6 +1195,11 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" @@ -375,6 +1210,16 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + create-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" @@ -389,18 +1234,28 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: +debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" +dedent@^1.0.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.1.tgz#4f3fc94c8b711e9bb2800d185cd6ad20f2a90aff" + integrity sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg== + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + default-browser-id@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" @@ -424,6 +1279,16 @@ define-lazy-prop@^3.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +diff-sequences@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2" + integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA== + diff@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" @@ -448,6 +1313,43 @@ dotenv@^16.3.1: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== +electron-to-chromium@^1.4.477: + version "1.4.482" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.482.tgz#77c5ed37b93d4dda860e27538e0e2a01d6a19e02" + integrity sha512-h+UqpfmEr1Qkk0zp7ej/jid7CXoq4m4QzW6wNTb0ELJ/BZCpA4wgUylBIMGCe621tnr4l5VmoHjdoSx2lbnNJA== + +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" + integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" @@ -526,6 +1428,11 @@ espree@^9.6.0, espree@^9.6.1: acorn-jsx "^5.3.2" eslint-visitor-keys "^3.4.1" +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + esquery@^1.4.2: version "1.5.0" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" @@ -580,6 +1487,23 @@ execa@^7.1.1: signal-exit "^3.0.7" strip-final-newline "^3.0.0" +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== + +expect@^29.0.0, expect@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.6.2.tgz#7b08e83eba18ddc4a2cf62b5f2d1918f5cd84521" + integrity sha512-iAErsLxJ8C+S02QbLAwgSGSezLQK+XXRDt8IuFXFpwCNw2ECmzZSmjKcCaFVp5VRMk+WAvz6h6jokzEzBFZEuA== + dependencies: + "@jest/expect-utils" "^29.6.2" + "@types/node" "*" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.6.2" + jest-message-util "^29.6.2" + jest-util "^29.6.2" + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -601,7 +1525,7 @@ fast-glob@^3.2.9, fast-glob@^3.3.0: merge2 "^1.3.0" micromatch "^4.0.4" -fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -618,6 +1542,13 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +fb-watchman@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== + dependencies: + bser "2.1.1" + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -632,6 +1563,14 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + find-up@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" @@ -663,6 +1602,31 @@ fs@^0.0.1-security: resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.1-security.tgz#8a7bd37186b6dddf3813f23858b57ecaaf5e41d4" integrity sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w== +fsevents@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + get-stream@^6.0.0, get-stream@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" @@ -682,7 +1646,7 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" -glob@^7.1.3: +glob@^7.1.3, glob@^7.1.4: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -694,6 +1658,11 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + globals@^13.19.0: version "13.20.0" resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" @@ -713,16 +1682,38 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" +graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + graphemer@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" @@ -746,6 +1737,14 @@ import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -764,6 +1763,18 @@ inherits@2: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-core-module@^2.11.0: + version "2.12.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" + integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== + dependencies: + has "^1.0.3" + is-docker@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" @@ -779,6 +1790,16 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -833,6 +1854,419 @@ isomorphic-fetch@^3.0.0: node-fetch "^2.6.1" whatwg-fetch "^3.4.1" +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-report@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^4.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.1.3: + version "3.1.6" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz#2544bcab4768154281a2f0870471902704ccaa1a" + integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jest-changed-files@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.5.0.tgz#e88786dca8bf2aa899ec4af7644e16d9dcf9b23e" + integrity sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag== + dependencies: + execa "^5.0.0" + p-limit "^3.1.0" + +jest-circus@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.6.2.tgz#1e6ffca60151ac66cad63fce34f443f6b5bb4258" + integrity sha512-G9mN+KOYIUe2sB9kpJkO9Bk18J4dTDArNFPwoZ7WKHKel55eKIS/u2bLthxgojwlf9NLCVQfgzM/WsOVvoC6Fw== + dependencies: + "@jest/environment" "^29.6.2" + "@jest/expect" "^29.6.2" + "@jest/test-result" "^29.6.2" + "@jest/types" "^29.6.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^1.0.0" + is-generator-fn "^2.0.0" + jest-each "^29.6.2" + jest-matcher-utils "^29.6.2" + jest-message-util "^29.6.2" + jest-runtime "^29.6.2" + jest-snapshot "^29.6.2" + jest-util "^29.6.2" + p-limit "^3.1.0" + pretty-format "^29.6.2" + pure-rand "^6.0.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-cli@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.6.2.tgz#edb381763398d1a292cd1b636a98bfa5644b8fda" + integrity sha512-TT6O247v6dCEX2UGHGyflMpxhnrL0DNqP2fRTKYm3nJJpCTfXX3GCMQPGFjXDoj0i5/Blp3jriKXFgdfmbYB6Q== + dependencies: + "@jest/core" "^29.6.2" + "@jest/test-result" "^29.6.2" + "@jest/types" "^29.6.1" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^29.6.2" + jest-util "^29.6.2" + jest-validate "^29.6.2" + prompts "^2.0.1" + yargs "^17.3.1" + +jest-config@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.6.2.tgz#c68723f06b31ca5e63030686e604727d406cd7c3" + integrity sha512-VxwFOC8gkiJbuodG9CPtMRjBUNZEHxwfQXmIudSTzFWxaci3Qub1ddTRbFNQlD/zUeaifLndh/eDccFX4wCMQw== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^29.6.2" + "@jest/types" "^29.6.1" + babel-jest "^29.6.2" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^29.6.2" + jest-environment-node "^29.6.2" + jest-get-type "^29.4.3" + jest-regex-util "^29.4.3" + jest-resolve "^29.6.2" + jest-runner "^29.6.2" + jest-util "^29.6.2" + jest-validate "^29.6.2" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^29.6.2" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.6.2.tgz#c36001e5543e82a0805051d3ceac32e6825c1c46" + integrity sha512-t+ST7CB9GX5F2xKwhwCf0TAR17uNDiaPTZnVymP9lw0lssa9vG+AFyDZoeIHStU3WowFFwT+ky+er0WVl2yGhA== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.4.3" + jest-get-type "^29.4.3" + pretty-format "^29.6.2" + +jest-docblock@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.4.3.tgz#90505aa89514a1c7dceeac1123df79e414636ea8" + integrity sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg== + dependencies: + detect-newline "^3.0.0" + +jest-each@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.6.2.tgz#c9e4b340bcbe838c73adf46b76817b15712d02ce" + integrity sha512-MsrsqA0Ia99cIpABBc3izS1ZYoYfhIy0NNWqPSE0YXbQjwchyt6B1HD2khzyPe1WiJA7hbxXy77ZoUQxn8UlSw== + dependencies: + "@jest/types" "^29.6.1" + chalk "^4.0.0" + jest-get-type "^29.4.3" + jest-util "^29.6.2" + pretty-format "^29.6.2" + +jest-environment-node@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.6.2.tgz#a9ea2cabff39b08eca14ccb32c8ceb924c8bb1ad" + integrity sha512-YGdFeZ3T9a+/612c5mTQIllvWkddPbYcN2v95ZH24oWMbGA4GGS2XdIF92QMhUhvrjjuQWYgUGW2zawOyH63MQ== + dependencies: + "@jest/environment" "^29.6.2" + "@jest/fake-timers" "^29.6.2" + "@jest/types" "^29.6.1" + "@types/node" "*" + jest-mock "^29.6.2" + jest-util "^29.6.2" + +jest-get-type@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" + integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== + +jest-haste-map@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.6.2.tgz#298c25ea5255cfad8b723179d4295cf3a50a70d1" + integrity sha512-+51XleTDAAysvU8rT6AnS1ZJ+WHVNqhj1k6nTvN2PYP+HjU3kqlaKQ1Lnw3NYW3bm2r8vq82X0Z1nDDHZMzHVA== + dependencies: + "@jest/types" "^29.6.1" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^29.4.3" + jest-util "^29.6.2" + jest-worker "^29.6.2" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + +jest-leak-detector@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.6.2.tgz#e2b307fee78cab091c37858a98c7e1d73cdf5b38" + integrity sha512-aNqYhfp5uYEO3tdWMb2bfWv6f0b4I0LOxVRpnRLAeque2uqOVVMLh6khnTcE2qJ5wAKop0HcreM1btoysD6bPQ== + dependencies: + jest-get-type "^29.4.3" + pretty-format "^29.6.2" + +jest-matcher-utils@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.6.2.tgz#39de0be2baca7a64eacb27291f0bd834fea3a535" + integrity sha512-4LiAk3hSSobtomeIAzFTe+N8kL6z0JtF3n6I4fg29iIW7tt99R7ZcIFW34QkX+DuVrf+CUe6wuVOpm7ZKFJzZQ== + dependencies: + chalk "^4.0.0" + jest-diff "^29.6.2" + jest-get-type "^29.4.3" + pretty-format "^29.6.2" + +jest-message-util@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.6.2.tgz#af7adc2209c552f3f5ae31e77cf0a261f23dc2bb" + integrity sha512-vnIGYEjoPSuRqV8W9t+Wow95SDp6KPX2Uf7EoeG9G99J2OVh7OSwpS4B6J0NfpEIpfkBNHlBZpA2rblEuEFhZQ== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.6.1" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.6.2" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.6.2.tgz#ef9c9b4d38c34a2ad61010a021866dad41ce5e00" + integrity sha512-hoSv3lb3byzdKfwqCuT6uTscan471GUECqgNYykg6ob0yiAw3zYc7OrPnI9Qv8Wwoa4lC7AZ9hyS4AiIx5U2zg== + dependencies: + "@jest/types" "^29.6.1" + "@types/node" "*" + jest-util "^29.6.2" + +jest-pnp-resolver@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== + +jest-regex-util@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.4.3.tgz#a42616141e0cae052cfa32c169945d00c0aa0bb8" + integrity sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg== + +jest-resolve-dependencies@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.2.tgz#36435269b6672c256bcc85fb384872c134cc4cf2" + integrity sha512-LGqjDWxg2fuQQm7ypDxduLu/m4+4Lb4gczc13v51VMZbVP5tSBILqVx8qfWcsdP8f0G7aIqByIALDB0R93yL+w== + dependencies: + jest-regex-util "^29.4.3" + jest-snapshot "^29.6.2" + +jest-resolve@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.6.2.tgz#f18405fe4b50159b7b6d85e81f6a524d22afb838" + integrity sha512-G/iQUvZWI5e3SMFssc4ug4dH0aZiZpsDq9o1PtXTV1210Ztyb2+w+ZgQkB3iOiC5SmAEzJBOHWz6Hvrd+QnNPw== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.6.2" + jest-pnp-resolver "^1.2.2" + jest-util "^29.6.2" + jest-validate "^29.6.2" + resolve "^1.20.0" + resolve.exports "^2.0.0" + slash "^3.0.0" + +jest-runner@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.6.2.tgz#89e8e32a8fef24781a7c4c49cd1cb6358ac7fc01" + integrity sha512-wXOT/a0EspYgfMiYHxwGLPCZfC0c38MivAlb2lMEAlwHINKemrttu1uSbcGbfDV31sFaPWnWJPmb2qXM8pqZ4w== + dependencies: + "@jest/console" "^29.6.2" + "@jest/environment" "^29.6.2" + "@jest/test-result" "^29.6.2" + "@jest/transform" "^29.6.2" + "@jest/types" "^29.6.1" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.13.1" + graceful-fs "^4.2.9" + jest-docblock "^29.4.3" + jest-environment-node "^29.6.2" + jest-haste-map "^29.6.2" + jest-leak-detector "^29.6.2" + jest-message-util "^29.6.2" + jest-resolve "^29.6.2" + jest-runtime "^29.6.2" + jest-util "^29.6.2" + jest-watcher "^29.6.2" + jest-worker "^29.6.2" + p-limit "^3.1.0" + source-map-support "0.5.13" + +jest-runtime@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.6.2.tgz#692f25e387f982e89ab83270e684a9786248e545" + integrity sha512-2X9dqK768KufGJyIeLmIzToDmsN0m7Iek8QNxRSI/2+iPFYHF0jTwlO3ftn7gdKd98G/VQw9XJCk77rbTGZnJg== + dependencies: + "@jest/environment" "^29.6.2" + "@jest/fake-timers" "^29.6.2" + "@jest/globals" "^29.6.2" + "@jest/source-map" "^29.6.0" + "@jest/test-result" "^29.6.2" + "@jest/transform" "^29.6.2" + "@jest/types" "^29.6.1" + "@types/node" "*" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^29.6.2" + jest-message-util "^29.6.2" + jest-mock "^29.6.2" + jest-regex-util "^29.4.3" + jest-resolve "^29.6.2" + jest-snapshot "^29.6.2" + jest-util "^29.6.2" + slash "^3.0.0" + strip-bom "^4.0.0" + +jest-snapshot@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.6.2.tgz#9b431b561a83f2bdfe041e1cab8a6becdb01af9c" + integrity sha512-1OdjqvqmRdGNvWXr/YZHuyhh5DeaLp1p/F8Tht/MrMw4Kr1Uu/j4lRG+iKl1DAqUJDWxtQBMk41Lnf/JETYBRA== + dependencies: + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-jsx" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^29.6.2" + "@jest/transform" "^29.6.2" + "@jest/types" "^29.6.1" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^29.6.2" + graceful-fs "^4.2.9" + jest-diff "^29.6.2" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.6.2" + jest-message-util "^29.6.2" + jest-util "^29.6.2" + natural-compare "^1.4.0" + pretty-format "^29.6.2" + semver "^7.5.3" + +jest-util@^29.0.0, jest-util@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.2.tgz#8a052df8fff2eebe446769fd88814521a517664d" + integrity sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w== + dependencies: + "@jest/types" "^29.6.1" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.6.2.tgz#25d972af35b2415b83b1373baf1a47bb266c1082" + integrity sha512-vGz0yMN5fUFRRbpJDPwxMpgSXW1LDKROHfBopAvDcmD6s+B/s8WJrwi+4bfH4SdInBA5C3P3BI19dBtKzx1Arg== + dependencies: + "@jest/types" "^29.6.1" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^29.4.3" + leven "^3.1.0" + pretty-format "^29.6.2" + +jest-watcher@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.6.2.tgz#77c224674f0620d9f6643c4cfca186d8893ca088" + integrity sha512-GZitlqkMkhkefjfN/p3SJjrDaxPflqxEAv3/ik10OirZqJGYH5rPiIsgVcfof0Tdqg3shQGdEIxDBx+B4tuLzA== + dependencies: + "@jest/test-result" "^29.6.2" + "@jest/types" "^29.6.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.13.1" + jest-util "^29.6.2" + string-length "^4.0.1" + +jest-worker@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.6.2.tgz#682fbc4b6856ad0aa122a5403c6d048b83f3fb44" + integrity sha512-l3ccBOabTdkng8I/ORCkADz4eSMKejTYv1vB/Z83UiubqhC1oQ5Li6dWCyqOIvSifGjUBxuvxvlm6KGK2DtuAQ== + dependencies: + "@types/node" "*" + jest-util "^29.6.2" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.6.2.tgz#3bd55b9fd46a161b2edbdf5f1d1bd0d1eab76c42" + integrity sha512-8eQg2mqFbaP7CwfsTpCxQ+sHzw1WuNWL5UUvjnWP4hx2riGz9fPSzYOaU5q8/GqWn1TfgZIVTqYJygbGbWAANg== + dependencies: + "@jest/core" "^29.6.2" + "@jest/types" "^29.6.1" + import-local "^3.0.2" + jest-cli "^29.6.2" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" @@ -840,6 +2274,16 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -850,6 +2294,21 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== +json5@^2.2.2, json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" @@ -858,6 +2317,18 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + locate-path@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" @@ -865,6 +2336,11 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" +lodash.memoize@4.x: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" @@ -875,6 +2351,13 @@ lossless-json@^2.0.8: resolved "https://registry.yarnpkg.com/lossless-json/-/lossless-json-2.0.11.tgz#3137684c93fd99481c6f99c985efc9c9c5cc76a5" integrity sha512-BP0vn+NGYvzDielvBZaFain/wgeJ1hTvURCqtKvhr1SCPePdaaTanmmcplrHfEJSJOUql7hk4FHwToNJjWRY3g== +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -882,11 +2365,25 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -make-error@^1.1.1: +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== + dependencies: + semver "^7.5.3" + +make-error@1.x, make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -923,7 +2420,7 @@ mimic-fn@^4.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== -minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -952,6 +2449,21 @@ node-fetch@^2.6.1: dependencies: whatwg-url "^5.0.0" +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== + +node-releases@^2.0.13: + version "2.0.13" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" @@ -1009,13 +2521,27 @@ optionator@^0.9.3: prelude-ls "^1.2.1" type-check "^0.4.0" -p-limit@^3.0.2: +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2, p-limit@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + p-locate@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" @@ -1023,6 +2549,11 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + pako@^2.0.4: version "2.1.0" resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" @@ -1035,6 +2566,16 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -1055,6 +2596,11 @@ path-key@^4.0.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -1065,11 +2611,23 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.3.1: +picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +pirates@^4.0.4: + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -1087,21 +2645,79 @@ prettier@^3.0.0: resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.0.tgz#e7b19f691245a21d618c68bc54dc06122f6105ae" integrity sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g== +pretty-format@^29.0.0, pretty-format@^29.6.2: + version "29.6.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.6.2.tgz#3d5829261a8a4d89d8b9769064b29c50ed486a47" + integrity sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg== + dependencies: + "@jest/schemas" "^29.6.0" + ansi-styles "^5.0.0" + react-is "^18.0.0" + +prompts@^2.0.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + punycode@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== +pure-rand@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.2.tgz#a9c2ddcae9b68d736a8163036f088a2781c8b306" + integrity sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ== + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve.exports@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" + integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== + +resolve@^1.20.0: + version "1.22.2" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" + integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== + dependencies: + is-core-module "^2.11.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -1128,7 +2744,12 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -semver@^7.5.4: +semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.5.3, semver@^7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== @@ -1152,11 +2773,41 @@ signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +stack-utils@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== + dependencies: + escape-string-regexp "^2.0.0" + starknet@^5.14.1: version "5.14.1" resolved "https://registry.yarnpkg.com/starknet/-/starknet-5.14.1.tgz#97fa5f99c4c24e42ffa315cfda525461d09d6087" @@ -1169,13 +2820,35 @@ starknet@^5.14.1: pako "^2.0.4" url-join "^4.0.1" -strip-ansi@^6.0.1: +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" @@ -1191,6 +2864,13 @@ strip-json-comments@^3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -1198,6 +2878,18 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + synckit@^0.8.5: version "0.8.5" resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.5.tgz#b7f4358f9bb559437f9f167eb6bc46b3c9818fa3" @@ -1206,6 +2898,15 @@ synckit@^0.8.5: "@pkgr/utils" "^2.3.1" tslib "^2.5.0" +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -1216,6 +2917,16 @@ titleize@^3.0.0: resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -1233,6 +2944,20 @@ ts-api-utils@^1.0.1: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.1.tgz#8144e811d44c749cd65b2da305a032510774452d" integrity sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A== +ts-jest@^29.1.1: + version "29.1.1" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.1.tgz#f58fe62c63caf7bfcc5cc6472082f79180f0815b" + integrity sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA== + dependencies: + bs-logger "0.x" + fast-json-stable-stringify "2.x" + jest-util "^29.0.0" + json5 "^2.2.3" + lodash.memoize "4.x" + make-error "1.x" + semver "^7.5.3" + yargs-parser "^21.0.1" + ts-node@^10.9.1: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" @@ -1264,11 +2989,21 @@ type-check@^0.4.0, type-check@~0.4.0: dependencies: prelude-ls "^1.2.1" +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + type-fest@^0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + typescript@^5.1.6: version "5.1.6" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" @@ -1279,6 +3014,14 @@ untildify@^4.0.0: resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== +update-browserslist-db@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -1296,6 +3039,22 @@ v8-compile-cache-lib@^3.0.1: resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== +v8-to-istanbul@^9.0.1: + version "9.1.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265" + integrity sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + +walker@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -1321,16 +3080,61 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== +write-file-atomic@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^3.0.7" + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yargs-parser@^21.0.1, yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^17.3.1: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" From 248386826fa5b2468337cb11087488068052af1f Mon Sep 17 00:00:00 2001 From: Orlando Date: Thu, 3 Aug 2023 17:55:31 +0100 Subject: [PATCH 17/25] chore: formatting --- starknet/src/authenticators/stark_sig.cairo | 20 +++++------ starknet/src/utils/stark_signatures.cairo | 38 ++++++++++++--------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/starknet/src/authenticators/stark_sig.cairo b/starknet/src/authenticators/stark_sig.cairo index 440a227a..d1db250a 100644 --- a/starknet/src/authenticators/stark_sig.cairo +++ b/starknet/src/authenticators/stark_sig.cairo @@ -78,9 +78,9 @@ mod StarkSigAuthenticator { ); self._used_salts.write((author, salt), true); - ISpaceDispatcher { - contract_address: target - }.propose(author, execution_strategy, user_proposal_validation_params); + ISpaceDispatcher { + contract_address: target + }.propose(author, execution_strategy, user_proposal_validation_params); } fn authenticate_vote( @@ -103,11 +103,11 @@ mod StarkSigAuthenticator { user_voting_strategies.span(), account_type ); - // No need to check salts here, as double voting is prevented by the space itself. + // No need to check salts here, as double voting is prevented by the space itself. - ISpaceDispatcher { - contract_address: target - }.vote(voter, proposal_id, choice, user_voting_strategies); + ISpaceDispatcher { + contract_address: target + }.vote(voter, proposal_id, choice, user_voting_strategies); } fn authenticate_update_proposal( @@ -132,9 +132,9 @@ mod StarkSigAuthenticator { ); self._used_salts.write((author, salt), true); - ISpaceDispatcher { - contract_address: target - }.update_proposal(author, proposal_id, execution_strategy); + ISpaceDispatcher { + contract_address: target + }.update_proposal(author, proposal_id, execution_strategy); } } #[constructor] diff --git a/starknet/src/utils/stark_signatures.cairo b/starknet/src/utils/stark_signatures.cairo index 04973dee..b4e0b451 100644 --- a/starknet/src/utils/stark_signatures.cairo +++ b/starknet/src/utils/stark_signatures.cairo @@ -79,19 +79,18 @@ impl StructHashIndexedStrategySpan of StructHash> { i += 1; }; encoded_data.span().struct_hash() - - // let mut self_ = *self; - // let mut encoded_data = ArrayTrait::::new(); - // loop { - // match self_.pop_front() { - // Option::Some(item) => { - // encoded_data.append(item.struct_hash()); - // }, - // Option::None(_) => { - // break encoded_data.span().struct_hash(); - // }, - // }; - // } + // let mut self_ = *self; + // let mut encoded_data = ArrayTrait::::new(); + // loop { + // match self_.pop_front() { + // Option::Some(item) => { + // encoded_data.append(item.struct_hash()); + // }, + // Option::None(_) => { + // break encoded_data.span().struct_hash(); + // }, + // }; + // } } } @@ -230,21 +229,26 @@ fn hash_typed_data( } /// Verifies the signature of a message by calling the account contract. -fn verify_signature(digest: felt252, signature: Array, account: ContractAddress, account_type: felt252) { +fn verify_signature( + digest: felt252, signature: Array, account: ContractAddress, account_type: felt252 +) { if account_type == 'camel' { assert( - AccountCamelABIDispatcher { contract_address: account }.supportsInterface(0xa66bd575) == true, + AccountCamelABIDispatcher { + contract_address: account + }.supportsInterface(0xa66bd575) == true, 'Invalid Account' ); AccountCamelABIDispatcher { contract_address: account }.isValidSignature(digest, signature); } else if account_type == 'snake' { assert( - AccountABIDispatcher { contract_address: account }.supports_interface(0x01ffc9a7) == true, + AccountABIDispatcher { + contract_address: account + }.supports_interface(0x01ffc9a7) == true, 'Invalid Account' ); AccountABIDispatcher { contract_address: account }.is_valid_signature(digest, signature); } else { panic_with_felt252('Invalid Account Type'); } - } From 8bf8e2e4a2af93c0aeda25db4cda71328ed4bfb9 Mon Sep 17 00:00:00 2001 From: Orlando Date: Mon, 7 Aug 2023 12:28:09 +0100 Subject: [PATCH 18/25] chore: type hash comments --- starknet/src/utils/constants.cairo | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/starknet/src/utils/constants.cairo b/starknet/src/utils/constants.cairo index cf49aeef..6d341eec 100644 --- a/starknet/src/utils/constants.cairo +++ b/starknet/src/utils/constants.cairo @@ -46,15 +46,29 @@ const INDEXED_STRATEGY_TYPEHASH_LOW: u128 = 0x8b36195eec0090e913c01e7534729c74; // ------ Stark Sig Constants ------ -// TODO: Add comments containing pre-images of the constants +// 'StarkNet Message' as short string const STARKNET_MESSAGE: felt252 = 0x537461726b4e6574204d657373616765; +// H('StarkNetDomain(name:felt252,version:felt252,chainId:felt252,verifyingContract:ContractAddress)') const DOMAIN_TYPEHASH: felt252 = 0xa9974a36dee531bbc36aad5eeab4ade4df5ad388a296bb14d28ad4e9bf2164; +// H('Propose(space:ContractAddress,author:ContractAddress,executionStrategy:Strategy, +// userProposalValidationParams:felt*,salt:felt252)Strategy(address:felt252,params:felt*)') const PROPOSE_TYPEHASH: felt252 = 0x1f8c9b1ab74c5990f89bac4c632dc405457352e22bbc7573a237989aa62cb60; +// H('Vote(space:ContractAddress,voter:ContractAddress,proposalId:u256,choice:felt252,userVotingStrategies:IndexedStrategy*) +// IndexedStrategy(index:felt252,params:felt*)u256(low:felt252,high:felt252)') const VOTE_TYPEHASH: felt252 = 0x1845db28c74470cdaa3cf6a1c5017d013586d70ffee45b519a5670e23fe9512; +// H('UpdateProposal(space:ContractAddress,author:ContractAddress,proposalId:u256,executionStrategy:Strategy, +// salt:felt252)Strategy(address:felt252,params:felt*)u256(low:felt252,high:felt252)') const UPDATE_PROPOSAL_TYPEHASH: felt252 = 0x222b737bd5f9ba595cf15e62d789e31a2e51c57c794a82802c94cd3925e7d49; +// H('Strategy(address:felt252,params:felt*)') const STRATEGY_TYPEHASH: felt252 = 0x39154ec0efadcd0deffdfc2044cf45dd986d260e59c26d69564b50a18f40f6b; +// H('IndexedStrategy(index:felt252,params:felt*)') const INDEXED_STRATEGY_TYPEHASH: felt252 = 0x1f464f3e668281a899c5f3fc74a009ccd1df05fd0b9331b0460dc3f8054f64c; +// H('u256(low:felt252,high:felt252)') const U256_TYPEHASH: felt252 = 0x1094260a770342332e6a73e9256b901d484a438925316205b4b6ff25df4a97a; + +// ------ ERC165 Interface Ids ------ +const ERC165_ACCOUNT_INTERFACE_ID: felt252 = 0xa66bd575; // snake +const ERC165_OLD_ACCOUNT_INTERFACE_ID: felt252 = 0x3943f10f; // camel From 749e409ea9774349732a9a9a7677eddb8e386f50 Mon Sep 17 00:00:00 2001 From: Orlando Date: Mon, 7 Aug 2023 12:29:24 +0100 Subject: [PATCH 19/25] refactor: cleanup contracts and test --- starknet/src/authenticators/stark_sig.cairo | 35 +++--- starknet/src/utils.cairo | 8 +- starknet/src/utils/legacy_hash.cairo | 26 ++++ .../src/utils/legacy_hash_eth_address.cairo | 9 -- ...rk_signatures.cairo => stark_eip712.cairo} | 111 ++---------------- starknet/src/utils/struct_hash.cairo | 69 +++++++++++ starknet/tests/stark-sig.test.ts | 27 ++++- 7 files changed, 152 insertions(+), 133 deletions(-) create mode 100644 starknet/src/utils/legacy_hash.cairo delete mode 100644 starknet/src/utils/legacy_hash_eth_address.cairo rename starknet/src/utils/{stark_signatures.cairo => stark_eip712.cairo} (59%) create mode 100644 starknet/src/utils/struct_hash.cairo diff --git a/starknet/src/authenticators/stark_sig.cairo b/starknet/src/authenticators/stark_sig.cairo index d1db250a..5df49562 100644 --- a/starknet/src/authenticators/stark_sig.cairo +++ b/starknet/src/authenticators/stark_sig.cairo @@ -1,6 +1,5 @@ use starknet::ContractAddress; -use starknet::SyscallResult; -use sx::utils::types::{Strategy, IndexedStrategy, Choice}; +use sx::types::{Strategy, IndexedStrategy, Choice}; #[starknet::interface] trait IStarkSigAuthenticator { @@ -39,14 +38,12 @@ trait IStarkSigAuthenticator { #[starknet::contract] mod StarkSigAuthenticator { use super::IStarkSigAuthenticator; - use starknet::ContractAddress; - use starknet::syscalls::call_contract_syscall; + use starknet::{ContractAddress, info}; use core::array::{ArrayTrait, SpanTrait}; - use clone::Clone; use serde::Serde; use sx::space::space::{ISpaceDispatcher, ISpaceDispatcherTrait}; - use sx::utils::types::{Strategy, IndexedStrategy, Choice}; - use sx::utils::stark_signatures; + use sx::types::{Strategy, IndexedStrategy, UserAddress, Choice}; + use sx::utils::stark_eip712; #[storage] struct Storage { @@ -66,7 +63,7 @@ mod StarkSigAuthenticator { salt: felt252, account_type: felt252 ) { - stark_signatures::verify_propose_sig( + stark_eip712::verify_propose_sig( self._domain_hash.read(), signature, target, @@ -80,7 +77,12 @@ mod StarkSigAuthenticator { self._used_salts.write((author, salt), true); ISpaceDispatcher { contract_address: target - }.propose(author, execution_strategy, user_proposal_validation_params); + } + .propose( + UserAddress::Starknet(author), + execution_strategy, + user_proposal_validation_params + ); } fn authenticate_vote( @@ -93,7 +95,7 @@ mod StarkSigAuthenticator { user_voting_strategies: Array, account_type: felt252 ) { - stark_signatures::verify_vote_sig( + stark_eip712::verify_vote_sig( self._domain_hash.read(), signature, target, @@ -107,7 +109,7 @@ mod StarkSigAuthenticator { ISpaceDispatcher { contract_address: target - }.vote(voter, proposal_id, choice, user_voting_strategies); + }.vote(UserAddress::Starknet(voter), proposal_id, choice, user_voting_strategies); } fn authenticate_update_proposal( @@ -120,7 +122,7 @@ mod StarkSigAuthenticator { salt: felt252, account_type: felt252 ) { - stark_signatures::verify_update_proposal_sig( + stark_eip712::verify_update_proposal_sig( self._domain_hash.read(), signature, target, @@ -134,13 +136,12 @@ mod StarkSigAuthenticator { self._used_salts.write((author, salt), true); ISpaceDispatcher { contract_address: target - }.update_proposal(author, proposal_id, execution_strategy); + }.update_proposal(UserAddress::Starknet(author), proposal_id, execution_strategy); } } #[constructor] - fn constructor( - ref self: ContractState, name: felt252, version: felt252 - ) { // TODO: domain hash is immutable so could be placed in the contract code instead of storage to save on reads. - self._domain_hash.write(stark_signatures::get_domain_hash(name, version)); + fn constructor(ref self: ContractState, name: felt252, version: felt252) { + // TODO: store domain hash in stark_eip712 component once syntax is live. + self._domain_hash.write(stark_eip712::get_domain_hash(name, version)); } } diff --git a/starknet/src/utils.cairo b/starknet/src/utils.cairo index 0a807f15..bfb14c8b 100644 --- a/starknet/src/utils.cairo +++ b/starknet/src/utils.cairo @@ -5,13 +5,15 @@ mod constants; mod felt_arr_to_uint_arr; use felt_arr_to_uint_arr::Felt252ArrayIntoU256Array; -mod legacy_hash_eth_address; -use legacy_hash_eth_address::LegacyHashEthAddress; +mod legacy_hash; +use legacy_hash::{LegacyHashEthAddress, LegacyHashSpanFelt252}; mod math; +mod struct_hash; + mod single_slot_proof; mod signatures; -mod stark_signatures; +mod stark_eip712; diff --git a/starknet/src/utils/legacy_hash.cairo b/starknet/src/utils/legacy_hash.cairo new file mode 100644 index 00000000..093457a9 --- /dev/null +++ b/starknet/src/utils/legacy_hash.cairo @@ -0,0 +1,26 @@ +use hash::LegacyHash; +use traits::Into; +use array::SpanTrait; +use starknet::EthAddress; + +impl LegacyHashEthAddress of LegacyHash { + fn hash(state: felt252, value: EthAddress) -> felt252 { + LegacyHash::::hash(state, value.into()) + } +} + +impl LegacyHashSpanFelt252 of LegacyHash> { + fn hash(state: felt252, mut value: Span) -> felt252 { + let mut call_data_state: felt252 = 0; + loop { + match value.pop_front() { + Option::Some(item) => { + call_data_state = LegacyHash::hash(call_data_state, *item); + }, + Option::None(_) => { + break call_data_state; + }, + }; + } + } +} diff --git a/starknet/src/utils/legacy_hash_eth_address.cairo b/starknet/src/utils/legacy_hash_eth_address.cairo deleted file mode 100644 index 43bc0b05..00000000 --- a/starknet/src/utils/legacy_hash_eth_address.cairo +++ /dev/null @@ -1,9 +0,0 @@ -use hash::LegacyHash; -use traits::Into; -use starknet::EthAddress; - -impl LegacyHashEthAddress of LegacyHash { - fn hash(state: felt252, value: EthAddress) -> felt252 { - LegacyHash::::hash(state, value.into()) - } -} diff --git a/starknet/src/utils/stark_signatures.cairo b/starknet/src/utils/stark_eip712.cairo similarity index 59% rename from starknet/src/utils/stark_signatures.cairo rename to starknet/src/utils/stark_eip712.cairo index b4e0b451..712caa5a 100644 --- a/starknet/src/utils/stark_signatures.cairo +++ b/starknet/src/utils/stark_eip712.cairo @@ -1,109 +1,22 @@ use core::starknet::SyscallResultTrait; -use starknet::{ContractAddress, contract_address_to_felt252, get_tx_info, get_contract_address}; +use starknet::{ContractAddress, get_tx_info, get_contract_address}; use array::{ArrayTrait, SpanTrait}; use traits::Into; use box::BoxTrait; -use clone::Clone; use serde::Serde; -use ecdsa::check_ecdsa_signature; -use hash::LegacyHash; -use integer::u256_from_felt252; -use sx::utils::types::{Strategy, IndexedStrategy, Choice, Felt252ArrayIntoU256Array}; -use sx::utils::math::pow; -use sx::utils::constants::{ - STARKNET_MESSAGE, DOMAIN_TYPEHASH, STRATEGY_TYPEHASH, INDEXED_STRATEGY_TYPEHASH, U256_TYPEHASH, - PROPOSE_TYPEHASH, VOTE_TYPEHASH, UPDATE_PROPOSAL_TYPEHASH +use sx::types::{Strategy, IndexedStrategy, Choice}; +use sx::utils::{ + struct_hash::StructHash, + constants::{ + STARKNET_MESSAGE, DOMAIN_TYPEHASH, PROPOSE_TYPEHASH, VOTE_TYPEHASH, + UPDATE_PROPOSAL_TYPEHASH, ERC165_ACCOUNT_INTERFACE_ID, ERC165_OLD_ACCOUNT_INTERFACE_ID + } }; use sx::interfaces::{ AccountABIDispatcher, AccountABIDispatcherTrait, AccountCamelABIDispatcher, AccountCamelABIDispatcherTrait }; -impl LegacyHashSpanFelt252 of LegacyHash> { - fn hash(state: felt252, mut value: Span) -> felt252 { - let mut call_data_state: felt252 = 0; - loop { - match value.pop_front() { - Option::Some(item) => { - call_data_state = LegacyHash::hash(call_data_state, *item); - }, - Option::None(_) => { - break call_data_state; - }, - }; - } - } -} - -trait StructHash { - fn struct_hash(self: @T) -> felt252; -} - -impl StructHashSpanFelt252 of StructHash> { - fn struct_hash(self: @Span) -> felt252 { - let mut call_data_state = LegacyHash::hash(0, *self); - call_data_state = LegacyHash::hash(call_data_state, (*self).len()); - call_data_state - } -} - -impl StructHashStrategy of StructHash { - fn struct_hash(self: @Strategy) -> felt252 { - let mut encoded_data = ArrayTrait::::new(); - STRATEGY_TYPEHASH.serialize(ref encoded_data); - (*self.address).serialize(ref encoded_data); - self.params.span().struct_hash().serialize(ref encoded_data); - encoded_data.span().struct_hash() - } -} - -impl StructHashIndexedStrategy of StructHash { - fn struct_hash(self: @IndexedStrategy) -> felt252 { - let mut encoded_data = ArrayTrait::::new(); - INDEXED_STRATEGY_TYPEHASH.serialize(ref encoded_data); - (*self.index).serialize(ref encoded_data); - self.params.span().struct_hash().serialize(ref encoded_data); - encoded_data.span().struct_hash() - } -} - -impl StructHashIndexedStrategySpan of StructHash> { - fn struct_hash(self: @Span) -> felt252 { - let mut encoded_data = ArrayTrait::::new(); - let mut i: usize = 0; - loop { - if i >= (*self).len() { - break (); - }; - encoded_data.append((*self).at(i).struct_hash()); - i += 1; - }; - encoded_data.span().struct_hash() - // let mut self_ = *self; - // let mut encoded_data = ArrayTrait::::new(); - // loop { - // match self_.pop_front() { - // Option::Some(item) => { - // encoded_data.append(item.struct_hash()); - // }, - // Option::None(_) => { - // break encoded_data.span().struct_hash(); - // }, - // }; - // } - } -} - -impl StructHashU256 of StructHash { - fn struct_hash(self: @u256) -> felt252 { - let mut encoded_data = ArrayTrait::::new(); - U256_TYPEHASH.serialize(ref encoded_data); - self.serialize(ref encoded_data); - encoded_data.span().struct_hash() - } -} - -// Reverts if the signature was not signed by the author. fn verify_propose_sig( domain_hash: felt252, signature: Array, @@ -232,19 +145,19 @@ fn hash_typed_data( fn verify_signature( digest: felt252, signature: Array, account: ContractAddress, account_type: felt252 ) { - if account_type == 'camel' { + if account_type == 'snake' { assert( AccountCamelABIDispatcher { contract_address: account - }.supportsInterface(0xa66bd575) == true, + }.supportsInterface(ERC165_ACCOUNT_INTERFACE_ID) == true, 'Invalid Account' ); AccountCamelABIDispatcher { contract_address: account }.isValidSignature(digest, signature); - } else if account_type == 'snake' { + } else if account_type == 'camel' { assert( AccountABIDispatcher { contract_address: account - }.supports_interface(0x01ffc9a7) == true, + }.supports_interface(ERC165_OLD_ACCOUNT_INTERFACE_ID) == true, 'Invalid Account' ); AccountABIDispatcher { contract_address: account }.is_valid_signature(digest, signature); diff --git a/starknet/src/utils/struct_hash.cairo b/starknet/src/utils/struct_hash.cairo new file mode 100644 index 00000000..c2c22f16 --- /dev/null +++ b/starknet/src/utils/struct_hash.cairo @@ -0,0 +1,69 @@ +use array::{ArrayTrait, SpanTrait}; +use hash::LegacyHash; +use serde::Serde; +use sx::types::{Strategy, IndexedStrategy}; +use sx::utils::{ + constants::{ + STARKNET_MESSAGE, DOMAIN_TYPEHASH, STRATEGY_TYPEHASH, INDEXED_STRATEGY_TYPEHASH, + U256_TYPEHASH, PROPOSE_TYPEHASH, VOTE_TYPEHASH, UPDATE_PROPOSAL_TYPEHASH + }, + LegacyHashSpanFelt252 +}; + +trait StructHash { + fn struct_hash(self: @T) -> felt252; +} + +impl StructHashSpanFelt252 of StructHash> { + fn struct_hash(self: @Span) -> felt252 { + let mut call_data_state = LegacyHash::hash(0, *self); + call_data_state = LegacyHash::hash(call_data_state, (*self).len()); + call_data_state + } +} + +impl StructHashStrategy of StructHash { + fn struct_hash(self: @Strategy) -> felt252 { + let mut encoded_data = ArrayTrait::::new(); + STRATEGY_TYPEHASH.serialize(ref encoded_data); + (*self.address).serialize(ref encoded_data); + self.params.span().struct_hash().serialize(ref encoded_data); + encoded_data.span().struct_hash() + } +} + +impl StructHashIndexedStrategy of StructHash { + fn struct_hash(self: @IndexedStrategy) -> felt252 { + let mut encoded_data = ArrayTrait::::new(); + INDEXED_STRATEGY_TYPEHASH.serialize(ref encoded_data); + (*self.index).serialize(ref encoded_data); + self.params.span().struct_hash().serialize(ref encoded_data); + encoded_data.span().struct_hash() + } +} + +impl StructHashIndexedStrategySpan of StructHash> { + fn struct_hash(self: @Span) -> felt252 { + let mut self_ = *self; + let mut encoded_data = ArrayTrait::::new(); + loop { + match self_.pop_front() { + Option::Some(item) => { + encoded_data.append(item.struct_hash()); + }, + Option::None(_) => { + break encoded_data.span().struct_hash(); + }, + }; + } + } +} + +impl StructHashU256 of StructHash { + fn struct_hash(self: @u256) -> felt252 { + let mut encoded_data = ArrayTrait::::new(); + U256_TYPEHASH.serialize(ref encoded_data); + self.serialize(ref encoded_data); + encoded_data.span().struct_hash() + } +} diff --git a/starknet/tests/stark-sig.test.ts b/starknet/tests/stark-sig.test.ts index 326ff229..fc2d5837 100644 --- a/starknet/tests/stark-sig.test.ts +++ b/starknet/tests/stark-sig.test.ts @@ -1,5 +1,4 @@ import fs from 'fs'; -import dotenv from 'dotenv'; import { Provider, Account, CallData, typedData, shortString, json } from 'starknet'; import { proposeTypes, @@ -20,8 +19,8 @@ describe('Starknet Signature Authenticator', () => { const address0 = '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a'; const account0 = new Account(provider, address0, privateKey0); - // change this to 'snake' if the account interface uses snake case - const account0Type = shortString.encodeShortString('camel'); + // change this to 'camel' if the account interface uses camel case + const account0Type = shortString.encodeShortString('snake'); let spaceAddress: string; let vanillaVotingStrategyAddress: string; @@ -94,7 +93,7 @@ describe('Starknet Signature Authenticator', () => { _owner: 1, _max_voting_duration: 100, _min_voting_duration: 100, - _voting_delay: 10, + _voting_delay: 1, _proposal_validation_strategy: { address: vanillaProposalValidationStrategyAddress, params: [], @@ -179,13 +178,31 @@ describe('Starknet Signature Authenticator', () => { calldata: CallData.compile(updateProposalCalldata as any), }); + { + // Random Tx just to advance the block number on the devnet so the voting period begins. + + await account0.declareAndDeploy({ + contract: json.parse( + fs + .readFileSync('starknet/target/dev/sx_StarkSigAuthenticator.sierra.json') + .toString('ascii'), + ), + casm: json.parse( + fs + .readFileSync('starknet/target/dev/sx_StarkSigAuthenticator.casm.json') + .toString('ascii'), + ), + constructorCalldata: CallData.compile({ name: 'sx-sn', version: '0.1.0' }), + }); + } + // VOTE const voteMsg: Vote = { space: spaceAddress, voter: address0, proposalId: { low: '0x1', high: '0x0' }, - choice: '0x2', + choice: '0x1', userVotingStrategies: [{ index: '0x0', params: ['0x1', '0x2', '0x3', '0x4'] }], }; From b404007c03f1125c5d59e1522a4277a1ea9b43b5 Mon Sep 17 00:00:00 2001 From: Orlando Date: Fri, 11 Aug 2023 17:24:19 +0100 Subject: [PATCH 20/25] fix: revert if salt used on propose and update --- starknet/src/authenticators/stark_sig.cairo | 7 ++++++- starknet/tests/stark-sig.test.ts | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/starknet/src/authenticators/stark_sig.cairo b/starknet/src/authenticators/stark_sig.cairo index 60a25445..b2a59e43 100644 --- a/starknet/src/authenticators/stark_sig.cairo +++ b/starknet/src/authenticators/stark_sig.cairo @@ -67,6 +67,8 @@ mod StarkSigAuthenticator { salt: felt252, account_type: felt252 ) { + assert(!self._used_salts.read((author, salt)), 'Salt Already Used'); + stark_eip712::verify_propose_sig( self._domain_hash.read(), signature, @@ -102,6 +104,8 @@ mod StarkSigAuthenticator { metadata_URI: Array, account_type: felt252 ) { + // No need to check salts here, as double voting is prevented by the space itself. + stark_eip712::verify_vote_sig( self._domain_hash.read(), signature, @@ -113,7 +117,6 @@ mod StarkSigAuthenticator { metadata_URI.span(), account_type ); - // No need to check salts here, as double voting is prevented by the space itself. ISpaceDispatcher { contract_address: target @@ -138,6 +141,8 @@ mod StarkSigAuthenticator { salt: felt252, account_type: felt252 ) { + assert(!self._used_salts.read((author, salt)), 'Salt Already Used'); + stark_eip712::verify_update_proposal_sig( self._domain_hash.read(), signature, diff --git a/starknet/tests/stark-sig.test.ts b/starknet/tests/stark-sig.test.ts index 4c22e097..2f8fa1ad 100644 --- a/starknet/tests/stark-sig.test.ts +++ b/starknet/tests/stark-sig.test.ts @@ -161,7 +161,7 @@ describe('Starknet Signature Authenticator', () => { params: ['0x5', '0x6', '0x7', '0x8'], }, metadataURI: ['0x1', '0x2', '0x3', '0x4'], - salt: '0x0', + salt: '0x1', }; const updateProposalData: typedData.TypedData = { types: updateProposalTypes, From 296a105d62d54e2ab5faa186a9fa3082d3d291e1 Mon Sep 17 00:00:00 2001 From: Orlando Date: Tue, 15 Aug 2023 21:48:20 +0100 Subject: [PATCH 21/25] chore: some comments --- starknet/src/interfaces/i_account.cairo | 1 + starknet/src/utils/constants.cairo | 2 ++ 2 files changed, 3 insertions(+) diff --git a/starknet/src/interfaces/i_account.cairo b/starknet/src/interfaces/i_account.cairo index aafc7c5f..21b94f82 100644 --- a/starknet/src/interfaces/i_account.cairo +++ b/starknet/src/interfaces/i_account.cairo @@ -3,6 +3,7 @@ use array::SpanTrait; use starknet::account::Call; use starknet::ContractAddress; +// Interfaces from OZ: https://github.com/OpenZeppelin/cairo-contracts/blob/cairo-2/src/account/interface.cairo #[starknet::interface] trait AccountABI { fn __execute__(self: @TState, calls: Array) -> Array>; diff --git a/starknet/src/utils/constants.cairo b/starknet/src/utils/constants.cairo index 0ced260a..42ab1ad9 100644 --- a/starknet/src/utils/constants.cairo +++ b/starknet/src/utils/constants.cairo @@ -45,6 +45,7 @@ const INDEXED_STRATEGY_TYPEHASH_LOW: u128 = 0x8b36195eec0090e913c01e7534729c74; // ------ Stark Signature Constants ------ +// H refers to the Starknet Keccak hash function const STARKNET_MESSAGE: felt252 = 'StarkNet Message'; @@ -77,5 +78,6 @@ const INDEXED_STRATEGY_TYPEHASH: felt252 = const U256_TYPEHASH: felt252 = 0x1094260a770342332e6a73e9256b901d484a438925316205b4b6ff25df4a97a; // ------ ERC165 Interface Ids ------ +// For more information, refer to: https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-5.md const ERC165_ACCOUNT_INTERFACE_ID: felt252 = 0xa66bd575; // snake const ERC165_OLD_ACCOUNT_INTERFACE_ID: felt252 = 0x3943f10f; // camel From db4d695b262dd970cdb0021706326a3c464b35e2 Mon Sep 17 00:00:00 2001 From: Orlando Date: Tue, 15 Aug 2023 21:49:15 +0100 Subject: [PATCH 22/25] chore: cleaned up test --- package.json | 3 ++- starknet/tests/stark-sig.test.ts | 14 ++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 4e5c338e..62688c76 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "author": "Snapshot Labs", "license": "MIT", "scripts": { - "format": "eslint . --ext .ts --fix" + "format:ts": "eslint . --ext .ts --fix", + "test:stark-sig-auth": "jest -c jest.config.ts" }, "devDependencies": { "@types/jest": "^29.5.3", diff --git a/starknet/tests/stark-sig.test.ts b/starknet/tests/stark-sig.test.ts index 2f8fa1ad..e45e084f 100644 --- a/starknet/tests/stark-sig.test.ts +++ b/starknet/tests/stark-sig.test.ts @@ -1,4 +1,5 @@ import fs from 'fs'; +import dotenv from 'dotenv'; import { Provider, Account, CallData, typedData, shortString, json } from 'starknet'; import { proposeTypes, @@ -12,12 +13,17 @@ import { StarknetSigUpdateProposalCalldata, } from './types'; +dotenv.config(); + +const network = process.env.NETWORK_URL || ''; + describe('Starknet Signature Authenticator', () => { - const provider = new Provider({ sequencer: { baseUrl: 'http://127.0.0.1:5050' } }); - // devnet predeployed account - const privateKey0 = '0xe3e70682c2094cac629f6fbed82c07cd'; + const provider = new Provider({ sequencer: { baseUrl: network } }); + // starknet devnet predeployed account 0 with seed 0 + + const privateKey_0 = '0xe3e70682c2094cac629f6fbed82c07cd'; const address0 = '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a'; - const account0 = new Account(provider, address0, privateKey0); + const account0 = new Account(provider, address0, privateKey_0); // change this to 'camel' if the account interface uses camel case const account0Type = shortString.encodeShortString('snake'); From f6bacd0ec191053381f455d02e1ed27226ce271b Mon Sep 17 00:00:00 2001 From: Orlando Date: Tue, 15 Aug 2023 21:49:49 +0100 Subject: [PATCH 23/25] chore: .env example --- .env.example | 1 + 1 file changed, 1 insertion(+) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..f2d01ce4 --- /dev/null +++ b/.env.example @@ -0,0 +1 @@ +NETWORK_URL= \ No newline at end of file From 5a1f73ebcd0053ea3ae32f02f51942eab17ecfe0 Mon Sep 17 00:00:00 2001 From: Orlando Date: Tue, 15 Aug 2023 21:50:09 +0100 Subject: [PATCH 24/25] chore: updated lint settings --- .eslintrc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.eslintrc b/.eslintrc index 5cd0c783..d0351e97 100644 --- a/.eslintrc +++ b/.eslintrc @@ -12,11 +12,7 @@ "sourceType": "module" }, "rules": { - "no-console": "off", "prettier/prettier": "error", - "@typescript-eslint/explicit-function-return-type": "off", - "@typescript-eslint/ban-ts-ignore": "off", - "@typescript-eslint/camelcase": "off", "@typescript-eslint/no-explicit-any": "off" } } \ No newline at end of file From b82456a910e9b3a70fc2c3ffbc69d7450f64fe81 Mon Sep 17 00:00:00 2001 From: Orlando Date: Tue, 15 Aug 2023 22:46:07 +0100 Subject: [PATCH 25/25] chore: formatting --- starknet/src/authenticators.cairo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/starknet/src/authenticators.cairo b/starknet/src/authenticators.cairo index a0d79bd5..4984e198 100644 --- a/starknet/src/authenticators.cairo +++ b/starknet/src/authenticators.cairo @@ -6,4 +6,4 @@ mod eth_sig; mod stark_sig; -mod stark_tx; \ No newline at end of file +mod stark_tx;